feat(desktop): improve profile IPC and error handling

- Add reloadSystemPrompt call after profile updates
- Add error handling and logging for Hub initialization
- Clean up debug logs from agent IPC handlers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jiang Bohan 2026-02-04 13:26:22 +08:00
parent fa03ae6e62
commit a4f8cbd978
4 changed files with 76 additions and 10 deletions

View file

@ -125,8 +125,6 @@ export function registerAgentIpcHandlers(): void {
* Persists the change to profile config and reloads tools.
*/
ipcMain.handle('tools:toggle', async (_event, toolName: string) => {
console.log(`[IPC] tools:toggle called for: ${toolName}`)
const agent = getDefaultAgent()
if (!agent) {
return { error: 'No agent available' }
@ -145,7 +143,6 @@ export function registerAgentIpcHandlers(): void {
// Get updated status
const newActiveTools = agent.getActiveTools()
const isNowEnabled = newActiveTools.includes(toolName)
console.log(`[IPC] Tool ${toolName} toggled: ${isCurrentlyEnabled} -> ${isNowEnabled}`)
return {
name: toolName,

View file

@ -13,31 +13,43 @@ import type { AsyncAgent } from '../../../../src/agent/async-agent.js'
let hub: Hub | null = null
let defaultAgentId: string | null = null
/**
* Safe log function that catches EPIPE errors.
* Electron main process stdout can be closed unexpectedly.
*/
function safeLog(...args: unknown[]): void {
try {
console.log(...args)
} catch {
// Ignore EPIPE errors when stdout is closed
}
}
/**
* Initialize Hub on app startup.
* Creates Hub and a default Agent automatically.
*/
export async function initializeHub(): Promise<void> {
if (hub) {
console.log('[Desktop] Hub already initialized')
safeLog('[Desktop] Hub already initialized')
return
}
const gatewayUrl = process.env['GATEWAY_URL'] ?? 'http://localhost:3000'
console.log(`[Desktop] Initializing Hub, connecting to Gateway: ${gatewayUrl}`)
safeLog(`[Desktop] Initializing Hub, connecting to Gateway: ${gatewayUrl}`)
hub = new Hub(gatewayUrl)
// Create default agent if none exists
const agents = hub.listAgents()
if (agents.length === 0) {
console.log('[Desktop] Creating default agent...')
safeLog('[Desktop] Creating default agent...')
const agent = hub.createAgent()
defaultAgentId = agent.sessionId
console.log(`[Desktop] Default agent created: ${defaultAgentId}`)
safeLog(`[Desktop] Default agent created: ${defaultAgentId}`)
} else {
defaultAgentId = agents[0]
console.log(`[Desktop] Using existing agent: ${defaultAgentId}`)
safeLog(`[Desktop] Using existing agent: ${defaultAgentId}`)
}
}
@ -47,7 +59,7 @@ export async function initializeHub(): Promise<void> {
function getHub(): Hub {
if (!hub) {
const gatewayUrl = process.env['GATEWAY_URL'] ?? 'http://localhost:3000'
console.log(`[Desktop] Creating Hub, connecting to Gateway: ${gatewayUrl}`)
safeLog(`[Desktop] Creating Hub, connecting to Gateway: ${gatewayUrl}`)
hub = new Hub(gatewayUrl)
}
return hub
@ -228,7 +240,7 @@ export function registerHubIpcHandlers(): void {
*/
export function cleanupHub(): void {
if (hub) {
console.log('[Desktop] Shutting down Hub')
safeLog('[Desktop] Shutting down Hub')
hub.shutdown()
hub = null
}

View file

@ -71,10 +71,21 @@ export function registerProfileIpcHandlers(): void {
ipcMain.handle('profile:updateUser', async (_event, content: string) => {
const agent = getDefaultAgent()
if (!agent) {
console.error('[Profile IPC] No agent available for updateUser')
return { error: 'No agent available' }
}
console.log('[Profile IPC] Updating user content:', content.substring(0, 50) + '...')
agent.setUserContent(content)
// Reload system prompt to apply changes immediately
console.log('[Profile IPC] Reloading system prompt...')
agent.reloadSystemPrompt()
// Verify the change
const newUserContent = agent.getUserContent()
console.log('[Profile IPC] New user content:', newUserContent?.substring(0, 50) + '...')
return { ok: true }
})
}

View file

@ -1,3 +1,49 @@
// Patch console methods to handle EPIPE errors in Electron main process
// This MUST be done before any other imports that might use console
// EPIPE happens when stdout/stderr pipes are closed unexpectedly
const originalConsoleLog = console.log.bind(console)
const originalConsoleError = console.error.bind(console)
const originalConsoleWarn = console.warn.bind(console)
const safeLog = (...args: unknown[]) => {
try {
originalConsoleLog(...args)
} catch {
// Ignore EPIPE errors silently
}
}
const safeError = (...args: unknown[]) => {
try {
originalConsoleError(...args)
} catch {
// Ignore EPIPE errors silently
}
}
const safeWarn = (...args: unknown[]) => {
try {
originalConsoleWarn(...args)
} catch {
// Ignore EPIPE errors silently
}
}
// Override global console
console.log = safeLog
console.error = safeError
console.warn = safeWarn
// Also handle process stdout/stderr EPIPE errors
process.stdout?.on?.('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EPIPE') return // Ignore
throw err
})
process.stderr?.on?.('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EPIPE') return // Ignore
throw err
})
import { app, BrowserWindow } from 'electron'
import { fileURLToPath } from 'node:url'
import path from 'node:path'