feat: 重构对话功能

This commit is contained in:
DEV_DSW
2026-04-14 17:02:20 +08:00
parent b3f07c4cfe
commit c61e41049f
53 changed files with 5200 additions and 1982 deletions

View File

@@ -1,4 +1,4 @@
import { app, BrowserWindow } from 'electron'
import { app, BrowserWindow, ipcMain } from 'electron'
import { CONFIG_KEYS } from '@lib/constants'
import { setupMainWindow } from './wins';
import started from 'electron-squirrel-startup'
@@ -8,10 +8,133 @@ import { initScriptStoreService } from '@electron/service/script-store-service'
import log from 'electron-log';
import 'bytenode'; // Ensure bytenode is bundled/externalized correctly
import { appUpdater } from '@electron/service/updater';
import axios from 'axios';
import { providerApiService, onProviderChange } from '@electron/service/provider-api-service';
import { gatewayManager } from '@electron/gateway/manager';
// 初始化 updater确保在 app ready 之前或者之中注册好 IPC
appUpdater.init();
// 注册 hostapi:fetch IPC 代理
// 模型管理相关接口在本地处理(对齐 ClawX其余接口代理到远端后端
const HOST_API_BASE_URL = process.env.VITE_SERVICE_URL || 'http://8.138.234.141/ingress';
async function handleLocalProviderApi(path: string, method: string, body: any) {
const parsedBody = typeof body === 'string' && body ? JSON.parse(body) : body;
if (path === '/api/provider-vendors' && method === 'GET') {
return { success: true, ok: true, json: providerApiService.getVendors(), data: providerApiService.getVendors() };
}
if (path === '/api/provider-accounts' && method === 'GET') {
return { success: true, ok: true, json: providerApiService.getAccounts(), data: providerApiService.getAccounts() };
}
if (path === '/api/providers' && method === 'GET') {
return { success: true, ok: true, json: providerApiService.getProviders(), data: providerApiService.getProviders() };
}
if (path === '/api/provider-accounts/default' && method === 'GET') {
return { success: true, ok: true, json: providerApiService.getDefault(), data: providerApiService.getDefault() };
}
if (path === '/api/provider-accounts' && method === 'POST') {
const result = providerApiService.createAccount(parsedBody || {});
return { success: true, ok: true, json: result, data: result };
}
if (path === '/api/provider-accounts/default' && method === 'PUT') {
const result = providerApiService.setDefault(parsedBody || {});
return { success: result.success, ok: result.success, json: result, data: result };
}
if (path.startsWith('/api/provider-accounts/') && method === 'PUT') {
const id = decodeURIComponent(path.replace('/api/provider-accounts/', ''));
const result = providerApiService.updateAccount(id, parsedBody || {});
return { success: result.success, ok: result.success, json: result, data: result };
}
if (path.startsWith('/api/provider-accounts/') && method === 'DELETE') {
const id = decodeURIComponent(path.replace('/api/provider-accounts/', ''));
const result = providerApiService.deleteAccount(id);
return { success: result.success, ok: result.success, json: result, data: result };
}
if (path === '/api/providers/default' && method === 'PUT') {
const result = providerApiService.setDefault({ accountId: parsedBody?.providerId });
return { success: result.success, ok: result.success, json: result, data: result };
}
if (path.startsWith('/api/providers/') && path.endsWith('/api-key') && method === 'GET') {
const id = decodeURIComponent(path.replace('/api/providers/', '').replace('/api-key', ''));
const result = providerApiService.getApiKey(id);
return { success: true, ok: true, json: result, data: result };
}
if (path.startsWith('/api/providers/') && method === 'PUT') {
// Provider updates are mapped to account updates for local storage
const id = decodeURIComponent(path.replace('/api/providers/', ''));
const result = providerApiService.updateAccount(id, parsedBody || {});
return { success: result.success, ok: result.success, json: result, data: result };
}
if (path.startsWith('/api/providers/') && method === 'DELETE') {
const [rawId, query] = path.replace('/api/providers/', '').split('?');
const id = decodeURIComponent(rawId);
if (query && query.includes('apiKeyOnly=1')) {
const result = providerApiService.deleteApiKey(id);
return { success: result.success, ok: result.success, json: result, data: result };
}
const result = providerApiService.deleteAccount(id);
return { success: result.success, ok: result.success, json: result, data: result };
}
if (path === '/api/providers/validate' && method === 'POST') {
const result = await providerApiService.validateApiKey(parsedBody || {});
return { success: true, ok: true, json: result, data: result };
}
if (path === '/api/usage/recent-token-history' && method === 'GET') {
return { success: true, ok: true, json: providerApiService.getUsageHistory(), data: providerApiService.getUsageHistory() };
}
return null;
}
ipcMain.handle('hostapi:fetch', async (_event, { path, method, headers, body }) => {
// 1. 优先本地处理模型管理接口
const localResult = await handleLocalProviderApi(path, method || 'GET', body);
if (localResult) return localResult;
// 2. 其余接口代理到远端后端
const url = `${HOST_API_BASE_URL}${path}`;
try {
const response = await axios({
url,
method: method || 'GET',
headers: {
'Content-Type': 'application/json',
...headers,
},
data: body ?? undefined,
timeout: 30000,
});
return {
success: true,
ok: true,
json: response.data,
data: response.data,
};
} catch (error: any) {
if (error.response) {
return {
success: false,
ok: false,
status: error.response.status,
error: error.response.data?.message || error.message,
text: error.response.statusText,
data: error.response.data,
};
}
return {
success: false,
ok: false,
error: error.message || 'Unknown error',
};
}
});
// Gateway RPC IPC handler
ipcMain.handle('gateway:rpc', async (_event, method: string, params: any) => {
return gatewayManager.rpc(method, params);
});
// import logManager from '@electron/service/logger'
@@ -29,6 +152,12 @@ if (started) {
// });
app.whenReady().then(() => {
gatewayManager.init();
onProviderChange(() => {
gatewayManager.reloadProviders();
});
setupMainWindow();
// 初始化脚本存储服务