feat: refactor HomePage to integrate agents store and update related components

feat: add runtime event handling for providers in ProvidersSection

feat: update routing to include Channels and Agents pages

feat: extend route types and navigation items for Channels and Agents

feat: implement agents store for managing agent data and interactions

fix: update chat store to utilize agents store for agent-related functionality

chore: export agents store from index

fix: enhance runtime types for better event handling

fix: update Vite config to handle dev server URL correctly
This commit is contained in:
duanshuwen
2026-04-18 14:56:32 +08:00
parent dfa4388087
commit ee72cf7261
52 changed files with 6626 additions and 189 deletions

View File

@@ -1,10 +1,18 @@
import { BrowserWindow } from 'electron';
import { windowManager } from '@electron/service/window-service';
import logManager from '@electron/service/logger';
import type { GatewayEvent } from './types';
import type { GatewayEvent, RuntimeRefreshTopic } from './types';
import * as chatHandlers from './handlers/chat';
import * as providerHandlers from './handlers/provider';
type RuntimeChangeBroadcast = {
topics: RuntimeRefreshTopic[];
reason?: string;
warnings?: string[];
channelType?: string;
accountId?: string;
};
class GatewayManager {
private initialized = false;
private status: 'connected' | 'disconnected' | 'reconnecting' = 'disconnected';
@@ -31,10 +39,13 @@ class GatewayManager {
this.setStatus('disconnected');
}
async restart(): Promise<void> {
async restart(options?: RuntimeChangeBroadcast): Promise<void> {
this.initialized = false;
this.setStatus('reconnecting');
await this.init();
if (options) {
this.notifyRuntimeChanged(options);
}
}
getStatus(): {
@@ -97,10 +108,34 @@ class GatewayManager {
}
}
reloadProviders(): void {
notifyRuntimeChanged(options: RuntimeChangeBroadcast): void {
const topics = Array.from(new Set(options.topics.filter(Boolean)));
if (topics.length === 0) {
return;
}
this.broadcast({
type: 'runtime:changed',
topics,
reason: options.reason,
warnings: options.warnings && options.warnings.length > 0 ? options.warnings : undefined,
channelType: options.channelType,
accountId: options.accountId,
syncedAt: new Date().toISOString(),
});
}
reloadProviders(options?: RuntimeChangeBroadcast): void {
logManager.info('GatewayManager reloading providers');
// For now, providers are resolved on each chat.send call,
// so no in-memory cache to invalidate. Future: notify active sessions.
this.notifyRuntimeChanged({
topics: options?.topics ?? ['providers', 'models'],
reason: options?.reason ?? 'providers:reload',
warnings: options?.warnings,
channelType: options?.channelType,
accountId: options?.accountId,
});
}
}

View File

@@ -1,15 +1,15 @@
import * as fs from 'fs';
import * as path from 'path';
import { app } from 'electron';
import logManager from '@electron/service/logger';
import { normalizeAgentSessionKey } from '@runtime/lib/models';
import type { RawMessage } from '@runtime/shared/chat-model';
import { getUserDataDir } from '@electron/utils/paths';
let sessionsFilePath: string | null = null;
function getSessionsFilePath(): string {
if (!sessionsFilePath) {
sessionsFilePath = path.join(app.getPath('userData'), 'chat-sessions.json');
sessionsFilePath = path.join(getUserDataDir(), 'chat-sessions.json');
}
return sessionsFilePath;
}

View File

@@ -1,5 +1,12 @@
import type { RawMessage } from '@runtime/shared/chat-model';
export type RuntimeRefreshTopic =
| 'providers'
| 'models'
| 'agents'
| 'channels'
| 'channel-targets';
/// Gateway 向 Renderer 推送的事件类型
export type GatewayEvent =
| {
@@ -28,6 +35,15 @@ export type GatewayEvent =
| {
type: 'gateway:status';
status: 'connected' | 'disconnected' | 'reconnecting';
}
| {
type: 'runtime:changed';
topics: RuntimeRefreshTopic[];
reason?: string;
syncedAt: string;
warnings?: string[];
channelType?: string;
accountId?: string;
};
/// Gateway RPC 方法参数映射