-
Notifications
You must be signed in to change notification settings - Fork 601
refactor: full agent loop mode #1208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Performance optimizations allow rendering of over 100,000 content items at once.
|
@codex review |
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds a unified ToolPresenter/ToolMapper and AgentToolManager/AgentFileSystemHandler, a WorkspacePresenter with renderer workspace store/composables/UI, removes built-in in-memory filesystem and tests, adds regex-safety utilities, extends DB/config types and presenter/type surfaces, and updates many presenter and renderer flows for mode-aware workspaces and tool routing. Changes
Sequence Diagram(s)sequenceDiagram
actor UI as Renderer UI
participant TP as ToolPresenter
participant TM as ToolMapper
participant MCP as MCP Presenter
participant AM as AgentToolManager
participant AF as AgentFileSystemHandler
UI->>TP: getAllToolDefinitions(context)
activate TP
TP->>MCP: fetch MCP definitions
MCP-->>TP: mcpDefs
TP->>TM: registerTools(mcpDefs,'mcp')
alt chatMode != 'chat'
TP->>AM: getAllToolDefinitions(context)
AM->>AF: ensureWorkspace / provide FS tool defs
AF-->>AM: fsDefs
AM-->>TP: agentDefs
TP->>TM: registerTools(agentDefs,'agent')
end
TP-->>UI: combinedDefs
deactivate TP
UI->>TP: callTool(name,args)
activate TP
TP->>TM: getToolSource(name)
TM-->>TP: source
alt source == 'agent'
TP->>AM: callTool(name,args)
AM->>AF: execute FS operation (if applicable)
AF-->>AM: result
AM-->>TP: {content,raw}
else
TP->>MCP: callTool(request)
MCP-->>TP: {content,raw}
end
TP-->>UI: {content,raw}
deactivate TP
Estimated code review effort🎯 5 (Critical) | ⏱️ ~220 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ 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".
| private async validatePath(requestedPath: string): Promise<string> { | ||
| const expandedPath = this.expandHome(requestedPath) | ||
| const absolute = path.isAbsolute(expandedPath) | ||
| ? path.resolve(expandedPath) | ||
| : path.resolve(process.cwd(), expandedPath) | ||
| const normalizedRequested = this.normalizePath(absolute) | ||
| const isAllowed = this.allowedDirectories.some((dir) => normalizedRequested.startsWith(dir)) | ||
| if (!isAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforce workspace boundary with path separator checks
The path-allowlist check in validatePath only uses startsWith(dir), which treats sibling paths like /workspace-evil as inside /workspace because they share the prefix. That allows agent filesystem tools to read/write outside the intended workspace when an attacker supplies a crafted path with the same prefix (including after realpath), weakening the sandbox. Use an equality check or startsWith(dir + path.sep) to ensure the requested path is actually inside an allowed directory.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
package.json (1)
9-9: Update Node.js version requirement to match coding guidelines.The engines field specifies Node.js >= 20.19.0, but the coding guidelines and retrieved learnings indicate Node.js >= 22 is required. This mismatch could lead to developers or CI environments using an unsupported Node.js version, potentially causing runtime errors if Node.js 22+ features are used in the codebase.
🔎 Proposed fix
- "node": ">=20.19.0", + "node": ">=22.0.0",Based on coding guidelines and learnings.
src/renderer/settings/components/BedrockProviderSettingsDetail.vue (1)
99-99: Replace Chinese text in comments and logs with English.Per coding guidelines, all logs and comments should use English. The following locations contain Chinese text:
- Line 99:
<!-- 模型管理 -->- Line 114:
<!-- 对话框容器 -->- Line 262:
console.log('验证成功')- Line 265: Comment before line 266
- Line 268:
console.log('验证失败', ...)- Line 328: Comment before line 329
🔎 Proposed fixes
- <!-- 模型管理 --> + <!-- Model management -->- <!-- 对话框容器 --> + <!-- Dialog container -->- console.log('验证成功') + console.log('Credential verification succeeded')- console.log('验证失败', resp.errorMsg) + console.log('Credential verification failed', resp.errorMsg)- // 验证成功后刷新当前provider的模型列表 + // Refresh current provider's model list after successful verification- // 模型配置变更后重新初始化数据 + // Reinitialize data after model configuration changesAlso applies to: 114-114, 262-262, 265-265, 268-268, 328-328
src/main/presenter/sqlitePresenter/tables/conversations.ts (1)
182-182: Potential bug: String 'NULL' instead of actual null.Line 182 passes the literal string
'NULL'whenenabledMcpToolsis falsy, which will be stored as text in the database rather than an actual SQL NULL. This may cause issues when reading back the value withgetJsonField.🔎 Proposed fix
- settings.enabledMcpTools ? JSON.stringify(settings.enabledMcpTools) : 'NULL', + settings.enabledMcpTools ? JSON.stringify(settings.enabledMcpTools) : null,
🟡 Minor comments (10)
src/renderer/src/i18n/ja-JP/chat.json-130-130 (1)
130-130: Fix variable placeholder format.The placeholder
{モード}should be{mode}for consistency with line 25 and standard i18n practices.🔎 Proposed fix
- "current": "現在のモード: {モード}" + "current": "現在のモード: {mode}"src/renderer/src/i18n/ja-JP/chat.json-133-133 (1)
133-133: Fix incorrect translation for "collapse".The translation "近い" means "near/close", not "collapse". It should be "折りたたむ" to match the correct translation used in line 98 (
acp.workspace.collapse).🔎 Proposed fix
- "collapse": "近い", + "collapse": "折りたたむ",src/renderer/src/i18n/ja-JP/chat.json-26-26 (1)
26-26: Fix variable placeholder format.The placeholder
{パス}should be{path}to maintain consistency with standard i18n practices. Variable placeholders must remain in English across all locale files for proper interpolation.🔎 Proposed fix
- "agentWorkspaceCurrent": "現在の作業ディレクトリ: {パス}", + "agentWorkspaceCurrent": "現在の作業ディレクトリ: {path}",Based on learnings, maintain consistent key-value structure across all language translation files.
src/renderer/src/i18n/ja-JP/chat.json-132-164 (1)
132-164: Align translation keys betweenacp.workspaceandworkspacesections across all locales.The new
workspacesection duplicatesacp.workspacewith translation inconsistencies. For ja-JP, all four corresponding keys differ:
files.section: "書類" (workspace) vs "ファイル" (acp)files.empty: "まだファイルがありません" vs "ファイルはまだありません"plan.empty: "まだタスクはありません" vs "タスクはまだありません"terminal.empty: "まだ出力はありません" vs "出力はまだありません"This inconsistency extends to other locales (zh-TW, zh-HK, ru-RU, pt-BR, ko-KR, fr-FR, da-DK, fa-IR). Align all corresponding translations to match the
acp.workspacevalues for consistency across the UI.src/renderer/src/i18n/fr-FR/chat.json-126-164 (1)
126-164: Translation inconsistencies betweenacp.workspaceandworkspacesections.Several mismatches with the existing French translations in
acp.workspace:
workspace.files.section:"document"vs"Fichiers"in acp.workspaceworkspace.plan.status.completed:"Complété"vs"Terminé"in acp.workspaceworkspace.plan.status.failed:"échouer"(infinitive verb) vs"Échoué"(past participle) in acp.workspacemode.chat:"chat"(English) - consider"Discussion"or"Conversation"- Inconsistent capitalization throughout
These should be aligned with the existing
acp.workspacetranslations for UI consistency. Based on coding guidelines, key-value structure should be consistent across translation files.src/renderer/src/i18n/da-DK/chat.json-126-164 (1)
126-164: Translation inconsistencies and potential errors in Danish locale.Several issues need attention:
workspace.plan.status.pending:"Indtil"(means "until") should be"Afventer"as inacp.workspaceworkspace.collapse:"tæt"(means "close/tight") should be"Skjul"as inacp.workspaceworkspace.files.section:"dokument"(document) vs"Filer"(Files) inacp.workspaceThese should align with the existing
acp.workspacetranslations for consistency. Based on coding guidelines, key-value structure should be consistent across translation files.src/renderer/src/i18n/pt-BR/chat.json-126-164 (1)
126-164: Inconsistent translations and capitalization betweenacp.workspaceandworkspacesections.Several translations have inconsistencies:
workspace.files.sectionis"documento"(document) vsacp.workspace.files.sectionas"Arquivos"(Files)workspace.titleis"área de trabalho"(lowercase) vsacp.workspace.titleas"Área de trabalho"(capitalized)workspace.plan.status.failedis"falhar"(verb: to fail) vsacp.workspace.plan.status.failedas"Falhou"(past tense: Failed)mode.chatas"bater papo"is very informal; consider"Chat"or"Conversa"Consider aligning the new workspace translations with the existing acp.workspace patterns for consistency. Based on coding guidelines, translation keys should maintain consistent key-value structure across locale files.
src/renderer/src/components/chat-input/ChatInput.vue-568-572 (1)
568-572: Remove debug console.log before merging.This debug logging statement should be removed as it exposes internal state and is not suitable for production code.
🔎 Proposed fix
const chatMode = useChatMode() const modeSelectOpen = ref(false) -console.log( - '%c🤪 ~ file: /Users/zerob13/Documents/deepchat/src/renderer/src/components/chat-input/ChatInput.vue:552 [] -> modeSelectOpen : ', - 'color: #394483', - modeSelectOpen -)Committable suggestion skipped: line range outside the PR's diff.
src/main/presenter/toolPresenter/index.ts-66-73 (1)
66-73: AgentToolManager is not updated when workspace path changes.Once
agentToolManageris initialized, subsequent calls with differentagentWorkspacePathvalues won't update the manager. The manager's internal workspace path handling viagetAllToolDefinitionsmay not reflect the new path correctly for all operations.Consider updating or recreating the manager when the workspace path changes:
🔎 Proposed fix
// 2. Get Agent tools (only in agent or acp agent mode) if (chatMode !== 'chat') { - // Initialize or update AgentToolManager if workspace path changed - if (!this.agentToolManager) { + // Initialize or recreate AgentToolManager if workspace path changed + if (!this.agentToolManager || this.agentToolManager.agentWorkspacePath !== agentWorkspacePath) { this.agentToolManager = new AgentToolManager({ yoBrowserPresenter: this.options.yoBrowserPresenter, agentWorkspacePath }) }Note: This requires exposing
agentWorkspacePathas a readonly property onAgentToolManager.Committable suggestion skipped: line range outside the PR's diff.
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts-74-90 (1)
74-90: Tool routing may fail silently for filesystem tools when handler is not initialized.If
toolNamedoes not start with'browser_'butfileSystemHandlerisnull, the code falls through to throw "Unknown Agent tool" even if the tool is a valid filesystem tool. This could happen if agent mode is active but no workspace path was configured.Consider adding explicit validation:
🔎 Proposed fix
async callTool(toolName: string, args: Record<string, unknown>): Promise<string> { // Route to Yo Browser tools if (toolName.startsWith('browser_')) { const response = await this.yoBrowserPresenter.callTool( toolName, args as Record<string, unknown> ) return typeof response === 'string' ? response : JSON.stringify(response) } // Route to FileSystem tools - if (this.fileSystemHandler) { - return await this.callFileSystemTool(toolName, args) + // Check if this is a known filesystem tool + const fsToolNames = [ + 'read_file', 'write_file', 'list_directory', 'create_directory', + 'move_files', 'edit_text', 'search_files', 'directory_tree', + 'get_file_info', 'grep_search', 'text_replace' + ] + if (fsToolNames.includes(toolName)) { + if (!this.fileSystemHandler) { + throw new Error(`FileSystem tool '${toolName}' requires an initialized workspace`) + } + return await this.callFileSystemTool(toolName, args) } throw new Error(`Unknown Agent tool: ${toolName}`) }
🧹 Nitpick comments (25)
src/renderer/src/views/ChatTabView.vue (1)
91-93: Consider documenting the margin calculation.The value
'mr-[calc(60%-104px)]'uses a specific calculation whose meaning isn't immediately clear. Adding a brief comment explaining what the 60% and 104px represent would improve maintainability.💡 Example documentation
if (artifactOpen) { - // Only artifact open + // Artifact panel takes 60% width minus 104px (sidebar width + padding) return 'mr-[calc(60%-104px)]' }src/renderer/src/i18n/zh-HK/chat.json (1)
132-164: Verify the purpose of parallel workspace structures before consolidation.Both
acp.workspace(lines 96-124) and root-levelworkspace(lines 132-164) exist across all language files, but contrary to the assumption, their translations are intentionally different, not identical copies. For example:
- da-DK: "Filer"/"Ingen filer" (acp) vs "dokument"/"Ingen filer endnu" (root)
- fa-IR: "فایلها"/"فایلی وجود ندارد" (acp) vs "سند"/"هنوز فایلی وجود ندارد" (root)
- en-US: Values happen to match, but this is an exception
Additionally, the root
workspaceadds abrowsersection not present inacp.workspace. This suggests the structures serve different purposes rather than representing an incomplete migration.Before consolidating, clarify:
- Why do these structures maintain distinct translations?
- Is the
browsersection exclusive to the generic workspace?- Should these be unified, or are the differences intentional for ACP vs. general agent contexts?
src/main/presenter/mcpPresenter/inMemoryServers/builder.ts (1)
2-2: Verify filesystem migration completion and remove unused artifacts.The removal of buildInFileSystem from in-memory servers is confirmed—builder.ts properly excludes it from the server factory. Agent tools now provide filesystem capabilities via AgentFileSystemHandler, registered as 'agent-filesystem' tools in agentToolManager.ts. Migration logic in mcpConfHelper.ts correctly removes buildInFileSystem from configurations.
However, incomplete cleanup remains:
- FileSystemServer class still exists in filesystem.ts but is unused
- Test file (test/main/presenter/filesystem.test.ts) still imports FileSystemServer
- i18n definitions (types/i18n.d.ts) still reference buildInFileSystem
Remove the unused FileSystemServer class, update test imports, and clean up i18n definitions.
src/renderer/src/components/chat-input/composables/useAgentWorkspace.ts (2)
40-56: Type assertion indicates potential interface mismatch.The type assertion for
chatStoresuggests the store interface may not be fully aligned with the expected API. This works but is fragile.Consider defining a proper interface or extending the store type
If
setAgentWorkspacePreferenceis a new addition to the chat store, ensure it's properly typed in the store's return type rather than using runtime type checks:// In the store, ensure setAgentWorkspacePreference is in the return object // Then here, simply call: const syncPreference = (workspacePath: string | null) => { chatStore.setAgentWorkspacePreference(workspacePath) }
104-141: Consider hoisting presenter calls to the top level.
usePresenter('devicePresenter')andusePresenter('workspacePresenter')are called insideselectWorkspace. These could be hoisted to the composable's top level for consistency withuseAcpWorkdirand to avoid repeated lookups.Hoist presenter declarations
export function useAgentWorkspace(options: UseAgentWorkspaceOptions) { const { t } = useI18n() const threadPresenter = usePresenter('threadPresenter') + const devicePresenter = usePresenter('devicePresenter') + const workspacePresenter = usePresenter('workspacePresenter') const chatMode = options.chatMode ?? useChatMode() // ... const selectWorkspace = async () => { // ... - const devicePresenter = usePresenter('devicePresenter') const result = await devicePresenter.selectDirectory() // ... - const workspacePresenter = usePresenter('workspacePresenter') await workspacePresenter.registerWorkspace(selectedPath) }src/renderer/src/components/workspace/WorkspaceBrowserTabs.vue (1)
71-71: Consider cleaning up stale favicon error entries.The
faviconErrorref accumulates entries for tabs that may no longer exist. While unlikely to cause issues in practice, consider clearing entries for removed tabs to prevent unbounded growth.🔎 Optional: Watch for tab removals
import { computed, ref, watch } from 'vue' // ... existing code ... // Clean up stale error entries when tabs change watch( () => store.tabs.map(t => t.id), (currentIds) => { const idSet = new Set(currentIds) for (const key of Object.keys(faviconError.value)) { if (!idSet.has(key)) { delete faviconError.value[key] } } } )src/main/presenter/threadPresenter/handlers/streamGenerationHandler.ts (1)
53-80: Synchronous file operations may block the main thread.Using
fs.mkdirSyncon Electron's main process can block the event loop. Consider using async alternatives for better responsiveness, especially since the calling method is already async.🔎 Proposed async alternative
+import { promises as fsPromises } from 'fs' - private getDefaultAgentWorkspacePath(conversationId?: string | null): string { + private async getDefaultAgentWorkspacePath(conversationId?: string | null): Promise<string> { const tempRoot = path.join(app.getPath('temp'), 'deepchat-agent', 'workspaces') try { - fs.mkdirSync(tempRoot, { recursive: true }) + await fsPromises.mkdir(tempRoot, { recursive: true }) } catch (error) { console.warn( '[StreamGenerationHandler] Failed to create default workspace root, using system temp:', error ) return app.getPath('temp') } if (!conversationId) { return tempRoot } const workspaceDir = path.join(tempRoot, conversationId) try { - fs.mkdirSync(workspaceDir, { recursive: true }) + await fsPromises.mkdir(workspaceDir, { recursive: true }) return workspaceDir } catch (error) { console.warn( '[StreamGenerationHandler] Failed to create conversation workspace, using root temp workspace:', error ) return tempRoot } }This would require updating
ensureAgentWorkspacePathto await the result accordingly.src/main/presenter/configPresenter/mcpConfHelper.ts (1)
5-6: Clean up commented-out import.The commented import for
appis dead code. Either remove it entirely or, if needed elsewhere in the file, keep it active.🔎 Proposed fix
-// app is used in DEFAULT_INMEMORY_SERVERS but removed buildInFileSystem -// import { app } from 'electron'src/main/presenter/toolPresenter/toolMapper.ts (1)
22-29: Potential duplicate entries in toolMappings array.
registerToolalways pushes totoolMappingseven if the tool already exists in the Map. This can cause the array to grow with duplicates while the Map correctly overwrites. Consider deduplicating or replacing existing entries.🔎 Proposed fix to prevent duplicates
registerTool(toolName: string, source: ToolSource, originalName?: string): void { + // Remove existing mapping if present to prevent duplicates + const existingIndex = this.toolMappings.findIndex(m => m.toolName === toolName) + if (existingIndex !== -1) { + this.toolMappings.splice(existingIndex, 1) + } this.toolNameToSource.set(toolName, source) this.toolMappings.push({ toolName, source, originalName: originalName || toolName }) }src/renderer/src/stores/yoBrowser.ts (1)
104-108: Consider error handling for the sequential async calls.The
openTabfunction chains three async operations. IfactivateTabfails, the subsequentshow()andloadState()calls may leave the UI in an inconsistent state.🔎 Suggested improvement with error handling
const openTab = async (tabId: string): Promise<void> => { - await yoBrowserPresenter.activateTab(tabId) - await yoBrowserPresenter.show() - await loadState() + try { + await yoBrowserPresenter.activateTab(tabId) + await yoBrowserPresenter.show() + await loadState() + } catch (error) { + console.error('Failed to open tab:', error) + // Attempt to reload state to sync UI + await loadState() + } }src/renderer/src/components/workspace/WorkspaceFileNode.vue (1)
168-187: Optional: Consider extracting transition styles to global stylesheet.The workspace-collapse transition styles are well-defined but are scoped to this component. If similar collapse/expand animations are needed elsewhere in the workspace UI, consider extracting these to a shared stylesheet or CSS module for reusability.
docs/workspace-agent-refactoring-summary.md (1)
1-404: Comprehensive refactoring documentation.This documentation provides excellent coverage of the workspace and agent capability refactoring, including architecture diagrams, implementation details, testing procedures, and architectural considerations. The level of detail will greatly assist future maintainers in understanding the design decisions and structure.
Minor documentation improvements
- Add language identifiers to fenced code blocks (lines 340, 358, 372):
The markdown linter flagged missing language specifications. Add language identifiers for better syntax highlighting:-``` +```text 用户选择 Mode
- Consider adding an English version: Since the coding guidelines specify using English for logs and comments, consider adding an English translation of this documentation or a bilingual version for international contributors.
src/renderer/src/components/NewThread.vue (1)
240-260: Consider consolidating model picker functions.The three functions
pickFirstEnabledModel,pickFirstAcpModel, andpickFirstNonAcpModelshare similar logic. Consider refactoring to a single parameterized function for better maintainability.🔎 Suggested refactor
const pickFirstEnabledModelByFilter = ( filter?: (m: { providerId: string; type: ModelType }) => boolean ) => { return modelStore.enabledModels .flatMap((p) => p.models.map((m) => ({ ...m, providerId: p.providerId }))) .find( (m) => (m.type === ModelType.Chat || m.type === ModelType.ImageGeneration) && (!filter || filter(m)) ) } const pickFirstEnabledModel = () => pickFirstEnabledModelByFilter() const pickFirstAcpModel = () => pickFirstEnabledModelByFilter((m) => m.providerId === 'acp') const pickFirstNonAcpModel = () => pickFirstEnabledModelByFilter((m) => m.providerId !== 'acp')src/renderer/src/components/chat-input/composables/useChatMode.ts (2)
141-148: Consider adding IPC listener cleanup for HMR compatibility.The IPC listener is never removed. While the
hasAcpListenerguard prevents duplicates during normal usage, Hot Module Replacement (HMR) during development could lead to stale listeners if the module is reloaded.🔎 Suggested approach
Consider exposing a cleanup function or using Vue's
onUnmountedif this composable is used in a root-level component that persists for the app lifetime. For a module-level singleton, this is typically acceptable in production but may cause issues during development with HMR.
152-160: Mark async call in watch withvoidoperator.The
setModecall is async but the result is not awaited or explicitly ignored. Per best practices, use thevoidoperator to indicate intentional fire-and-forget.🔎 Proposed fix
watch( () => hasAcpAgents.value, (hasAgents) => { // If current mode is 'acp agent' but agents are removed, switch to 'chat' if (!hasAgents && currentMode.value === 'acp agent') { - setMode('chat') + void setMode('chat') } } )src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts (1)
172-174: Consider reordering: notify success after abort check.Currently,
notifyToolCallFinished('success')is called before checkingcontext.abortSignal.aborted. If the operation was aborted, notifying success may be misleading. Consider moving the notification after the abort check.🔎 Proposed fix
- notifyToolCallFinished('success') - if (context.abortSignal.aborted) break + + notifyToolCallFinished('success') const supportsFunctionCall = context.modelConfig?.functionCall || falsesrc/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (1)
854-858: Reconsider notifying FILES_CHANGED on read operations.
readTextFiledoes not modify the file system, yetnotifyWorkspaceFilesChangedis called. This may trigger unnecessary UI re-renders. Consider removing this notification from read operations or documenting why it's needed.🔎 Proposed fix
readTextFile: async (params) => { const handler = this.getFsHandler(params.sessionId) - try { - return await handler.readTextFile(params) - } finally { - this.notifyWorkspaceFilesChanged(params.sessionId) - } + return await handler.readTextFile(params) },src/main/presenter/workspacePresenter/index.ts (1)
61-63: Type casting between AcpFileNode and WorkspaceFileNode.The
as unknown as WorkspaceFileNode[]casts rely on structural compatibility betweenAcpFileNodeandWorkspaceFileNode. Per the AI summary, these types have the same structure, but consider adding a runtime type guard or explicitly documenting this assumption to prevent future breaking changes.Also applies to: 76-78
src/renderer/src/i18n/en-US/chat.json (1)
101-133: Consider consolidating duplicate workspace translations.The new
workspacenamespace (lines 101-133) largely duplicates the existingacp.workspacenamespace (lines 134-163). Both contain identical translations fortitle,collapse,plan.*,files.*, andterminal.*sections.Consider consolidating these into a single shared namespace to avoid translation drift and reduce maintenance burden. The new
workspacesection addsbrowser.*which could be merged into a unified structure.src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (1)
399-411: Consider using asyncfs.promises.mkdirinstead of syncfs.mkdirSync.The synchronous file operation can block the main process event loop. While the impact is minimal for occasional directory creation, using async operations aligns better with best practices for Electron main process code.
🔎 Proposed async version
- private getDefaultAgentWorkspacePath(): string { + private async getDefaultAgentWorkspacePath(): Promise<string> { const tempDir = path.join(app.getPath('temp'), 'deepchat-agent', 'workspaces') try { - fs.mkdirSync(tempDir, { recursive: true }) + await fs.promises.mkdir(tempDir, { recursive: true }) } catch (error) { console.warn( '[AgentToolManager] Failed to create default workspace, using system temp:', error ) return app.getPath('temp') } return tempDir }src/renderer/src/stores/workspace.ts (2)
115-120: Avoidas anytype assertions; use proper type narrowing instead.The
as anycasts bypass TypeScript's type checking. Consider defining proper presenter interfaces or using type guards to maintain type safety.🔎 Proposed fix
// Register workspace/workdir before reading (security boundary) - await to ensure completion if (isAcpAgentMode.value) { - await (acpWorkspacePresenter as any).registerWorkdir(workspacePath) + await acpWorkspacePresenter.registerWorkdir(workspacePath) } else { - await (workspacePresenter as any).registerWorkspace(workspacePath) + await workspacePresenter.registerWorkspace(workspacePath) }Ensure the
IWorkspacePresenterandIAcpWorkspacePresenterinterfaces include these methods in their type definitions atsrc/shared/types/presenters/.
229-280: Consider providing a cleanup mechanism for event listeners.The IPC event listeners registered in
setupEventListeners()are never removed. While this is typically fine for singleton stores, providing a cleanup mechanism improves testability and supports HMR during development.🔎 Example cleanup pattern
const cleanupFunctions: (() => void)[] = [] const setupEventListeners = () => { const planHandler = (_, payload) => { /* ... */ } window.electron.ipcRenderer.on(WORKSPACE_EVENTS.PLAN_UPDATED, planHandler) cleanupFunctions.push(() => window.electron.ipcRenderer.removeListener(WORKSPACE_EVENTS.PLAN_UPDATED, planHandler) ) // ... repeat for other listeners } const cleanup = () => { cleanupFunctions.forEach(fn => fn()) cleanupFunctions.length = 0 } // Export cleanup in return object if neededsrc/main/presenter/toolPresenter/index.ts (1)
13-21: Consider importingIToolPresenterfrom shared types instead of redefining it locally.The interface is also defined in
src/shared/types/presenters/tool.presenter.d.ts. Redefining it here creates a risk of the definitions drifting apart. Import from the shared location:-export interface IToolPresenter { - getAllToolDefinitions(context: { - enabledMcpTools?: string[] - chatMode?: 'chat' | 'agent' | 'acp agent' - supportsVision?: boolean - agentWorkspacePath?: string | null - }): Promise<MCPToolDefinition[]> - callTool(request: MCPToolCall): Promise<{ content: unknown; rawData: MCPToolResponse }> -} +import type { IToolPresenter } from '@shared/presenter'src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (1)
105-132: Duplicated default workspace path logic with AgentToolManager.This method duplicates
getDefaultAgentWorkspacePathfromagentToolManager.ts. Consider consolidating into a shared utility to ensure consistent behavior and reduce maintenance burden.Additionally, uses synchronous
fs.mkdirSyncwhich can block the event loop.src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (1)
163-178: Empty catch block lacks context for debugging.While the fallback logic is correct (checking parent directory when file doesn't exist), the empty catch block at line 163 makes debugging difficult. Consider logging at debug level:
🔎 Proposed improvement
try { const realPath = await fs.realpath(absolute) const normalizedReal = this.normalizePath(realPath) const isRealPathAllowed = this.allowedDirectories.some((dir) => normalizedReal.startsWith(dir) ) if (!isRealPathAllowed) { throw new Error('Access denied - symlink target outside allowed directories') } return realPath - } catch { + } catch (err) { + // File doesn't exist yet, validate parent directory instead const parentDir = path.dirname(absolute) try { const realParentPath = await fs.realpath(parentDir)
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
Outdated
Show resolved
Hide resolved
src/renderer/settings/components/BedrockProviderSettingsDetail.vue
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/renderer/src/components/NewThread.vue (2)
510-510: Variable shadowing:chatModeshadows composable import.The local
const chatModedeclaration shadows thechatModeimported fromuseChatMode()at line 129. Rename to avoid confusion.🔎 Proposed fix: Rename local variable
- const chatMode = chatInput?.getChatMode?.() + const currentChatMode = chatInput?.getChatMode?.() const agentWorkspacePath = pathFromInput ?? pathFromStore ?? undefinedThen update usages at line 515 and 535:
- chatMode, + chatMode: currentChatMode,- if (chatMode === 'agent' || chatMode === 'acp agent') { + if (currentChatMode === 'agent' || currentChatMode === 'acp agent') {
506-506: Remove leftover comment artifact.The
// #region agent logcomment is a leftover from the debug logging that was removed. Clean up this orphaned region marker.🔎 Proposed fix
const handleSend = async (content: UserMessageContent) => { - // #region agent log const chatInput = chatInputRef.value
🧹 Nitpick comments (4)
src/renderer/src/components/NewThread.vue (3)
240-260: Consider extracting common model-picking logic.Both functions duplicate the flatMap and find pattern from
pickFirstEnabledModel. This is acceptable for clarity, but if more model-picking variants are added, consider a single helper with a predicate parameter.🔎 Optional: Unified helper with predicate
const pickFirstModel = (predicate: (m: { providerId: string; type: ModelType }) => boolean) => { return modelStore.enabledModels .flatMap((p) => p.models.map((m) => ({ ...m, providerId: p.providerId }))) .find((m) => (m.type === ModelType.Chat || m.type === ModelType.ImageGeneration) && predicate(m) ) } const pickFirstAcpModel = () => pickFirstModel((m) => m.providerId === 'acp') const pickFirstNonAcpModel = () => pickFirstModel((m) => m.providerId !== 'acp')
352-391: Mode-aware model switching implementation is sound.The watcher correctly guards against initialization and no-op transitions. One edge case: if
pickFirstAcpModel()returns undefined when switching to 'acp agent' mode, the user silently remains on a non-ACP model. Consider adding user feedback for this scenario.🔎 Optional: Notify user when no matching model is available
if (targetModel) { setActiveFromEnabled(targetModel) // 更新 chat config 和偏好设置 chatStore.updateChatConfig({ modelId: targetModel.id, providerId: targetModel.providerId }) configPresenter.setSetting('preferredModel', { modelId: targetModel.id, providerId: targetModel.providerId }) + } else { + // Consider showing a toast/notification that no matching model is available + console.warn(`No ${shouldBeAcp ? 'ACP' : 'non-ACP'} model available for mode: ${newMode}`) }
535-538: Consider error handling for workspace refresh.The
refreshFileTree()call is awaited beforesendMessage(), which could delay or block message sending if it fails. Consider wrapping in try-catch or using.catch()to ensure message sending proceeds even if refresh fails.🔎 Proposed fix
- if (chatMode === 'agent' || chatMode === 'acp agent') { - await workspaceStore.refreshFileTree() - } + if (chatMode === 'agent' || chatMode === 'acp agent') { + await workspaceStore.refreshFileTree().catch((err) => { + console.warn('Failed to refresh file tree:', err) + }) + } chatStore.sendMessage(content)src/renderer/src/components/chat-input/ChatInput.vue (1)
978-983: Remove stale debug region comment.The debug fetch code has been removed (thank you!), but the
// #region agent logcomment remains as an artifact. Please remove it for cleanliness.🔎 Proposed fix
restoreFocus, getAgentWorkspacePath: () => { - // #region agent log const mode = chatMode.currentMode.value if (mode !== 'agent') return null return workspace.workspacePath.value },
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/renderer/src/components/NewThread.vuesrc/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/stores/chat.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/renderer/src/stores/chat.ts
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.vue: Use Vue 3 Composition API for all components instead of Options API
Use Tailwind CSS with scoped styles for component styling
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/**/*.vue: All user-facing strings must use i18n keys via vue-i18n for internationalization
Ensure proper error handling and loading states in all UI components
Implement responsive design using Tailwind CSS utilities for all UI components
src/renderer/**/*.vue: Use composition API and declarative programming patterns; avoid options API
Structure files: exported component, composables, helpers, static content, types
Use PascalCase for component names (e.g., AuthWizard.vue)
Use Vue 3 with TypeScript, leveraging defineComponent and PropType
Use template syntax for declarative rendering
Use Shadcn Vue, Radix Vue, and Tailwind for components and styling
Implement responsive design with Tailwind CSS; use a mobile-first approach
Use Suspense for asynchronous components
Use <script setup> syntax for concise component definitions
Prefer 'lucide:' icon family as the primary choice for Iconify icons
Import Icon component from '@iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*.{vue,ts,tsx}: All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Use the dynamic locale.value property to switch languages at runtime
Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/**/*.{vue,js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Renderer process code should be placed in
src/renderer(Vue 3 application)
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability in Vue.js applications
Implement proper state management with Pinia in Vue.js applications
Utilize Vue Router for navigation and route management in Vue.js applications
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/src/**/*.vue
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
Use scoped styles to prevent CSS conflicts between Vue components
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Write concise, technical TypeScript code with accurate examples
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid enums; use const objects instead
Use arrow functions for methods and computed properties
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statementsVue 3 app code in
src/renderer/srcshould be organized intocomponents/,stores/,views/,i18n/,lib/directories with shell UI insrc/renderer/shell/
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/**
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use lowercase with dashes for directories (e.g., components/auth-wizard)
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching
Leverage ref, reactive, and computed for reactive state management
Use provide/inject for dependency injection when appropriate
Use Iconify/Vue for icon implementation
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use TypeScript with Vue 3 Composition API for the renderer application
All user-facing strings must use vue-i18n keys insrc/renderer/src/i18n
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/renderer/src/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g.,ChatInput.vue)
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Avoid logging sensitive information (passwords, tokens, PII) in logs
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use camelCase for composables (e.g., useAuthState.ts)
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Implement custom composables for reusable logic
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:20.067Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/pinia-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:20.067Z
Learning: Applies to src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx} : Use modules to organize related state and actions in Pinia stores
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/stores/*.ts : Use Pinia for state management
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Leverage ref, reactive, and computed for reactive state management
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-06-21T15:49:17.044Z
Learnt from: neoragex2002
Repo: ThinkInAIXYZ/deepchat PR: 550
File: src/renderer/src/stores/chat.ts:1011-1035
Timestamp: 2025-06-21T15:49:17.044Z
Learning: In src/renderer/src/stores/chat.ts, the user prefers to keep both `text` and `content` properties in the `handleMeetingInstruction` function's `sendMessage` call, even though they are redundant, rather than removing the `content` property.
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/renderer/src/components/**/*.vue : Vue component files must use PascalCase naming (e.g., `ChatInput.vue`)
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,tsx,vue} : Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Use Iconify/Vue for icon implementation
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Import Icon component from 'iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Prefer 'lucide:' icon family as the primary choice for Iconify icons
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/configPresenter/**/*.ts : Store and retrieve custom prompts via `configPresenter.getCustomPrompts()` for config-based data source management
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:27:20.067Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/pinia-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:20.067Z
Learning: Applies to src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx} : Keep Pinia stores focused on global state, not component-specific data
Applied to files:
src/renderer/src/components/NewThread.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (8)
src/renderer/src/components/NewThread.vue (1)
113-138: LGTM!The new imports and store setup follow Vue 3 Composition API patterns and project conventions. The
useChatModecomposable anduseWorkspaceStoreare properly instantiated at component scope.src/renderer/src/components/chat-input/ChatInput.vue (7)
738-738: Placeholder computed property always returnsfalse.
isModeLockedis referenced in multiple places (button disabled state, popover visibility, watcher) but currently always returnsfalse. If mode locking is intended (e.g., during streaming), consider implementing the actual logic. Otherwise, if this is intentional scaffolding for a future feature, a brief comment would help clarify.
73-127: Well-structured mode selector UI.The mode switch implementation properly uses i18n, Tailwind CSS, and follows Vue 3 patterns. The conditional rendering based on lock state and active mode highlighting are implemented correctly.
816-827: LGTM!The
handleModeSelectfunction has proper guard clause, awaits async operations correctly, includes error handling with informative warning, and closes the menu after selection.
953-970: LGTM!The watcher correctly handles bidirectional mode synchronization between the composable and the chat store, with proper null checks and error handling.
463-464: LGTM!Clean imports for the new chat mode and workspace composables.
745-750: LGTM!The workspace composable is properly initialized with all required reactive dependencies.
128-161: The workspace button UI and tooltip implementation correctly use i18n translations. All tooltip strings (tooltipTitle,tooltipCurrent,tooltipSelect) are properly translated viat()function calls with i18n keys in theuseAgentWorkspacecomposable, meeting the i18n requirements.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (3)
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (1)
142-177: Past review issue addressed: workspace context resolution is now centralized.The
resolveWorkspaceContexthelper method correctly consolidates the duplicated logic that was previously flagged. Both thegetAllToolDefinitionscallback (lines 43-53) andstartStreamCompletion(lines 303-315) now delegate to this shared helper.src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (2)
135-141: Past review issue addressed: Path boundary enforcement now uses separator checks.The
isPathAllowedmethod now correctly enforces workspace boundaries by:
- Checking exact equality with allowed directory (line 137)
- Appending path separator before
startsWithcheck (lines 138-139)This prevents the previously identified vulnerability where sibling paths like
/workspace-evilcould bypass checks for/workspace.
240-249: Past review issue addressed: ReDoS protection implemented in grepSearch.The code now calls
validateRegexPattern(pattern)(line 241) before constructing the RegExp (line 246). This addresses the previously flagged ReDoS vulnerability. The static analysis warning at line 245 is now a false positive since validation precedes construction.
🧹 Nitpick comments (13)
src/renderer/src/components/MessageNavigationSidebar.vue (1)
245-257: Excellent defense-in-depth approach for ReDoS protection.The implementation correctly escapes regex metacharacters and validates the pattern before use. The silent fallback when a pattern is deemed unsafe is safe and reasonable.
One minor UX consideration: users won't receive feedback if their search query can't be highlighted due to safety concerns. While this scenario should be rare given the escaping, you might consider logging this case for debugging purposes.
💡 Optional: Add debug logging for unsafe patterns
const pattern = `(${escapedQuery})` if (!isSafeRegexPattern(pattern)) { + console.debug('Search pattern deemed unsafe, skipping highlight:', query) // If pattern is unsafe, return text without highlighting return text }This would help with debugging without exposing information to end users.
src/main/presenter/workspacePresenter/index.ts (5)
25-36: Validate workspace paths before registration.
registerWorkspaceshould verify the path exists and is a directory before adding it toallowedWorkspaces. Currently, invalid or non-existent paths can be registered and remain in the Set even though they'll fail duringisPathAllowedchecks.🔎 Proposed validation
async registerWorkspace(workspacePath: string): Promise<void> { - const normalized = path.resolve(workspacePath) - this.allowedWorkspaces.add(normalized) + try { + const normalized = path.resolve(workspacePath) + const stat = fs.statSync(normalized) + if (!stat.isDirectory()) { + console.warn(`[Workspace] Cannot register non-directory path: ${normalized}`) + return + } + this.allowedWorkspaces.add(normalized) + } catch (error) { + console.warn(`[Workspace] Cannot register invalid path: ${workspacePath}`, error) + } }
83-107: Consider extracting the common directory-reading logic.Both
readDirectoryandexpandDirectoryhave identical implementations. Extracting the common logic would improve maintainability.🔎 Possible refactor
+ private async readDirectoryInternal( + dirPath: string, + operation: string + ): Promise<WorkspaceFileNode[]> { + if (!this.isPathAllowed(dirPath)) { + console.warn(`[Workspace] Blocked ${operation} attempt for unauthorized path: ${dirPath}`) + return [] + } + const nodes = await readDirectoryShallow(dirPath) + return nodes as unknown as WorkspaceFileNode[] + } + async readDirectory(dirPath: string): Promise<WorkspaceFileNode[]> { - if (!this.isPathAllowed(dirPath)) { - console.warn(`[Workspace] Blocked read attempt for unauthorized path: ${dirPath}`) - return [] - } - const nodes = await readDirectoryShallow(dirPath) - return nodes as unknown as WorkspaceFileNode[] + return this.readDirectoryInternal(dirPath, 'read') } async expandDirectory(dirPath: string): Promise<WorkspaceFileNode[]> { - if (!this.isPathAllowed(dirPath)) { - console.warn(`[Workspace] Blocked expand attempt for unauthorized path: ${dirPath}`) - return [] - } - const nodes = await readDirectoryShallow(dirPath) - return nodes as unknown as WorkspaceFileNode[] + return this.readDirectoryInternal(dirPath, 'expand') }
112-147: Use structured logging instead of console methods.Per coding guidelines, use
logger.error(),logger.warn()methods from logging utilities instead ofconsole.error(). This applies to error logging in bothrevealFileInFolderandopenFile.As per coding guidelines: "Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities."
160-172: Consider conversation-specific event targeting.The
updatePlanEntriesmethod broadcasts toALL_WINDOWS, which may send plan updates to windows that aren't displaying the relevant conversation. While functional, consider whether more targeted broadcasting would be appropriate.
177-185: Same broadcast targeting consideration applies here.Similar to
updatePlanEntries, this method broadcasts terminal output to all windows. Consider whether conversation-specific targeting would be more appropriate.src/renderer/src/components/chat-input/ChatInput.vue (2)
811-822: Simplify redundant condition check after mode update.Line 814 checks
chatMode.currentMode.value === modeimmediately after callingsetMode(mode)on line 813. This condition is redundant because:
- If
setModesucceeds, the condition is always true- If
setModefails, you should handle that error rather than silently skip the config updateConsider simplifying to only check for an active conversation.
🔎 Proposed simplification
const handleModeSelect = async (mode: ChatMode) => { if (isModeLocked.value) return await chatMode.setMode(mode) - if (conversationId.value && chatMode.currentMode.value === mode) { + if (conversationId.value) { try { await chatStore.updateChatConfig({ chatMode: mode }) } catch (error) { console.warn('Failed to update chat mode in conversation settings:', error) } } modeSelectOpen.value = false }
973-978: Remove leftover debug comment.The
// #region agent logcomment on line 974 appears to be a leftover from the debug code that was removed in commit 0f2d32b. Clean up by removing this orphaned region marker.🔎 Proposed cleanup
getAgentWorkspacePath: () => { - // #region agent log const mode = chatMode.currentMode.value if (mode !== 'agent') return null return workspace.workspacePath.value },src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (1)
87-114: Synchronous directory creation may block the main process.
fs.mkdirSyncis used here, which blocks the event loop. While this is typically brief for directory creation, consider using the asyncfs.promises.mkdirfor consistency with the rest of the codebase's async patterns.🔎 Proposed refactor to async
- private getDefaultAgentWorkspacePath(conversationId?: string | null): string { + private async getDefaultAgentWorkspacePath(conversationId?: string | null): Promise<string> { const tempRoot = path.join(app.getPath('temp'), 'deepchat-agent', 'workspaces') try { - fs.mkdirSync(tempRoot, { recursive: true }) + await fs.promises.mkdir(tempRoot, { recursive: true }) } catch (error) { console.warn( '[AgentLoopHandler] Failed to create default workspace root, using system temp:', error ) return app.getPath('temp') } if (!conversationId) { return tempRoot } const workspaceDir = path.join(tempRoot, conversationId) try { - fs.mkdirSync(workspaceDir, { recursive: true }) + await fs.promises.mkdir(workspaceDir, { recursive: true }) return workspaceDir } catch (error) { console.warn( '[AgentLoopHandler] Failed to create conversation workspace, using root temp workspace:', error ) return tempRoot } }src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (1)
588-618: Consider adding depth limit to prevent resource exhaustion in directoryTree.The recursive
buildTreefunction has no depth limit, which could lead to excessive memory usage or stack overflow on deeply nested directory structures.🔎 Proposed fix with depth limit
+ const MAX_TREE_DEPTH = 20 - const buildTree = async (currentPath: string): Promise<TreeEntry[]> => { + const buildTree = async (currentPath: string, depth: number = 0): Promise<TreeEntry[]> => { + if (depth >= MAX_TREE_DEPTH) { + return [] // Stop recursion at max depth + } const validPath = await this.validatePath(currentPath) const entries = await fs.readdir(validPath, { withFileTypes: true }) const result: TreeEntry[] = [] for (const entry of entries) { const entryData: TreeEntry = { name: entry.name, type: entry.isDirectory() ? 'directory' : 'file' } if (entry.isDirectory()) { const subPath = path.join(currentPath, entry.name) - entryData.children = await buildTree(subPath) + entryData.children = await buildTree(subPath, depth + 1) } result.push(entryData) } return result }src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (3)
38-40: Consider lazy initialization of the default workspace path.The default workspace path is created eagerly on every call to
getAllToolDefinitionsin agent mode (Line 39), even if filesystem tools might not be used. This results in unnecessary directory creation and filesystem operations.🔎 Suggested approach: Defer workspace creation
Consider creating the default workspace only when filesystem tools are first accessed, or memoize the result of
getDefaultAgentWorkspacePath()to avoid repeated calls:async getAllToolDefinitions(context: { chatMode: 'chat' | 'agent' | 'acp agent' supportsVision: boolean agentWorkspacePath: string | null }): Promise<MCPToolDefinition[]> { const defs: MCPToolDefinition[] = [] const isAgentMode = context.chatMode === 'agent' - const effectiveWorkspacePath = isAgentMode - ? context.agentWorkspacePath?.trim() || this.getDefaultAgentWorkspacePath() - : null + const effectiveWorkspacePath = isAgentMode && context.agentWorkspacePath?.trim() + ? context.agentWorkspacePath.trim() + : nullThen create the default workspace only in Line 45 if
effectiveWorkspacePathis still null but filesystem handler is needed:if (effectiveWorkspacePath !== this.agentWorkspacePath) { - if (effectiveWorkspacePath) { + const actualPath = effectiveWorkspacePath || (isAgentMode ? this.getDefaultAgentWorkspacePath() : null) + if (actualPath) { - this.fileSystemHandler = new AgentFileSystemHandler([effectiveWorkspacePath]) + this.fileSystemHandler = new AgentFileSystemHandler([actualPath]) } else { this.fileSystemHandler = null } - this.agentWorkspacePath = effectiveWorkspacePath + this.agentWorkspacePath = actualPath }
92-380: Extract schema definitions to avoid repeated object creation.The zod schemas (lines 93-186) and MCPToolDefinition array (lines 188-379) are recreated on every call to
getFileSystemToolDefinitions, which is inefficient. Since these definitions are static, they should be defined once as class-level or module-level constants.🔎 Suggested refactor to improve performance
Move schema definitions outside the method:
// Define schemas as module-level constants const FILE_SYSTEM_SCHEMAS = { ReadFile: z.object({ paths: z.array(z.string()).min(1) }), WriteFile: z.object({ path: z.string(), content: z.string() }), // ... other schemas } as const // Helper to create MCPToolDefinition function createFSToolDef( name: string, description: string, schema: z.ZodType ): MCPToolDefinition { return { type: 'function', function: { name, description, parameters: zodToJsonSchema(schema) as { type: string properties: Record<string, unknown> required?: string[] } }, server: { name: 'agent-filesystem', icons: '📁', description: 'Agent FileSystem tools' } } } // Then cache the definitions array as a class property private readonly fsToolDefinitions: MCPToolDefinition[] // Initialize in constructor this.fsToolDefinitions = [ createFSToolDef('read_file', 'Read the contents of one or more files', FILE_SYSTEM_SCHEMAS.ReadFile), createFSToolDef('write_file', 'Write content to a file', FILE_SYSTEM_SCHEMAS.WriteFile), // ... other tools ] // Simplify the method private getFileSystemToolDefinitions(): MCPToolDefinition[] { return this.fsToolDefinitions }This eliminates repeated object creation and improves performance, especially during active agent sessions where this method may be called frequently.
418-430: Memoize the default workspace path to avoid repeated filesystem operations.This method is called from
getAllToolDefinitions(Line 39) and performs filesystem operations (directory creation) on each invocation. Consider memoizing the result to avoid repeated disk I/O.Additionally, the fallback to
app.getPath('temp')at Line 427 without subdirectories could cause issues if the workspace is shared across multiple agent sessions.🔎 Suggested improvement with memoization
Add a class property to cache the result:
export class AgentToolManager { private readonly yoBrowserPresenter: IYoBrowserPresenter private agentWorkspacePath: string | null private fileSystemHandler: AgentFileSystemHandler | null = null + private defaultWorkspacePath: string | null = null // ... private getDefaultAgentWorkspacePath(): string { + if (this.defaultWorkspacePath) { + return this.defaultWorkspacePath + } + const tempDir = path.join(app.getPath('temp'), 'deepchat-agent', 'workspaces') try { fs.mkdirSync(tempDir, { recursive: true }) + this.defaultWorkspacePath = tempDir } catch (error) { console.warn( '[AgentToolManager] Failed to create default workspace, using system temp:', error ) - return app.getPath('temp') + // Still use a subdirectory for isolation + const fallback = path.join(app.getPath('temp'), 'deepchat-workspace-fallback') + try { + fs.mkdirSync(fallback, { recursive: true }) + this.defaultWorkspacePath = fallback + } catch { + this.defaultWorkspacePath = app.getPath('temp') + } } - return tempDir + return this.defaultWorkspacePath }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
package.jsonsrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/filesystem.tssrc/main/presenter/workspacePresenter/index.tssrc/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/components/chat-input/ChatInput.vuesrc/renderer/src/i18n/da-DK/chat.jsonsrc/renderer/src/stores/mcp.tssrc/shared/regexValidator.tstest/main/presenter/filesystem.test.ts
💤 Files with no reviewable changes (2)
- test/main/presenter/filesystem.test.ts
- src/main/presenter/mcpPresenter/inMemoryServers/filesystem.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/renderer/src/i18n/da-DK/chat.json
- package.json
🧰 Additional context used
📓 Path-based instructions (33)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/renderer/src/components/chat-input/ChatInput.vuesrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.vue: Use Vue 3 Composition API for all components instead of Options API
Use Tailwind CSS with scoped styles for component styling
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/**/*.vue: All user-facing strings must use i18n keys via vue-i18n for internationalization
Ensure proper error handling and loading states in all UI components
Implement responsive design using Tailwind CSS utilities for all UI components
src/renderer/**/*.vue: Use composition API and declarative programming patterns; avoid options API
Structure files: exported component, composables, helpers, static content, types
Use PascalCase for component names (e.g., AuthWizard.vue)
Use Vue 3 with TypeScript, leveraging defineComponent and PropType
Use template syntax for declarative rendering
Use Shadcn Vue, Radix Vue, and Tailwind for components and styling
Implement responsive design with Tailwind CSS; use a mobile-first approach
Use Suspense for asynchronous components
Use <script setup> syntax for concise component definitions
Prefer 'lucide:' icon family as the primary choice for Iconify icons
Import Icon component from '@iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*.{vue,ts,tsx}: All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Use the dynamic locale.value property to switch languages at runtime
Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/renderer/src/components/chat-input/ChatInput.vuesrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/renderer/**/*.{vue,js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Renderer process code should be placed in
src/renderer(Vue 3 application)
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability in Vue.js applications
Implement proper state management with Pinia in Vue.js applications
Utilize Vue Router for navigation and route management in Vue.js applications
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.vue
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
Use scoped styles to prevent CSS conflicts between Vue components
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Write concise, technical TypeScript code with accurate examples
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid enums; use const objects instead
Use arrow functions for methods and computed properties
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statementsVue 3 app code in
src/renderer/srcshould be organized intocomponents/,stores/,views/,i18n/,lib/directories with shell UI insrc/renderer/shell/
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use lowercase with dashes for directories (e.g., components/auth-wizard)
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching
Leverage ref, reactive, and computed for reactive state management
Use provide/inject for dependency injection when appropriate
Use Iconify/Vue for icon implementation
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use TypeScript with Vue 3 Composition API for the renderer application
All user-facing strings must use vue-i18n keys insrc/renderer/src/i18n
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/stores/mcp.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g.,ChatInput.vue)
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/components/chat-input/ChatInput.vue
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/renderer/src/components/chat-input/ChatInput.vuesrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/shared/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Shared type definitions and utilities between main and renderer processes should be placed in
src/shared
Files:
src/shared/regexValidator.ts
src/shared/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Shared types and utilities should be placed in
src/shared/
Files:
src/shared/regexValidator.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/shared/regexValidator.tssrc/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/renderer/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use the
usePresenter.tscomposable for renderer-to-main IPC communication to call presenter methods directly
Files:
src/renderer/src/stores/mcp.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/pinia-best-practices.mdc)
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}: Use modules to organize related state and actions in Pinia stores
Implement proper state persistence for maintaining data across sessions in Pinia stores
Use getters for computed state properties in Pinia stores
Utilize actions for side effects and asynchronous operations in Pinia stores
Keep Pinia stores focused on global state, not component-specific data
Files:
src/renderer/src/stores/mcp.ts
src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use TypeScript for all code; prefer types over interfaces
Files:
src/renderer/src/stores/mcp.ts
src/renderer/**/stores/*.ts
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use Pinia for state management
Files:
src/renderer/src/stores/mcp.ts
src/renderer/src/stores/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use Pinia for state management
Files:
src/renderer/src/stores/mcp.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/main/presenter/mcpPresenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Register new MCP tools in
mcpPresenter/index.tsafter implementing them ininMemoryServers/
Files:
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
src/main/presenter/llmProviderPresenter/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)
Define the standardized
LLMCoreStreamEventinterface with fields:type(text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data),content(for text),reasoning_content(for reasoning),tool_call_id,tool_call_name,tool_call_arguments_chunk(for streaming),tool_call_arguments_complete(for complete arguments),error_message,usageobject with token counts,stop_reason(tool_use | max_tokens | stop_sequence | error | complete), andimage_dataobject with Base64-encoded data and mimeType
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
🧠 Learnings (36)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
📚 Learning: 2025-11-25T05:27:49.615Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-router-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:49.615Z
Learning: Applies to src/renderer/src/router/**/*.{ts,tsx,js,jsx} : Implement proper navigation guards for authentication and authorization in Vue Router
Applied to files:
src/renderer/src/components/MessageNavigationSidebar.vue
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Applied to files:
src/renderer/src/components/MessageNavigationSidebar.vuesrc/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.vue : Ensure proper error handling and loading states in all UI components
Applied to files:
src/renderer/src/components/MessageNavigationSidebar.vue
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.vue : All user-facing strings must use i18n keys via vue-i18n for internationalization
Applied to files:
src/renderer/src/components/MessageNavigationSidebar.vue
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Applied to files:
src/renderer/src/components/MessageNavigationSidebar.vue
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
Applied to files:
src/renderer/src/stores/mcp.tssrc/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.tssrc/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Applied to files:
src/renderer/src/stores/mcp.ts
📚 Learning: 2025-06-21T15:48:29.950Z
Learnt from: neoragex2002
Repo: ThinkInAIXYZ/deepchat PR: 550
File: src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts:250-252
Timestamp: 2025-06-21T15:48:29.950Z
Learning: In the meeting server implementation (src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts), when multiple tabs have the same title, the user prefers to let the code silently select the first match without adding warnings or additional ambiguity handling.
Applied to files:
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.tssrc/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/configPresenter/**/*.ts : Store and retrieve custom prompts via `configPresenter.getCustomPrompts()` for config-based data source management
Applied to files:
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/**/*.ts : Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Applied to files:
src/main/presenter/workspacePresenter/index.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Applied to files:
src/main/presenter/workspacePresenter/index.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/main/presenter/workspacePresenter/index.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/workspacePresenter/index.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Applied to files:
src/main/presenter/workspacePresenter/index.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `stop` events by checking `stop_reason`: if `'tool_use'`, add the buffered assistant message and prepare for the next loop iteration; otherwise, add the final assistant message and exit the loop
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations (`src/main/presenter/llmProviderPresenter/providers/*.ts`), the `coreStream(messages, modelId, temperature, maxTokens)` method should perform a *single-pass* streaming API request for each conversation round without containing multi-turn tool call loop logic
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `reasoning`, `text`, `image_data`, and `usage` events by processing and forwarding them through `STREAM_EVENTS.RESPONSE` events to the frontend
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Tool call events: strictly follow sequence `tool_call_start → tool_call_chunk* → tool_call_end`, ensure `tool_call_id` is required and stable
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to **/*.{ts,tsx,js,jsx,vue} : Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Avoid logging sensitive information (passwords, tokens, PII) in logs
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:26:15.929Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/development-setup.mdc:0-0
Timestamp: 2025-11-25T05:26:15.929Z
Learning: Applies to **/*.{js,ts,jsx,tsx,mjs,cjs} : Write logs and comments in English
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use camelCase for composables (e.g., useAuthState.ts)
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Implement custom composables for reusable logic
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:20.067Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/pinia-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:20.067Z
Learning: Applies to src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx} : Use modules to organize related state and actions in Pinia stores
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/stores/*.ts : Use Pinia for state management
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
🧬 Code graph analysis (6)
src/renderer/src/stores/mcp.ts (1)
src/shared/regexValidator.ts (1)
isSafeRegexPattern(36-47)
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.ts (1)
src/shared/regexValidator.ts (1)
isSafeRegexPattern(36-47)
src/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.ts (1)
src/shared/regexValidator.ts (1)
isSafeRegexPattern(36-47)
src/main/presenter/workspacePresenter/index.ts (6)
src/shared/types/presenters/index.d.ts (5)
IWorkspacePresenter(55-55)WorkspaceFileNode(52-52)WorkspacePlanEntry(51-51)WorkspaceRawPlanEntry(54-54)WorkspaceTerminalSnippet(53-53)src/shared/types/presenters/workspace.d.ts (5)
IWorkspacePresenter(75-140)WorkspaceFileNode(30-41)WorkspacePlanEntry(14-25)WorkspaceRawPlanEntry(66-70)WorkspaceTerminalSnippet(46-61)src/main/presenter/acpWorkspacePresenter/planStateManager.ts (1)
PlanStateManager(12-119)src/main/presenter/acpWorkspacePresenter/directoryReader.ts (1)
readDirectoryShallow(30-73)src/main/events.ts (1)
WORKSPACE_EVENTS(248-252)src/renderer/src/events.ts (1)
WORKSPACE_EVENTS(189-193)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (2)
src/shared/types/presenters/legacy.presenters.d.ts (2)
IYoBrowserPresenter(190-220)MCPToolDefinition(1476-1492)src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (1)
AgentFileSystemHandler(115-673)
src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (1)
src/shared/regexValidator.ts (1)
validateRegexPattern(11-28)
🪛 ast-grep (0.40.3)
src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.ts
[warning] 196-196: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
src/main/presenter/mcpPresenter/inMemoryServers/conversationSearchServer.ts
[warning] 468-468: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, 'gi')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts
[warning] 245-245: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, regexFlags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 364-364: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, regexFlags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 375-375: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, caseSensitive ? 'g' : 'gi')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 511-511: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(parsed.data.pattern, flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (3)
38-40: Add error handling for default workspace path creation.The
getDefaultAgentWorkspacePath()call at Line 39 occurs within a ternary expression without explicit error handling. Although the method has internal error handling with a fallback, wrapping this in a try-catch would make error recovery more explicit and allow for better error logging.🔎 Proposed improvement for safer error handling
- const effectiveWorkspacePath = isAgentMode - ? context.agentWorkspacePath?.trim() || this.getDefaultAgentWorkspacePath() - : null + let effectiveWorkspacePath: string | null = null + if (isAgentMode) { + try { + effectiveWorkspacePath = context.agentWorkspacePath?.trim() || this.getDefaultAgentWorkspacePath() + } catch (error) { + // Log error with structured logger and use null as fallback + console.error('[AgentToolManager] Failed to determine workspace path', error) + effectiveWorkspacePath = null + } + }
95-383: Consider extracting repeated metadata to reduce duplication.The server metadata object and type assertion pattern are repeated across all 11 tool definitions. Extracting these to constants would improve maintainability and reduce the risk of inconsistencies.
🔎 Suggested refactor to reduce duplication
private getFileSystemToolDefinitions(): MCPToolDefinition[] { + // Common metadata for all filesystem tools + const FILESYSTEM_SERVER_METADATA = { + name: 'agent-filesystem', + icons: '📁', + description: 'Agent FileSystem tools' + } + + type JSONSchemaParams = { + type: string + properties: Record<string, unknown> + required?: string[] + } + + const createToolDef = ( + name: string, + description: string, + schema: z.ZodType<any> + ): MCPToolDefinition => ({ + type: 'function', + function: { + name, + description, + parameters: zodToJsonSchema(schema) as JSONSchemaParams + }, + server: FILESYSTEM_SERVER_METADATA + }) const ReadFileSchema = z.object({ paths: z.array(z.string()).min(1) }) // ... other schemas ... return [ - { - type: 'function', - function: { - name: 'read_file', - description: 'Read the contents of one or more files', - parameters: zodToJsonSchema(ReadFileSchema) as { - type: string - properties: Record<string, unknown> - required?: string[] - } - }, - server: { - name: 'agent-filesystem', - icons: '📁', - description: 'Agent FileSystem tools' - } - }, + createToolDef('read_file', 'Read the contents of one or more files', ReadFileSchema), // ... repeat for other tools ... ] }
385-400: Consider deriving tool names from a single source of truth.The filesystem tool names are hardcoded here and must stay in sync with
getFileSystemToolDefinitions(Lines 95-383) andcallFileSystemTool(Lines 410-435). When adding a new tool, all three locations need updates, increasing maintenance burden and risk of inconsistencies.💡 Suggested approach
Define tool names as a constant array or derive them from tool definitions to ensure single source of truth. For example:
private static readonly FILESYSTEM_TOOLS = [ 'read_file', 'write_file', 'list_directory', 'create_directory', 'move_files', 'edit_text', 'search_files', 'directory_tree', 'get_file_info', 'grep_search', 'text_replace' ] as const private isFileSystemTool(toolName: string): boolean { return AgentToolManager.FILESYSTEM_TOOLS.includes(toolName as any) }Then reference this array in all three locations, or better yet, refactor to use a Map/Record structure that combines tool metadata, schemas, and handlers.
src/renderer/src/components/chat-input/ChatInput.vue (2)
73-123: Remove redundant title attribute.Line 86 sets a
titleattribute that duplicates the tooltip content defined at line 121. The Tooltip component already provides accessible hover/focus text, making the native title redundant and potentially causing double tooltips.🔎 Proposed fix
<PopoverTrigger as-child> <Button variant="outline" :class="[ 'w-7 h-7 text-xs rounded-lg', variant === 'chat' ? 'text-accent-foreground' : '' ]" size="icon" - :title="t('chat.mode.current', { mode: chatMode.currentLabel.value })" > <Icon :icon="chatMode.currentIcon.value" class="w-4 h-4" /> </Button>
962-968: Remove orphaned debug comment.Line 963 contains a
#region agent logcomment that's a leftover from the debug fetch code removed in a previous commit (0f2d32b). This orphaned comment is now misleading and should be removed.🔎 Proposed fix
getAgentWorkspacePath: () => { - // #region agent log const mode = chatMode.currentMode.value if (mode !== 'agent') return null return workspace.workspacePath.value },
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/renderer/src/components/chat-input/ChatInput.vue
🧰 Additional context used
📓 Path-based instructions (25)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/renderer/src/components/chat-input/ChatInput.vue
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/presenter/llmProviderPresenter/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)
Define the standardized
LLMCoreStreamEventinterface with fields:type(text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data),content(for text),reasoning_content(for reasoning),tool_call_id,tool_call_name,tool_call_arguments_chunk(for streaming),tool_call_arguments_complete(for complete arguments),error_message,usageobject with token counts,stop_reason(tool_use | max_tokens | stop_sequence | error | complete), andimage_dataobject with Base64-encoded data and mimeType
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/renderer/src/components/chat-input/ChatInput.vue
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.vue: Use Vue 3 Composition API for all components instead of Options API
Use Tailwind CSS with scoped styles for component styling
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/**/*.vue: All user-facing strings must use i18n keys via vue-i18n for internationalization
Ensure proper error handling and loading states in all UI components
Implement responsive design using Tailwind CSS utilities for all UI components
src/renderer/**/*.vue: Use composition API and declarative programming patterns; avoid options API
Structure files: exported component, composables, helpers, static content, types
Use PascalCase for component names (e.g., AuthWizard.vue)
Use Vue 3 with TypeScript, leveraging defineComponent and PropType
Use template syntax for declarative rendering
Use Shadcn Vue, Radix Vue, and Tailwind for components and styling
Implement responsive design with Tailwind CSS; use a mobile-first approach
Use Suspense for asynchronous components
Use <script setup> syntax for concise component definitions
Prefer 'lucide:' icon family as the primary choice for Iconify icons
Import Icon component from '@iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*.{vue,ts,tsx}: All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Use the dynamic locale.value property to switch languages at runtime
Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.{vue,js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Renderer process code should be placed in
src/renderer(Vue 3 application)
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability in Vue.js applications
Implement proper state management with Pinia in Vue.js applications
Utilize Vue Router for navigation and route management in Vue.js applications
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.vue
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
Use scoped styles to prevent CSS conflicts between Vue components
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Write concise, technical TypeScript code with accurate examples
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid enums; use const objects instead
Use arrow functions for methods and computed properties
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statementsVue 3 app code in
src/renderer/srcshould be organized intocomponents/,stores/,views/,i18n/,lib/directories with shell UI insrc/renderer/shell/
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use lowercase with dashes for directories (e.g., components/auth-wizard)
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching
Leverage ref, reactive, and computed for reactive state management
Use provide/inject for dependency injection when appropriate
Use Iconify/Vue for icon implementation
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use TypeScript with Vue 3 Composition API for the renderer application
All user-facing strings must use vue-i18n keys insrc/renderer/src/i18n
Files:
src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g.,ChatInput.vue)
Files:
src/renderer/src/components/chat-input/ChatInput.vue
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Provide meaningful error messages when catching errors
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Error handling: use `error` event uniformly to carry error messages, avoid mixing errors into other event fields
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to **/*.{ts,tsx,js,jsx,vue} : Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Avoid logging sensitive information (passwords, tokens, PII) in logs
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use camelCase for composables (e.g., useAuthState.ts)
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Implement custom composables for reusable logic
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:20.067Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/pinia-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:20.067Z
Learning: Applies to src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx} : Use modules to organize related state and actions in Pinia stores
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/stores/*.ts : Use Pinia for state management
Applied to files:
src/renderer/src/components/chat-input/ChatInput.vue
🧬 Code graph analysis (1)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (2)
src/shared/types/presenters/legacy.presenters.d.ts (2)
IYoBrowserPresenter(190-220)MCPToolDefinition(1476-1492)src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (1)
AgentFileSystemHandler(115-673)
🔇 Additional comments (8)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (4)
74-93: LGTM! Tool routing logic is well-structured.The method properly routes tools to their respective handlers with clear error messages when handlers are not initialized. The previous review concern has been addressed effectively.
402-436: LGTM! Comprehensive tool routing with proper error handling.The switch statement covers all filesystem tools with appropriate handler method calls and includes a defensive null check for the handler.
438-450: Default workspace path creation is well-designed with fallback.The method properly creates a dedicated workspace directory with recursive creation and falls back gracefully to system temp on failure. Note: The
console.warnat Line 443 should use structured logging (already flagged in Lines 54-59 review).
10-13: No changes needed.AgentToolManagerOptionsis used only internally within the constructor and is not referenced by external code, so exporting it is unnecessary. It serves as an internal type annotation and does not need to be part of the public API.Likely an incorrect or invalid review comment.
src/renderer/src/components/chat-input/ChatInput.vue (4)
460-461: LGTM! Composable integration follows best practices.The new composables
useChatModeanduseAgentWorkspaceare properly imported and initialized following Vue 3 Composition API patterns. Dependencies are correctly passed touseAgentWorkspace(conversationId, activeModel, chatMode).Also applies to: 562-564, 736-741
807-817: LGTM! Mode selection logic is correct and defensive.The function properly:
- Updates local mode state via
chatMode.setMode(mode)- Defensively verifies mode was set before persisting to chat config
- Handles errors gracefully
- Closes the mode selector UI
937-954: LGTM! Mode synchronization watcher is well-implemented.The watcher properly handles:
- Bidirectional sync between local mode state and stored chat config
- Initialization when mode hasn't been persisted yet
- Mode updates when switching conversations
- Error cases with appropriate logging
- Runs immediately on mount with
immediate: true
125-158: No action required—workspace tooltip text is properly internationalized.Lines 149, 152, and 155 reference
workspace.tooltipTitle,workspace.tooltipCurrent, andworkspace.tooltipSelectfrom theuseAgentWorkspacecomposable. The composable correctly usesuseI18n()and returns i18n-translated strings via thet()function for all tooltip properties (chat.input.agentWorkspaceTooltip,chat.input.agentWorkspaceCurrent,chat.input.agentWorkspaceSelect), fully complying with internationalization requirements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (3)
75-83: Consider error handling for JSON.stringify.Line 82 uses
JSON.stringifywithout error handling. If the response contains circular references or non-serializable values, it will throw an uncaught error.🔎 Proposed fix to add error handling
async callTool(toolName: string, args: Record<string, unknown>): Promise<string> { // Route to Yo Browser tools if (toolName.startsWith('browser_')) { const response = await this.yoBrowserPresenter.callTool( toolName, args as Record<string, unknown> ) - return typeof response === 'string' ? response : JSON.stringify(response) + if (typeof response === 'string') return response + try { + return JSON.stringify(response) + } catch (error) { + logger.error('[AgentToolManager] Failed to serialize browser tool response', { error, toolName }) + return '[Error: Unable to serialize response]' + } }
386-401: Reduce maintenance burden by extracting filesystem tool names.The hardcoded tool list must be kept in sync with
getFileSystemToolDefinitionsandcallFileSystemTool. If a tool is added or removed, three locations require updates.🔎 Proposed fix to extract tool names to a constant
At the top of the class (after the field declarations):
private static readonly FILESYSTEM_TOOLS = [ 'read_file', 'write_file', 'list_directory', 'create_directory', 'move_files', 'edit_text', 'search_files', 'directory_tree', 'get_file_info', 'grep_search', 'text_replace' ] as constThen update the method:
private isFileSystemTool(toolName: string): boolean { - const filesystemTools = [ - 'read_file', - 'write_file', - 'list_directory', - 'create_directory', - 'move_files', - 'edit_text', - 'search_files', - 'directory_tree', - 'get_file_info', - 'grep_search', - 'text_replace' - ] - return filesystemTools.includes(toolName) + return AgentToolManager.FILESYSTEM_TOOLS.includes(toolName as any) }This ensures all three locations reference the same source of truth.
407-409: Remove redundant null check.The null check for
fileSystemHandlerat lines 407-409 is redundant. ThecallToolmethod already performs this check at lines 87-89 before callingcallFileSystemTool.🔎 Proposed fix
private async callFileSystemTool( toolName: string, args: Record<string, unknown> ): Promise<string> { - if (!this.fileSystemHandler) { - throw new Error('FileSystem handler not initialized') - } - switch (toolName) { case 'read_file': - return await this.fileSystemHandler.readFile(args) + return await this.fileSystemHandler!.readFile(args) case 'write_file': - return await this.fileSystemHandler.writeFile(args) + return await this.fileSystemHandler!.writeFile(args) // ... rest of cases with non-null assertionOr keep the defensive check if preferred for safety.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/presenter/llmProviderPresenter/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)
Define the standardized
LLMCoreStreamEventinterface with fields:type(text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data),content(for text),reasoning_content(for reasoning),tool_call_id,tool_call_name,tool_call_arguments_chunk(for streaming),tool_call_arguments_complete(for complete arguments),error_message,usageobject with token counts,stop_reason(tool_use | max_tokens | stop_sequence | error | complete), andimage_dataobject with Base64-encoded data and mimeType
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Provide meaningful error messages when catching errors
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Error handling: use `error` event uniformly to carry error messages, avoid mixing errors into other event fields
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `stop` events by checking `stop_reason`: if `'tool_use'`, add the buffered assistant message and prepare for the next loop iteration; otherwise, add the final assistant message and exit the loop
Applied to files:
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
🧬 Code graph analysis (1)
src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts (2)
src/shared/types/presenters/legacy.presenters.d.ts (2)
IYoBrowserPresenter(190-220)MCPToolDefinition(1476-1492)src/main/presenter/llmProviderPresenter/agent/agentFileSystemHandler.ts (1)
AgentFileSystemHandler(115-673)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
src/renderer/src/components/NewThread.vue (1)
509-509: Variable shadowing:chatModeshadows composable import.The local
const chatModeshadows thechatModeimported fromuseChatMode()at line 129, which can cause confusion and potential bugs. This was flagged in a previous review.🔎 Proposed fix: Rename local variable
- const chatMode = chatInput?.getChatMode?.() + const currentChatMode = chatInput?.getChatMode?.() const agentWorkspacePath = pathFromInput ?? pathFromStore ?? undefinedThen update usages at lines 514 and 534:
- chatMode, + chatMode: currentChatMode,- if (chatMode === 'agent' || chatMode === 'acp agent') { + if (currentChatMode === 'agent' || currentChatMode === 'acp agent') {
🧹 Nitpick comments (9)
src/main/presenter/browser/YoBrowserPresenter.ts (2)
303-313: Consider more descriptive error messages.The aggregation of text content from tool results is correct, but the fallback error message on line 310 could be more informative.
🔎 Proposed enhancement
if (result.isError) { - throw new Error(textContent || 'Tool execution failed') + throw new Error(textContent || `Tool '${toolName}' execution failed without error details`) }This provides context about which tool failed when no error text is available.
391-409: Inconsistent change detection between title and favicon updates.The favicon listener checks if the value changed before emitting (line 403), but the title listener always emits even if the title hasn't changed. This inconsistency could lead to unnecessary event emissions.
🔎 Proposed fix for consistency
contents.on('page-title-updated', (_event, title) => { const tab = this.tabIdToBrowserTab.get(tabId) if (!tab) return - tab.title = title || tab.url - tab.updatedAt = Date.now() - this.emitTabUpdated(tab) + const newTitle = title || tab.url + if (tab.title !== newTitle) { + tab.title = newTitle + tab.updatedAt = Date.now() + this.emitTabUpdated(tab) + } })This ensures both listeners follow the same pattern of only emitting when the value actually changes.
src/main/presenter/browser/tools/navigate.ts (3)
96-98: Extract magic number to named constant.The 100ms delay is hardcoded. Consider extracting it to a named constant for better maintainability and documentation.
🔎 Proposed refactor
At the top of the file, add:
const TAB_INITIALIZATION_DELAY_MS = 100Then replace the hardcoded value:
- await new Promise((resolve) => setTimeout(resolve, 100)) + await new Promise((resolve) => setTimeout(resolve, TAB_INITIALIZATION_DELAY_MS))
134-137: Extract navigation timeout to named constant.The 15-second timeout is hardcoded here and duplicated in lines 147 and 154. Extract to a named constant for consistency and maintainability.
🔎 Proposed refactor
At the top of the file, add:
const NAVIGATION_TIMEOUT_MS = 15000Then replace all three occurrences:
timeout = setTimeout(() => { cleanup() reject(new Error('Timeout waiting for page load')) - }, 15000) + }, NAVIGATION_TIMEOUT_MS)And similarly on lines 147 and 154:
- await browserTab.navigate(parsed.url, 15000) + await browserTab.navigate(parsed.url, NAVIGATION_TIMEOUT_MS)
104-156: Consider extracting complex navigation logic to helper function.The nested logic for waiting on navigation completion (loading detection, event listeners, timeout handling, URL verification) spans 50+ lines and has high cognitive complexity. Extracting this into a separate helper function would improve readability, testability, and maintainability.
💡 Suggested approach
Extract to a helper function like:
async function ensureNavigationComplete( browserTab: BrowserTab, targetUrl: string, timeoutMs: number = 15000 ): Promise<void> { if (browserTab.contents.isLoading()) { // Wait for current navigation to complete await new Promise<void>((resolve, reject) => { // ... existing event listener logic }) // Check if URL matches after loading const finalUrl = browserTab.contents.getURL() if (finalUrl !== targetUrl) { await browserTab.navigate(targetUrl, timeoutMs) } } else { // Tab is not loading, check if URL matches const currentUrl = browserTab.contents.getURL() if (currentUrl !== targetUrl) { await browserTab.navigate(targetUrl, timeoutMs) } } }Then simplify the main handler:
if (browserTab) { try { await ensureNavigationComplete(browserTab, parsed.url) return { content: [{ type: 'text' as const, text: `Created new tab and navigated to ${parsed.url}\nTitle: ${browserTab.title || 'unknown'}` }] } } catch (error) { // ... error handling } }src/renderer/src/components/NewThread.vue (1)
233-260: Consider consolidating model picker helpers.The three functions (
pickFirstEnabledModel,pickFirstAcpModel,pickFirstNonAcpModel) share identicalflatMaplogic. Consider extracting a common helper with a predicate parameter to reduce duplication.🔎 Proposed refactor
+const pickFirstEnabledModelWhere = ( + predicate: (m: { providerId: string; type?: ModelType }) => boolean +) => { + return modelStore.enabledModels + .flatMap((p) => p.models.map((m) => ({ ...m, providerId: p.providerId }))) + .find( + (m) => + predicate(m) && (m.type === ModelType.Chat || m.type === ModelType.ImageGeneration) + ) +} + const pickFirstEnabledModel = () => { - const found = modelStore.enabledModels - .flatMap((p) => p.models.map((m) => ({ ...m, providerId: p.providerId }))) - .find((m) => m.type === ModelType.Chat || m.type === ModelType.ImageGeneration) - return found + return pickFirstEnabledModelWhere(() => true) } const pickFirstAcpModel = () => { - const found = modelStore.enabledModels - .flatMap((p) => p.models.map((m) => ({ ...m, providerId: p.providerId }))) - .find( - (m) => - m.providerId === 'acp' && - (m.type === ModelType.Chat || m.type === ModelType.ImageGeneration) - ) - return found + return pickFirstEnabledModelWhere((m) => m.providerId === 'acp') } const pickFirstNonAcpModel = () => { - const found = modelStore.enabledModels - .flatMap((p) => p.models.map((m) => ({ ...m, providerId: p.providerId }))) - .find( - (m) => - m.providerId !== 'acp' && - (m.type === ModelType.Chat || m.type === ModelType.ImageGeneration) - ) - return found + return pickFirstEnabledModelWhere((m) => m.providerId !== 'acp') }src/main/presenter/llmProviderPresenter/managers/errorClassification.ts (1)
23-101: Substring matching on error messages is fragile.The error classification relies solely on substring matching against lowercase error messages, which has several limitations:
- Provider-dependent formatting: Different LLM providers and tools may format the same error differently (e.g., "Invalid JSON" vs "JSON parsing failed" vs "Malformed JSON payload").
- No structured error handling: Consider checking error types/codes when available, not just message strings.
- Missing common patterns: Consider adding patterns for permanently non-retryable errors like:
- File/resource not found (without "permission")
- Quota exceeded (hard limits, not rate limits)
- Resource already exists conflicts
- Invalid credentials that won't change
- Localization blind: Assumes all error messages are in English.
The current categories are reasonable, but consider augmenting with structured error type checks when available from providers.
🔎 Suggested enhancement
export function isNonRetryableError(error: Error | string): boolean { + // Check structured error properties first if available + if (error instanceof Error) { + // Example: Check for error codes/types from known providers + const errorWithCode = error as any + if (errorWithCode.code) { + // Handle known non-retryable error codes + const nonRetryableCodes = ['INVALID_ARGUMENT', 'PERMISSION_DENIED', 'NOT_FOUND'] + if (nonRetryableCodes.includes(errorWithCode.code)) { + return true + } + } + } + const errorMessage = error instanceof Error ? error.message : String(error) const lowerMessage = errorMessage.toLowerCase()Based on coding guidelines requiring proper error classification and handling.
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts (1)
234-267: Simplify error classification variable.The error classification logic creates a redundant intermediate variable. Since
isNonRetryableErroralready handlesError | string, you can passtoolErrordirectly.🔎 Proposed simplification
const errorMessage = toolError instanceof Error ? toolError.message : String(toolError) - // Check if error is non-retryable (should stop the loop) - const errorForClassification: Error | string = - toolError instanceof Error ? toolError : String(toolError) - const isNonRetryable = isNonRetryableError(errorForClassification) + // Check if error is non-retryable (should stop the loop) + const isNonRetryable = isNonRetryableError(toolError)src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (1)
65-85: Consider structured logging for initialization errors.The lazy initialization pattern is sound, but the error throw bypasses structured logging. Consider logging the error before throwing for better observability.
🔎 Suggested improvement
private getToolPresenter(): ToolPresenter { if (!this.toolPresenter) { // Check if presenter is fully initialized if (!presenter.mcpPresenter || !presenter.yoBrowserPresenter) { + console.error('[AgentLoopHandler] ToolPresenter dependencies not initialized') throw new Error( 'ToolPresenter dependencies not initialized. mcpPresenter and yoBrowserPresenter must be initialized first.' ) }Based on coding guidelines requiring structured logging with appropriate log levels.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/browser/tools/navigate.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/renderer/src/components/NewThread.vuesrc/renderer/src/components/chat-input/ChatInput.vue
🚧 Files skipped from review as they are similar to previous changes (1)
- src/renderer/src/components/chat-input/ChatInput.vue
🧰 Additional context used
📓 Path-based instructions (25)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/renderer/src/components/NewThread.vuesrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/main/presenter/llmProviderPresenter/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)
Define the standardized
LLMCoreStreamEventinterface with fields:type(text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data),content(for text),reasoning_content(for reasoning),tool_call_id,tool_call_name,tool_call_arguments_chunk(for streaming),tool_call_arguments_complete(for complete arguments),error_message,usageobject with token counts,stop_reason(tool_use | max_tokens | stop_sequence | error | complete), andimage_dataobject with Base64-encoded data and mimeType
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/renderer/src/components/NewThread.vuesrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/renderer/src/components/NewThread.vuesrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.tssrc/main/presenter/browser/tools/navigate.ts
**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.vue: Use Vue 3 Composition API for all components instead of Options API
Use Tailwind CSS with scoped styles for component styling
Files:
src/renderer/src/components/NewThread.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/**/*.vue: All user-facing strings must use i18n keys via vue-i18n for internationalization
Ensure proper error handling and loading states in all UI components
Implement responsive design using Tailwind CSS utilities for all UI components
src/renderer/**/*.vue: Use composition API and declarative programming patterns; avoid options API
Structure files: exported component, composables, helpers, static content, types
Use PascalCase for component names (e.g., AuthWizard.vue)
Use Vue 3 with TypeScript, leveraging defineComponent and PropType
Use template syntax for declarative rendering
Use Shadcn Vue, Radix Vue, and Tailwind for components and styling
Implement responsive design with Tailwind CSS; use a mobile-first approach
Use Suspense for asynchronous components
Use <script setup> syntax for concise component definitions
Prefer 'lucide:' icon family as the primary choice for Iconify icons
Import Icon component from '@iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Files:
src/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*.{vue,ts,tsx}: All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Use the dynamic locale.value property to switch languages at runtime
Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Files:
src/renderer/src/components/NewThread.vue
src/renderer/**/*.{vue,js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Renderer process code should be placed in
src/renderer(Vue 3 application)
Files:
src/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability in Vue.js applications
Implement proper state management with Pinia in Vue.js applications
Utilize Vue Router for navigation and route management in Vue.js applications
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/components/NewThread.vue
src/renderer/src/**/*.vue
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
Use scoped styles to prevent CSS conflicts between Vue components
Files:
src/renderer/src/components/NewThread.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Write concise, technical TypeScript code with accurate examples
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid enums; use const objects instead
Use arrow functions for methods and computed properties
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statementsVue 3 app code in
src/renderer/srcshould be organized intocomponents/,stores/,views/,i18n/,lib/directories with shell UI insrc/renderer/shell/
Files:
src/renderer/src/components/NewThread.vue
src/renderer/**
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use lowercase with dashes for directories (e.g., components/auth-wizard)
Files:
src/renderer/src/components/NewThread.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching
Leverage ref, reactive, and computed for reactive state management
Use provide/inject for dependency injection when appropriate
Use Iconify/Vue for icon implementation
Files:
src/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use TypeScript with Vue 3 Composition API for the renderer application
All user-facing strings must use vue-i18n keys insrc/renderer/src/i18n
Files:
src/renderer/src/components/NewThread.vue
src/renderer/src/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g.,ChatInput.vue)
Files:
src/renderer/src/components/NewThread.vue
🧠 Learnings (40)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Implement error retry mechanisms for transient failures in TypeScript
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Error handling: use `error` event uniformly to carry error messages, avoid mixing errors into other event fields
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.tssrc/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Provide user-friendly error messages for user-facing errors in TypeScript components
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Provide meaningful error messages when catching errors
Applied to files:
src/main/presenter/llmProviderPresenter/managers/errorClassification.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/index.tssrc/renderer/src/components/NewThread.vuesrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Tool call events: strictly follow sequence `tool_call_start → tool_call_chunk* → tool_call_end`, ensure `tool_call_id` is required and stable
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `stop` events by checking `stop_reason`: if `'tool_use'`, add the buffered assistant message and prepare for the next loop iteration; otherwise, add the final assistant message and exit the loop
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations (`src/main/presenter/llmProviderPresenter/providers/*.ts`), the `coreStream(messages, modelId, temperature, maxTokens)` method should perform a *single-pass* streaming API request for each conversation round without containing multi-turn tool call loop logic
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/**/*.ts : Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/index.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/**/*.ts : Use EventBus from `src/main/eventbus.ts` for main-to-renderer communication, broadcasting events via `mainWindow.webContents.send()`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/index.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Follow the Presenter Pattern architecture where each functional domain has a dedicated Presenter class in `src/main/presenter/`
Applied to files:
src/main/presenter/index.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `reasoning`, `text`, `image_data`, and `usage` events by processing and forwarding them through `STREAM_EVENTS.RESPONSE` events to the frontend
Applied to files:
src/main/presenter/index.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Leverage ref, reactive, and computed for reactive state management
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Avoid logging sensitive information (passwords, tokens, PII) in logs
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-06-21T15:49:17.044Z
Learnt from: neoragex2002
Repo: ThinkInAIXYZ/deepchat PR: 550
File: src/renderer/src/stores/chat.ts:1011-1035
Timestamp: 2025-06-21T15:49:17.044Z
Learning: In src/renderer/src/stores/chat.ts, the user prefers to keep both `text` and `content` properties in the `handleMeetingInstruction` function's `sendMessage` call, even though they are redundant, rather than removing the `content` property.
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/renderer/src/components/**/*.vue : Vue component files must use PascalCase naming (e.g., `ChatInput.vue`)
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,tsx,vue} : Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use camelCase for composables (e.g., useAuthState.ts)
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Use Iconify/Vue for icon implementation
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Import Icon component from 'iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Prefer 'lucide:' icon family as the primary choice for Iconify icons
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/configPresenter/**/*.ts : Store and retrieve custom prompts via `configPresenter.getCustomPrompts()` for config-based data source management
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/stores/*.ts : Use Pinia for state management
Applied to files:
src/renderer/src/components/NewThread.vue
📚 Learning: 2025-11-25T05:27:20.067Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/pinia-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:20.067Z
Learning: Applies to src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx} : Keep Pinia stores focused on global state, not component-specific data
Applied to files:
src/renderer/src/components/NewThread.vue
🧬 Code graph analysis (5)
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts (2)
src/shared/types/presenters/legacy.presenters.d.ts (3)
MCPToolDefinition(1476-1492)MCPToolCall(1494-1506)MCPToolResponse(1508-1537)src/main/presenter/llmProviderPresenter/managers/errorClassification.ts (1)
isNonRetryableError(23-102)
src/main/presenter/browser/YoBrowserPresenter.ts (4)
src/main/presenter/browser/BrowserTab.ts (2)
contents(35-37)BrowserTab(7-642)src/main/eventbus.ts (1)
eventBus(151-151)src/main/events.ts (1)
YO_BROWSER_EVENTS(190-198)src/renderer/src/events.ts (1)
YO_BROWSER_EVENTS(154-162)
src/main/presenter/index.ts (2)
src/shared/types/presenters/workspace.d.ts (1)
IWorkspacePresenter(75-140)src/shared/types/presenters/tool.presenter.d.ts (1)
IToolPresenter(12-29)
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (6)
src/main/presenter/toolPresenter/index.ts (1)
ToolPresenter(33-145)src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts (1)
ToolCallProcessor(40-443)src/main/presenter/index.ts (1)
presenter(265-265)test/mocks/electron.ts (1)
app(2-10)src/main/events.ts (1)
WORKSPACE_EVENTS(248-252)src/renderer/src/events.ts (1)
WORKSPACE_EVENTS(189-193)
src/main/presenter/browser/tools/navigate.ts (1)
src/main/presenter/browser/tools/types.ts (1)
ToolResult(6-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (28)
src/main/presenter/browser/YoBrowserPresenter.ts (5)
33-33: LGTM: State tracking flag added.The
explicitlyOpenedflag appropriately tracks user-initiated browser window visibility, enabling conditional logic in show/hide flows.
46-62: LGTM: Window creation options properly threaded.The optional
showOnReadyparameter is correctly defaulted and passed through to the window presenter, maintaining proper separation of concerns.
68-81: LGTM: Show flow properly manages initial state.The method correctly:
- Marks the browser as explicitly opened
- Ensures window creation with immediate visibility
- Creates an initial tab only when needed (no existing tabs)
375-380: LGTM: Window close properly resets state.The
explicitlyOpenedflag is correctly reset when the window closes, maintaining state consistency.
536-539: LGTM: Tab update emission properly centralized.The new
emitTabUpdatedmethod follows the established pattern for event emission in this class and correctly broadcasts tab state changes to all renderer windows.Based on learnings: Uses EventBus for main-to-renderer communication as per the Presenter pattern.
src/main/presenter/browser/tools/navigate.ts (1)
109-141: Excellent event listener management and type usage.The event listener cleanup pattern (lines 118-122) is well-implemented:
- Proper cleanup function that removes all listeners and clears timeout
- Called in both success and failure paths
- Prevents memory leaks
The ToolResult type usage with
as constassertions correctly aligns with the new standardized tool result patterns introduced in this PR.Also applies to: 158-166, 182-190
src/renderer/src/components/NewThread.vue (4)
113-113: LGTM: New store and composable imports.The workspace store and chat mode composable imports follow project conventions and support the new agent mode features.
Also applies to: 125-125, 129-129, 138-138
352-391: LGTM: Chat mode watcher for auto model switching.The watcher correctly handles mode-to-model synchronization with proper guards for initialization state. The conditional model switching logic is sound, and the preference update is appropriately fire-and-forget for UX.
534-536: LGTM: Workspace refresh for agent modes.Refreshing the file tree after thread creation in agent modes ensures the workspace stays synchronized with file operations performed by agents. The await ensures proper sequencing before sending the message.
511-532: Thread creation payload uses proper types;as anycast can be removed.The
chatModeandagentWorkspacePathproperties are already properly defined in theCONVERSATION_SETTINGStype as optional fields. Theas anycast is unnecessary and bypasses type safety. Remove the cast to leverage TypeScript's type checking for this object.Likely an incorrect or invalid review comment.
src/main/presenter/index.ts (4)
27-28: LGTM! Import declarations follow established patterns.The new presenter imports are properly structured, with interface types imported from
@shared/presenterand concrete implementations imported from their respective modules. This maintains consistency with the existing codebase architecture.Also applies to: 49-50
89-90: LGTM! Public field declarations properly typed.The new presenter fields follow the camelCase naming convention and are correctly typed with their respective interfaces, maintaining consistency with the existing presenter pattern.
169-176: LGTM! Excellent defensive programming with initialization guard.The idempotent initialization guard using
initCalledis a solid improvement that prevents duplicate initialization ifREADY_TO_SHOWfires multiple times. The closure correctly maintains state sincesetupEventBus()is called once from the constructor.
135-146: No cleanup required for workspacePresenter or toolPresenter.These presenters hold only in-memory data structures (Sets and Maps) with no external resources. Unlike other presenters that manage database connections, event listeners, or native resources, workspacePresenter and toolPresenter don't require explicit cleanup in the
destroy()method. Automatic garbage collection handles cleanup when the application terminates.Likely an incorrect or invalid review comment.
src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts (5)
9-9: LGTM! Clean interface additions.The
onToolCallFinishedcallback andconversationIdcontext field are well-typed and properly integrated into the existing interfaces.Also applies to: 14-20, 32-32
104-117: LGTM! Defensive callback wrapper.The
notifyToolCallFinishedhelper properly guards against missing callbacks and handler errors, ensuring that callback failures don't disrupt the tool execution flow.
145-171: LGTM! Permission notification correctly placed.The
notifyToolCallFinished('permission')call is properly positioned before yielding the permission-required event and breaking the loop.
173-175: LGTM! Defensive abort check after async callback.Adding an abort check after the success notification is good defensive programming, ensuring that if the stream is aborted during the callback, the processor stops promptly.
311-316: LGTM! Consistent content stringification.Using
stringifyToolContentconsistently for both native and legacy function call paths improves maintainability and ensures uniform content formatting.src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (9)
1-1: LGTM! Appropriate imports and field for new functionality.The new imports support workspace management, ToolPresenter integration, and file system operations needed for agent workspace paths.
Also applies to: 4-4, 9-12, 24-24
29-53: LGTM! Clean callback refactoring.The callback properly extracts modelId, resolves workspace context, and delegates to ToolPresenter. The duplication noted in previous reviews has been resolved.
55-62: LGTM! Proper tool call delegation and workspace refresh.The callback correctly delegates to ToolPresenter and triggers workspace file change notifications only for agent-filesystem tools.
136-177: LGTM! Well-structured workspace context resolution.The method properly handles different chat modes and resolves workspace paths accordingly. The logic correctly distinguishes between ACP agent mode (using
acpWorkdirMap[modelId]) and regular agent mode.
179-184: LGTM! Clean workspace change notification.The method properly guards against missing conversationId and broadcasts file change events using the EventBus pattern.
303-315: LGTM! Proper workspace context integration.The workspace context resolution and tool definition retrieval are correctly integrated into the stream completion flow.
629-630: LGTM! Proper conversationId propagation.Passing
conversationIdto the ToolCallProcessor enables workspace-aware tool execution and proper notification handling.
643-645: LGTM! Defensive abort check after async tool processing.Adding an abort check after tool processing completes is good defensive programming, ensuring the loop stops promptly if aborted during tool execution.
709-711: LGTM! Workspace refresh for ACP provider.Triggering workspace file change notifications in the finally block ensures the renderer stays synchronized with filesystem changes made by ACP tools.
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (1)
607-613: Avoidas anytype casting.The
as anycast at line 612 bypasses TypeScript's type safety when addingreasoning_contentto the assistant message. Consider extending theChatMessagetype to include an optionalreasoning_contentfield, or create a specific message type for reasoning-capable models.🔎 Type-safe alternatives
Option 1: Extend the ChatMessage interface (in shared types)
interface ChatMessage { role: string content: string reasoning_content?: string // Add as optional field }Option 2: Use type assertion to more specific type
interface ReasoningChatMessage extends ChatMessage { reasoning_content: string } // Then use: if ( this.requiresReasoningField(modelId) && currentToolCalls.length > 0 && currentReasoning ) { (assistantMessage as ReasoningChatMessage).reasoning_content = currentReasoning }
🧹 Nitpick comments (2)
src/main/presenter/browser/tools/navigate.ts (1)
96-98: Consider event-based synchronization instead of arbitrary delay.The 100ms delay is a timing assumption that may not hold under all conditions (slow systems, heavy load). While the subsequent event-based waiting (lines 109-141) is good, consider whether you can rely entirely on event-driven synchronization or increase the delay if testing shows it's insufficient.
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (1)
303-315: Consider caching workspace context per iteration.The workspace context is resolved twice per loop iteration: once here for the LLM provider call (line 304) and once in the
getAllToolDefinitionscallback (line 43) for tool execution. While this ensures fresh context at each stage, caching the resolved context per iteration could reduce overhead without sacrificing correctness in most scenarios.💡 Potential optimization approach
Cache the workspace context at the start of each loop iteration and pass it through to both the LLM call and the ToolCallProcessor callback:
// At the start of each iteration (around line 303) const workspaceContext = await this.resolveWorkspaceContext(conversationId, modelId) // Use cached context for LLM call const toolDefs = await this.getToolPresenter().getAllToolDefinitions({ enabledMcpTools, ...workspaceContext, supportsVision: this.currentSupportsVision }) // Pass cached context to ToolCallProcessor or modify callback to accept pre-resolved contextThis would require updating the ToolCallProcessor callback signature to optionally accept pre-resolved context.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/agent/agentToolManager.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/presenter/llmProviderPresenter/agent/agentToolManager.ts
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/browser/tools/navigate.tssrc/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
src/main/presenter/llmProviderPresenter/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)
Define the standardized
LLMCoreStreamEventinterface with fields:type(text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data),content(for text),reasoning_content(for reasoning),tool_call_id,tool_call_name,tool_call_arguments_chunk(for streaming),tool_call_arguments_complete(for complete arguments),error_message,usageobject with token counts,stop_reason(tool_use | max_tokens | stop_sequence | error | complete), andimage_dataobject with Base64-encoded data and mimeType
Files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Applied to files:
src/main/presenter/browser/tools/navigate.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Always use try-catch to handle possible errors in TypeScript code
Applied to files:
src/main/presenter/browser/tools/navigate.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations (`src/main/presenter/llmProviderPresenter/providers/*.ts`), the `coreStream(messages, modelId, temperature, maxTokens)` method should perform a *single-pass* streaming API request for each conversation round without containing multi-turn tool call loop logic
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `stop` events by checking `stop_reason`: if `'tool_use'`, add the buffered assistant message and prepare for the next loop iteration; otherwise, add the final assistant message and exit the loop
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:26.656Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T05:27:26.656Z
Learning: Applies to src/main/**/*.{js,ts} : Main process code for Electron should be placed in `src/main`
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `reasoning`, `text`, `image_data`, and `usage` events by processing and forwarding them through `STREAM_EVENTS.RESPONSE` events to the frontend
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Tool call events: strictly follow sequence `tool_call_start → tool_call_chunk* → tool_call_end`, ensure `tool_call_id` is required and stable
Applied to files:
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts
🧬 Code graph analysis (2)
src/main/presenter/browser/tools/navigate.ts (1)
src/main/presenter/browser/tools/types.ts (1)
ToolResult(6-6)
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (4)
src/main/presenter/toolPresenter/index.ts (1)
ToolPresenter(33-145)src/main/presenter/llmProviderPresenter/managers/toolCallProcessor.ts (1)
ToolCallProcessor(40-443)src/shared/types/presenters/legacy.presenters.d.ts (1)
MCPToolCall(1494-1506)src/main/events.ts (1)
WORKSPACE_EVENTS(248-252)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (11)
src/main/presenter/browser/tools/navigate.ts (3)
99-156: Well-implemented navigation completion handling.The event-based waiting with proper cleanup, timeout, and error handling (lines 109-141) is robust. The subsequent URL verification (lines 143-148, 149-156) correctly handles redirects and ensures the final URL matches the target, which is good defensive programming for browser automation.
167-180: Previous error suppression issue resolved.The catch block now properly logs navigation failures and returns an error result with
isError: true, addressing the concern raised in the previous review. The error message is correctly extracted and included in the response, ensuring callers are aware when navigation fails.
2-2: Good type safety improvements.The explicit
ToolResulttype annotations andas constassertions throughout ensure proper type checking and align with the project's strict TypeScript guidelines.Also applies to: 158-215
src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts (8)
1-26: LGTM! Clean imports and class structure.The imports appropriately bring in ToolPresenter, filesystem APIs, and Electron app module for workspace management. The lazy initialization pattern for
toolPresentercorrectly accommodates the Presenter initialization order dependency.
70-85: LGTM! Appropriate lazy initialization with dependency checks.The lazy initialization pattern correctly ensures
mcpPresenterandyoBrowserPresenterare available before creatingToolPresenter. The explicit error with a descriptive message serves as a valuable safety check given the Presenter initialization order.
87-114: LGTM! Proper async filesystem operations.The method correctly uses
fs.promises.mkdirfor non-blocking directory creation, addressing the previous review concern. Error handling is defensive with appropriate fallbacks to system temp paths.Based on past review comments requesting async operations instead of blocking
fs.mkdirSync.
116-134: LGTM! Properly handles async workspace path resolution.The method correctly awaits
getDefaultAgentWorkspacePathand handles the Promise return type. Error handling around persistence is appropriate with warning logs, ensuring the method returns a valid path even if the database update fails.
142-177: LGTM! Well-structured workspace context resolution.The helper method successfully consolidates the workspace path resolution logic that was previously duplicated, addressing the earlier review concern. The three-mode handling (chat/agent/acp agent) is clear, with proper ACP modelId-based resolution and fallback error handling.
Based on past review comments requesting extraction of duplicated workspace resolution logic.
179-184: LGTM! Proper EventBus usage for workspace notifications.The helper correctly uses the
EventBuspattern for main-to-renderer communication, broadcasting workspace file changes to all windows with the appropriate conversation context.As per coding guidelines requiring EventBus pattern for inter-process communication.
619-646: LGTM! Proper tool processor integration with workspace context.The addition of
conversationIdto the tool execution context (line 630) correctly enables workspace-specific notifications via theonToolCallFinishedcallback. The generator pattern properly forwards events from the processor.
709-711: LGTM! Appropriate ACP workspace notification.The final workspace notification for the ACP provider complements the per-tool notifications for
agent-filesystemtools (line 60). This dual notification strategy correctly handles both the ACP-managed workspace and the agent filesystem tooling.
| // Fallback if getTab fails | ||
| const result: ToolResult = { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| type: 'text' as const, | ||
| text: `Created new tab and navigated to ${parsed.url}\nTitle: ${newTab.title || 'unknown'}` | ||
| } | ||
| ] | ||
| } | ||
| return result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fallback returns success despite verification failure.
When getTab(newTab.id) fails (line 102), this fallback returns a success result even though the BrowserTab couldn't be retrieved. This might mask initialization issues. Consider returning an error result or at minimum including a note in the text that the tab was created but couldn't be verified.
🔎 Suggested improvement
// Fallback if getTab fails
const result: ToolResult = {
content: [
{
type: 'text' as const,
- text: `Created new tab and navigated to ${parsed.url}\nTitle: ${newTab.title || 'unknown'}`
+ text: `Created new tab ${newTab.id} and initiated navigation to ${parsed.url}\nWarning: Could not verify tab initialization\nTitle: ${newTab.title || 'unknown'}`
}
- ]
+ ],
+ isError: false // Not a hard error, but caller should be aware
}
return resultAlternatively, consider whether this should be isError: true if tab verification is critical.
🤖 Prompt for AI Agents
In src/main/presenter/browser/tools/navigate.ts around lines 182 to 191, the
fallback currently returns a successful ToolResult after getTab(newTab.id)
fails, which masks verification failures; modify the fallback to return a
failure-style ToolResult (set isError: true) or at minimum include an explicit
notice in the content text that the tab was created but could not be verified,
and append the getTab error or missing-tab details to the log/text so callers
can detect and surface the initialization failure.
| } catch { | ||
| // Ignore errors, modelId will be undefined | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider logging a warning for ignored errors.
Silently ignoring all errors when fetching the conversation might hide legitimate issues such as database connection failures or permission problems. While the code defensively continues with undefined modelId, visibility into these failures would aid debugging.
🔎 Suggested improvement
- } catch {
- // Ignore errors, modelId will be undefined
+ } catch (error) {
+ console.warn('[AgentLoopHandler] Failed to fetch modelId from conversation:', error)
+ // Continue with undefined modelId
}🤖 Prompt for AI Agents
In src/main/presenter/llmProviderPresenter/managers/agentLoopHandler.ts around
lines 38-40, the catch block currently swallows all errors when fetching the
conversation; update it to catch the error into a variable and emit a
warning-level log including the error and a short context message while
preserving the existing behavior of continuing with an undefined modelId. Use
the module's existing logger (e.g., logger or processLogger) to log the warning;
if no logger is in scope, import or inject the appropriate logger and log the
error rather than silently ignoring it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/windowPresenter/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/presenter/windowPresenter/index.ts
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-06-21T15:48:29.950Z
Learnt from: neoragex2002
Repo: ThinkInAIXYZ/deepchat PR: 550
File: src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts:250-252
Timestamp: 2025-06-21T15:48:29.950Z
Learning: In the meeting server implementation (src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts), when multiple tabs have the same title, the user prefers to let the code silently select the first match without adding warnings or additional ambiguity handling.
Applied to files:
src/main/presenter/tabPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/**/*.ts : Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/**/*.ts : Use EventBus from `src/main/eventbus.ts` for main-to-renderer communication, broadcasting events via `mainWindow.webContents.send()`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/shared/**/*.d.ts : Define type definitions in shared/*.d.ts files for objects exposed by the main process to the renderer process
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/**/*.ts : Use EventBus for inter-process communication events
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:27:26.656Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T05:27:26.656Z
Learning: Applies to src/shared/**/*.{js,ts} : Shared type definitions and utilities between main and renderer processes should be placed in `src/shared`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,tsx,vue} : Write concise, technical TypeScript code with accurate examples
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (8)
src/main/presenter/tabPresenter.ts (1)
746-749: LGTM: Conditional focus logic properly prevents hidden browser windows from stealing focus.The logic correctly focuses tabs when the window is visible or when it's a chat window, while avoiding focus on hidden browser windows. This aligns with the mode-aware workspace handling introduced in this PR.
src/main/presenter/browser/YoBrowserPresenter.ts (7)
1-2: LGTM: Imports support new window positioning logic.The
screenAPI andRectangletype are correctly imported for the new positioning calculations.
34-34: LGTM: Tracks explicit user-initiated window visibility.The
explicitlyOpenedflag properly distinguishes explicit show() calls from automatic window creation, and is correctly reset in the window lifecycle.
47-69: LGTM: ensureWindow signature extended for positioning control.The method signature is backward compatible, and positioning options are properly passed through to
createShellWindow. The defaultshowOnReady: falsealigns with lazy initialization.
424-476: LGTM: Window positioning logic correctly handles multiple scenarios.The positioning helpers properly:
- Find reference windows (focused or fallback)
- Calculate non-overlapping positions with fallback strategies
- Clamp coordinates to display work area boundaries
The logic is complex but well-structured with clear fallback paths.
478-483: LGTM: Properly resets explicit-open state on window close.The
explicitlyOpenedflag is correctly reset in the window cleanup lifecycle.
494-512: LGTM: Tab update emissions properly track title and favicon changes.The addition of
emitTabUpdatedprovides proper state change notifications, and the favicon change detection prevents redundant emissions. TheupdatedAttimestamp is correctly maintained.Also applies to: 639-642
352-362: The text aggregation logic incallTool()is sound. Tool implementations are designed to always return at least one text chunk, including explicit messages like "(no text found)" or "(no content found)" when appropriate. Returning an empty string on success is not a concern because tools never return empty content arrays.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/main/presenter/browser/YoBrowserPresenter.ts (1)
100-119: Critical: Missing try-catch around window operations (previously flagged).This issue was already flagged in a previous review but remains unresolved. Lines 102-103 call
window.getBounds()andwindow.setPosition()without try-catch protection, and lines 116-117 callthis.windowPresenter.show()andthis.emitVisibility()within the reveal callback without error handling. Per coding guidelines, all window method calls must be wrapped in try-catch blocks, asisDestroyed()checks are not reliable safeguards against "Object has been destroyed" errors.🔎 Proposed fix
if (existingWindow) { - const currentReferenceBounds = this.getReferenceBounds(window.id) - const position = this.calculateWindowPosition(window.getBounds(), currentReferenceBounds) - window.setPosition(position.x, position.y) + try { + const currentReferenceBounds = this.getReferenceBounds(window.id) + const position = this.calculateWindowPosition(window.getBounds(), currentReferenceBounds) + window.setPosition(position.x, position.y) + } catch (error) { + logger.warn('Failed to reposition window', error) + } } // For existing windows, directly show them (they're already ready) // For new windows, wait for ready-to-show event if (existingWindow) { // Window already exists, just show it directly - this.windowPresenter.show(window.id) - this.emitVisibility(true) + try { + this.windowPresenter.show(window.id) + this.emitVisibility(true) + } catch (error) { + logger.warn('Failed to show window', error) + } } else { // New window, wait for ready-to-show const reveal = () => { if (!window.isDestroyed()) { - this.windowPresenter.show(window.id) - this.emitVisibility(true) + try { + this.windowPresenter.show(window.id) + this.emitVisibility(true) + } catch (error) { + logger.warn('Failed to show window in reveal callback', error) + } } }
🧹 Nitpick comments (1)
src/main/presenter/browser/YoBrowserPresenter.ts (1)
350-360: Consider more descriptive error message.The error message on Line 357 could include the tool name to aid debugging when multiple tools fail.
🔎 Proposed enhancement
if (result.isError) { - throw new Error(textContent || 'Tool execution failed') + throw new Error(textContent || `Tool '${toolName}' execution failed`) }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/windowPresenter/index.tssrc/renderer/src/stores/chat.tssrc/shared/types/presenters/legacy.presenters.d.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/main/presenter/tabPresenter.ts
- src/renderer/src/stores/chat.ts
- src/main/presenter/windowPresenter/index.ts
- src/shared/types/presenters/legacy.presenters.d.ts
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/**/*.ts : Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Always use try-catch to handle possible errors in TypeScript code
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx}x : Use error boundaries to catch rendering errors in React components
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Implement error retry mechanisms for transient failures in TypeScript
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Implement proper error handling and logging for debugging in Electron applications
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/**/*.ts : Use EventBus from `src/main/eventbus.ts` for main-to-renderer communication, broadcasting events via `mainWindow.webContents.send()`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/shared/**/*.d.ts : Define type definitions in shared/*.d.ts files for objects exposed by the main process to the renderer process
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/**/*.ts : Use EventBus for inter-process communication events
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:27:26.656Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T05:27:26.656Z
Learning: Applies to src/shared/**/*.{js,ts} : Shared type definitions and utilities between main and renderer processes should be placed in `src/shared`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,tsx,vue} : Write concise, technical TypeScript code with accurate examples
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
🧬 Code graph analysis (1)
src/main/presenter/browser/YoBrowserPresenter.ts (3)
test/mocks/electron.ts (1)
screen(57-60)src/main/eventbus.ts (1)
eventBus(151-151)src/main/events.ts (1)
YO_BROWSER_EVENTS(190-198)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (1)
src/main/presenter/browser/YoBrowserPresenter.ts (1)
510-528: LGTM: Tab update event emission is well implemented.The new
emitTabUpdated()method and its integration withpage-title-updatedandpage-favicon-updatedevent listeners properly maintain tab state and emit the newTAB_UPDATEDevent. The favicon check on Line 522 prevents unnecessary updates when the favicon hasn't changed.Also applies to: 655-659
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
src/main/presenter/browser/YoBrowserPresenter.ts (3)
459-468: Add try-catch aroundgetBounds()calls.Lines 462 and 467 call
getBounds()without error handling. Per coding guidelines, window method calls should be wrapped in try-catch blocks to prevent uncaught exceptions when windows are destroyed.
470-530: Replace Chinese comments with English.Multiple Chinese comments in this method violate coding guidelines which require English for logs and comments.
69-127: Add try-catch around window method calls in show().Lines 102-103 call
window.getBounds()andwindow.setPosition()without error handling. Per coding guidelines, all window method calls should be wrapped in try-catch to handle cases where the window may be destroyed.
🧹 Nitpick comments (1)
src/main/presenter/browser/BrowserTab.ts (1)
631-636: Replace Chinese comment with English.Per coding guidelines, all comments must be in English. The safety check logic is correct and prevents CDP session binding on internal local pages.
🔎 Proposed fix
- // 安全检查:只有加载外部网页的 browser tab 才允许绑定 CDP + // Safety check: only allow CDP binding for browser tabs loading external web pages const currentUrl = this.webContents.getURL() if (currentUrl.startsWith('local://')) { throw new Error('CDP is not allowed for local:// URLs') }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/windowPresenter/index.tssrc/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.tssrc/shared/types/presenters/legacy.presenters.d.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/shared/types/presenters/legacy.presenters.d.ts
🧰 Additional context used
📓 Path-based instructions (27)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/windowPresenter/index.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/windowPresenter/index.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/windowPresenter/index.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.tssrc/main/presenter/windowPresenter/index.ts
**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.vue: Use Vue 3 Composition API for all components instead of Options API
Use Tailwind CSS with scoped styles for component styling
Files:
src/renderer/shell/components/AppBar.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/**/*.vue: All user-facing strings must use i18n keys via vue-i18n for internationalization
Ensure proper error handling and loading states in all UI components
Implement responsive design using Tailwind CSS utilities for all UI components
src/renderer/**/*.vue: Use composition API and declarative programming patterns; avoid options API
Structure files: exported component, composables, helpers, static content, types
Use PascalCase for component names (e.g., AuthWizard.vue)
Use Vue 3 with TypeScript, leveraging defineComponent and PropType
Use template syntax for declarative rendering
Use Shadcn Vue, Radix Vue, and Tailwind for components and styling
Implement responsive design with Tailwind CSS; use a mobile-first approach
Use Suspense for asynchronous components
Use <script setup> syntax for concise component definitions
Prefer 'lucide:' icon family as the primary choice for Iconify icons
Import Icon component from '@iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Files:
src/renderer/shell/components/AppBar.vue
src/renderer/**/*.{vue,js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Renderer process code should be placed in
src/renderer(Vue 3 application)
Files:
src/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.ts
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Write concise, technical TypeScript code with accurate examples
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid enums; use const objects instead
Use arrow functions for methods and computed properties
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statementsVue 3 app code in
src/renderer/srcshould be organized intocomponents/,stores/,views/,i18n/,lib/directories with shell UI insrc/renderer/shell/
Files:
src/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.ts
src/renderer/**
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use lowercase with dashes for directories (e.g., components/auth-wizard)
Files:
src/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.ts
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching
Leverage ref, reactive, and computed for reactive state management
Use provide/inject for dependency injection when appropriate
Use Iconify/Vue for icon implementation
Files:
src/renderer/shell/components/AppBar.vuesrc/renderer/src/stores/yoBrowser.ts
src/renderer/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use the
usePresenter.tscomposable for renderer-to-main IPC communication to call presenter methods directly
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*.{vue,ts,tsx}: All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Use the dynamic locale.value property to switch languages at runtime
Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/pinia-best-practices.mdc)
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}: Use modules to organize related state and actions in Pinia stores
Implement proper state persistence for maintaining data across sessions in Pinia stores
Use getters for computed state properties in Pinia stores
Utilize actions for side effects and asynchronous operations in Pinia stores
Keep Pinia stores focused on global state, not component-specific data
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability in Vue.js applications
Implement proper state management with Pinia in Vue.js applications
Utilize Vue Router for navigation and route management in Vue.js applications
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use TypeScript for all code; prefer types over interfaces
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/**/stores/*.ts
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use Pinia for state management
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use TypeScript with Vue 3 Composition API for the renderer application
All user-facing strings must use vue-i18n keys insrc/renderer/src/i18n
Files:
src/renderer/src/stores/yoBrowser.ts
src/renderer/src/stores/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use Pinia for state management
Files:
src/renderer/src/stores/yoBrowser.ts
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/preload/**/*.ts : Secure IPC bridge should be implemented in `src/preload/` with contextIsolation enabled
Applied to files:
src/main/presenter/browser/BrowserTab.tssrc/main/presenter/tabPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/renderer/src/stores/yoBrowser.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/windowPresenter/index.ts
📚 Learning: 2025-06-21T15:48:29.950Z
Learnt from: neoragex2002
Repo: ThinkInAIXYZ/deepchat PR: 550
File: src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts:250-252
Timestamp: 2025-06-21T15:48:29.950Z
Learning: In the meeting server implementation (src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts), when multiple tabs have the same title, the user prefers to let the code silently select the first match without adding warnings or additional ambiguity handling.
Applied to files:
src/main/presenter/tabPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Applied to files:
src/main/presenter/tabPresenter.tssrc/main/presenter/browser/YoBrowserPresenter.tssrc/main/presenter/windowPresenter/index.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Maintain context isolation with preload scripts for secure IPC between main and renderer processes
Applied to files:
src/main/presenter/tabPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/**/*.ts : Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Always use try-catch to handle possible errors in TypeScript code
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx}x : Use error boundaries to catch rendering errors in React components
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Implement error retry mechanisms for transient failures in TypeScript
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Implement proper error handling and logging for debugging in Electron applications
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to **/*.{ts,tsx,js,jsx,vue} : Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:15.929Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/development-setup.mdc:0-0
Timestamp: 2025-11-25T05:26:15.929Z
Learning: Applies to **/*.{js,ts,jsx,tsx,mjs,cjs} : Write logs and comments in English
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,tsx,vue} : Write concise, technical TypeScript code with accurate examples
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/**/*.ts : Use EventBus from `src/main/eventbus.ts` for main-to-renderer communication, broadcasting events via `mainWindow.webContents.send()`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/shared/**/*.d.ts : Define type definitions in shared/*.d.ts files for objects exposed by the main process to the renderer process
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/**/*.ts : Use EventBus for inter-process communication events
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:27:26.656Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T05:27:26.656Z
Learning: Applies to src/shared/**/*.{js,ts} : Shared type definitions and utilities between main and renderer processes should be placed in `src/shared`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
🧬 Code graph analysis (4)
src/main/presenter/tabPresenter.ts (4)
test/mocks/electron-toolkit-utils.ts (1)
is(1-3)src/main/events.ts (1)
WINDOW_EVENTS(87-106)src/renderer/src/events.ts (1)
WINDOW_EVENTS(62-67)src/main/presenter/index.ts (1)
presenter(265-265)
src/main/presenter/browser/YoBrowserPresenter.ts (3)
test/mocks/electron.ts (1)
screen(57-60)src/main/eventbus.ts (1)
eventBus(151-151)src/main/events.ts (1)
YO_BROWSER_EVENTS(190-198)
src/renderer/src/stores/yoBrowser.ts (4)
src/shared/types/browser.ts (1)
BrowserTabInfo(9-18)src/main/events.ts (1)
YO_BROWSER_EVENTS(190-198)src/renderer/src/events.ts (1)
YO_BROWSER_EVENTS(154-162)src/main/presenter/browser/YoBrowserPresenter.ts (1)
handleTabClosed(630-635)
src/main/presenter/windowPresenter/index.ts (1)
src/main/presenter/tabPresenter.ts (1)
TabPresenter(16-1140)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (17)
src/main/presenter/windowPresenter/index.ts (4)
390-416: LGTM!The
show()method signature update withshouldFocusparameter maintains backward compatibility (defaults totrue) and provides proper control over window focus behavior. This is essential for preventing focus stealing when browser windows are created programmatically by agent tools.
684-692: LGTM!Dynamic default width based on window type (600px for browser, 800px for chat) is appropriate. Browser windows are typically sidebars, and the narrower default width makes sense for this use case.
767-777: LGTM!The conditional auto-show/focus logic for browser windows is a key part of the agent mode behavior. Browser windows created via tool calls should not steal focus from the chat window, which this change correctly implements.
1048-1048: LGTM!Removing automatic DevTools opening in development mode is reasonable. DevTools can still be opened manually when needed.
src/main/presenter/browser/YoBrowserPresenter.ts (2)
547-565: LGTM!The enhanced tab listeners for title and favicon updates now properly set
updatedAtand emitTAB_UPDATEDevents, enabling real-time UI updates in the renderer.
692-695: LGTM!The new
emitTabUpdatedmethod provides a centralized way to notify renderers of tab state changes, complementing the existingemitTabCreated,emitTabClosed, etc. methods.src/main/presenter/tabPresenter.ts (5)
51-53: LGTM!Making
getWindowTypepublic is appropriate as other presenters (e.g.,YoBrowserPresenter) need to query window types for conditional behavior.
187-195: LGTM!Not injecting the preload script for browser windows is a good security measure. Browser windows load external content, so they should not have access to the IPC bridge that local app pages use.
219-223: LGTM!Disabling automatic DevTools for browser windows in development mode is appropriate. DevTools can still be opened manually when needed for debugging.
664-682: LGTM!The conditional
focusActiveTabcall ensures that browser windows created via tool calls don't steal focus from the chat window. This is essential for the agent mode UX where the user should remain in the chat context.
754-770: LGTM!The focus logic in
bringViewToFrontcorrectly differentiates between browser and chat windows:
- Browser windows only focus if already visible and focused (prevents focus stealing)
- Chat windows focus when visible (normal behavior)
This is a key enabler for the agent mode workflow.
src/renderer/shell/components/AppBar.vue (1)
697-703: LGTM!The explicit
show(true)call aligns with the updatedYoBrowserPresenter.show(shouldFocus)signature. While the default istrue, making the intent explicit improves code clarity.src/renderer/src/stores/yoBrowser.ts (5)
73-78: LGTM!The
handleTabUpdatedhandler correctly upserts the updated tab into the store and synchronizes theactiveTabIdstate. This follows the same pattern as the existinghandleTabCreatedhandler.
88-91: LGTM!The
show()method now explicitly passestruetoyoBrowserPresenter.show(), aligning with the updated presenter signature.
104-108: LGTM!The new
openTabmethod provides a clean API for activating a specific tab and ensuring the browser window is visible. The sequence (activate → show → loadState) is correct.
117-117: LGTM!Proper registration of the
TAB_UPDATEDevent handler inonMounted.
138-138: LGTM!Proper cleanup of the
TAB_UPDATEDevent listener inonBeforeUnmount, maintaining symmetry with the registration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
src/main/presenter/browser/YoBrowserPresenter.ts (3)
98-126: Add try-catch around window method calls in theshow()method.Lines 102-103 call
getBounds()andsetPosition()without error handling. Per coding guidelines, all TypeScript code that can throw must be wrapped in try-catch. Electron'sisDestroyed()check alone is insufficient as race conditions can still cause "Object has been destroyed" errors.🔎 Proposed fix
if (existingWindow) { - const currentReferenceBounds = this.getReferenceBounds(window.id) - const position = this.calculateWindowPosition(window.getBounds(), currentReferenceBounds) - window.setPosition(position.x, position.y) + try { + const currentReferenceBounds = this.getReferenceBounds(window.id) + const position = this.calculateWindowPosition(window.getBounds(), currentReferenceBounds) + window.setPosition(position.x, position.y) + } catch (error) { + console.warn('[YoBrowser] Failed to reposition window', error) + } }
422-431: Add try-catch aroundgetBounds()calls.Lines 425 and 430 call
getBounds()without error handling. Per coding guidelines, wrap these in try-catch blocks to prevent uncaught exceptions when windows are unexpectedly destroyed.🔎 Proposed fix
private getReferenceBounds(excludeWindowId?: number): Rectangle | undefined { const focused = this.windowPresenter.getFocusedWindow() if (focused && !focused.isDestroyed() && focused.id !== excludeWindowId) { - return focused.getBounds() + try { + return focused.getBounds() + } catch (error) { + console.warn('[YoBrowser] Failed to get bounds from focused window', error) + } } const fallback = this.windowPresenter .getAllWindows() .find((candidate) => candidate.id !== excludeWindowId) - return fallback?.getBounds() + if (fallback) { + try { + return fallback.getBounds() + } catch (error) { + console.warn('[YoBrowser] Failed to get bounds from fallback window', error) + } + } + return undefined }
433-493: Replace Chinese comments with English.Lines 438, 451, 455, 463, 467, 471, 477, and 482 contain Chinese comments. Per coding guidelines, all comments in TypeScript files must be in English.
🔎 Proposed fix
if (!referenceBounds) { - // 如果没有参考窗口,使用默认位置 + // No reference window available, use default position const display = screen.getDisplayMatching(windowBounds)- // Browser 窗口尺寸 + // Browser window dimensions const browserWidth = windowBounds.width- // 计算主窗口右侧和左侧的空间 + // Calculate available space on right and left of main window const spaceOnRight = workArea.x + workArea.width - (referenceBounds.x + referenceBounds.width)if (spaceOnRight >= browserWidth + gap) { - // 显示在主窗口右侧 + // Position on the right side of main window targetX = referenceBounds.x + referenceBounds.width + gap} else if (spaceOnLeft >= browserWidth + gap) { - // 显示在主窗口左侧 + // Position on the left side of main window targetX = referenceBounds.x - browserWidth - gap} else { - // 空间不够,显示在主窗口下方 + // Not enough horizontal space, position below main window targetX = referenceBounds.x} else { - // 下方空间也不够,显示在主窗口上方 + // Not enough space below, position above main window targetY = referenceBounds.y - browserHeight - gap- // 确保窗口在屏幕范围内 + // Ensure window stays within screen bounds const clampedX = Math.max(
🧹 Nitpick comments (4)
docs/workspace-agent-refactoring-summary.md (4)
9-50: Specify language identifier for Mermaid diagram.The code block contains a Mermaid diagram but lacks an explicit language identifier, which prevents proper rendering and linting compliance.
🔎 Proposed fix
-```mermaid +```mermaid graph TBNote: If
mermaidis not recognized, use a standard format or ensure your documentation tool supports Mermaid.
269-277: Add language identifier to data flow code block.The fenced code block lacks a language specification, which violates Markdown best practices and may fail linting checks.
🔎 Proposed fix
-``` +```text ChatMode ↓ ChatInput (Mode Switch)
281-291: Add language identifier to Workspace data flow code block.Same formatting issue—missing language specification for the fenced code block.
🔎 Proposed fix
-``` +```text Workspace Path Select ↓ useAgentWorkspace / useAcpWorkdir
295-305: Add language identifier to tool call flow code block.Missing language specification for consistency and linting compliance.
🔎 Proposed fix
-``` +```text Agent Loop ↓ ToolCallProcessor
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
docs/workspace-agent-refactoring-summary.mdsrc/main/presenter/browser/YoBrowserPresenter.ts
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/browser/YoBrowserPresenter.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Electron main process code belongs in `src/main/` with presenters in `presenter/` (Window/Tab/Thread/Mcp/Config/LLMProvider) and `eventbus.ts` for app events
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/**/*.ts : Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Always use try-catch to handle possible errors in TypeScript code
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx}x : Use error boundaries to catch rendering errors in React components
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Implement error retry mechanisms for transient failures in TypeScript
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Implement proper error handling and logging for debugging in Electron applications
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to **/*.{ts,tsx,js,jsx,vue} : Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:15.929Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/development-setup.mdc:0-0
Timestamp: 2025-11-25T05:26:15.929Z
Learning: Applies to **/*.{js,ts,jsx,tsx,mjs,cjs} : Write logs and comments in English
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,tsx,vue} : Write concise, technical TypeScript code with accurate examples
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:35.317Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/error-logging.mdc:0-0
Timestamp: 2025-11-25T05:26:35.317Z
Learning: Applies to **/*.{ts,tsx} : Avoid logging sensitive information (passwords, tokens, PII) in logs
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/**/*.ts : Use EventBus from `src/main/eventbus.ts` for main-to-renderer communication, broadcasting events via `mainWindow.webContents.send()`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to src/shared/**/*.d.ts : Define type definitions in shared/*.d.ts files for objects exposed by the main process to the renderer process
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/**/*.ts : Use EventBus for inter-process communication events
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
📚 Learning: 2025-11-25T05:27:26.656Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T05:27:26.656Z
Learning: Applies to src/shared/**/*.{js,ts} : Shared type definitions and utilities between main and renderer processes should be placed in `src/shared`
Applied to files:
src/main/presenter/browser/YoBrowserPresenter.ts
🧬 Code graph analysis (1)
src/main/presenter/browser/YoBrowserPresenter.ts (4)
test/mocks/electron.ts (1)
screen(57-60)src/main/presenter/browser/BrowserTab.ts (1)
BrowserTab(7-648)src/main/eventbus.ts (1)
eventBus(151-151)src/main/events.ts (1)
YO_BROWSER_EVENTS(190-198)
🪛 LanguageTool
docs/workspace-agent-refactoring-summary.md
[uncategorized] ~5-~5: 您的意思是“"不"齐”?
Context: ...ce UI 对 agent/acp agent 通用,路径选择与会话设置同步,并补齐安全边界与文件刷新机制。 ## 架构概览 ```mermaid graph...
(BU)
[uncategorized] ~128-~128: 您的意思是“"不"写”?
Context: ...r(useAcpWorkdir) - 路径与会话设置同步(会话未创建时暂存并补写) ### 7. 模型选择逻辑更新 ✅ 实现文件: - `src/...
(BU)
[uncategorized] ~149-~149: 您的意思是“"不"全”?
Context: ...ationHandler.ts **功能**: -agent模式自动补全默认工作区并落库 - system prompt 在agent` 模式追加...
(BU)
[uncategorized] ~174-~174: 您的意思是“"不"齐”?
Context: ... - ToolPresenter、Workspace、ChatMode 相关类型补齐 - 新增模式/Workspace/工具调用相关文案 ## 关键文件 - ...
(BU)
🪛 markdownlint-cli2 (0.18.1)
docs/workspace-agent-refactoring-summary.md
269-269: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
281-281: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
295-295: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (6)
docs/workspace-agent-refactoring-summary.md (1)
1-315: LGTM—comprehensive and well-structured refactoring documentation.The document provides excellent coverage of the refactoring objectives, including architecture diagrams, implementation details, testing guidance, and backward compatibility notes. The structure clearly maps to the PR objectives (agent mode support, unified tool routing, generalized Workspace UI, and mode-aware capability switches). The separation of concerns between
agentandacp agentmodes is well-documented, and safety constraints (path whitelisting, regex validation) are explicitly called out.Minor note: The LanguageTool suggestions flagged by static analysis appear to be false positives—the Chinese phrases are idiomatic and correct in context.
src/main/presenter/browser/YoBrowserPresenter.ts (5)
46-54: LGTM!Clean implementation of optional positioning parameters. The signature change allows pre-calculating window position before creation, which integrates well with the new
show()flow.
159-165: LGTM!Clean pattern storing the result before returning, consistent with similar changes in
createTab().
350-360: LGTM!Solid implementation of text content aggregation from tool results. The type guard is correctly narrowing the type, and the fallback error message handles edge cases where no text content exists.
510-528: LGTM!Good improvements to tab listener handling:
- Properly updates
updatedAttimestamp on title and favicon changes- Smart optimization to only emit
TAB_UPDATEDwhen favicon actually changes (line 522 comparison)- Consistent use of the new
emitTabUpdatedhelper
655-658: LGTM!Clean addition following the established pattern of other emit methods in the class. Properly broadcasts tab updates to all renderer windows via EventBus.
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.