feat: 完善 Server 层并添加 CLI 和 Web 前端
Server 层增强: - 添加 Agent 适配层,支持动态加载 core 模块 - 实现 Token 认证机制,支持本地/远程模式 - WebSocket 集成 Agent 实时对话 CLI 模块 (packages/cli): - serve 命令启动 HTTP Server - attach 命令连接远程 Server - API Client 封装 Web 前端 (packages/web): - React 18 + Vite + Tailwind CSS - 会话管理侧边栏 - WebSocket 实时聊天界面 - 流式消息显示
This commit is contained in:
@@ -18,6 +18,16 @@ import {
|
||||
} from './ws.js';
|
||||
import { handleSSE, getSSEStats } from './sse.js';
|
||||
import { getSessionManager } from './session/manager.js';
|
||||
import { initCore, isCoreAvailable, getAgentStats } from './agent/index.js';
|
||||
import {
|
||||
authMiddleware,
|
||||
initAuth,
|
||||
getAuthConfig,
|
||||
generateToken,
|
||||
addToken,
|
||||
setAuthEnabled,
|
||||
maskToken,
|
||||
} from './auth/index.js';
|
||||
|
||||
// 创建 Hono 应用
|
||||
const app = new Hono();
|
||||
@@ -36,15 +46,26 @@ app.use(
|
||||
})
|
||||
);
|
||||
|
||||
// 健康检查
|
||||
// 认证中间件 (在 CORS 之后)
|
||||
app.use('*', authMiddleware);
|
||||
|
||||
// 健康检查 (跳过认证)
|
||||
app.get('/health', (c) => {
|
||||
const sessionManager = getSessionManager();
|
||||
const wsStats = getConnectionStats();
|
||||
const sseStats = getSSEStats();
|
||||
const authConfig = getAuthConfig();
|
||||
|
||||
return c.json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
agent: {
|
||||
coreAvailable: isCoreAvailable(),
|
||||
},
|
||||
auth: {
|
||||
enabled: authConfig.enabled,
|
||||
tokenCount: authConfig.tokens.length,
|
||||
},
|
||||
stats: {
|
||||
sessions: sessionManager.count(),
|
||||
websocket: wsStats,
|
||||
@@ -119,6 +140,10 @@ app.onError((err, c) => {
|
||||
export interface ServerOptions {
|
||||
port?: number;
|
||||
host?: string;
|
||||
/** 是否启用认证 (远程模式自动启用) */
|
||||
auth?: boolean;
|
||||
/** 预设的 token */
|
||||
token?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,12 +160,51 @@ export function createServer(options: ServerOptions = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化服务器(加载 core 模块等)
|
||||
*/
|
||||
export async function initServer(options: ServerOptions = {}): Promise<void> {
|
||||
// 尝试加载 core 模块
|
||||
const coreLoaded = await initCore();
|
||||
if (coreLoaded) {
|
||||
console.log('[Server] Core module initialized');
|
||||
} else {
|
||||
console.warn('[Server] Core module not available, running in limited mode');
|
||||
}
|
||||
|
||||
// 初始化认证
|
||||
const { host = '127.0.0.1', auth, token } = options;
|
||||
const isRemote = host !== '127.0.0.1' && host !== 'localhost';
|
||||
const authEnabled = auth !== undefined ? auth : isRemote;
|
||||
|
||||
initAuth({
|
||||
enabled: authEnabled,
|
||||
tokens: [],
|
||||
skipPaths: ['/health', '/api/health'],
|
||||
});
|
||||
|
||||
// 如果启用认证,生成或使用提供的 token
|
||||
if (authEnabled) {
|
||||
const serverToken = token || generateToken();
|
||||
addToken(serverToken);
|
||||
console.log(`[Auth] Authentication enabled`);
|
||||
console.log(`[Auth] Token: ${serverToken}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动服务器 (Bun 环境)
|
||||
*/
|
||||
export function startServer(options: ServerOptions = {}): void {
|
||||
export async function startServer(options: ServerOptions = {}): Promise<void> {
|
||||
const { port = 3000, host = '127.0.0.1' } = options;
|
||||
|
||||
// 初始化
|
||||
await initServer(options);
|
||||
|
||||
const coreStatus = isCoreAvailable() ? '✅ Core loaded' : '⚠️ Core not available';
|
||||
const authConfig = getAuthConfig();
|
||||
const authStatus = authConfig.enabled ? '🔐 Enabled' : '🔓 Disabled';
|
||||
|
||||
console.log(`
|
||||
╔════════════════════════════════════════════╗
|
||||
║ AI Assistant Server ║
|
||||
@@ -149,6 +213,8 @@ export function startServer(options: ServerOptions = {}): void {
|
||||
║ WebSocket: ws://${host}:${port}/api/ws/:sessionId
|
||||
║ SSE: http://${host}:${port}/api/sessions/:id/events
|
||||
║ Health: http://${host}:${port}/health
|
||||
║ Agent: ${coreStatus}
|
||||
║ Auth: ${authStatus}
|
||||
╚════════════════════════════════════════════╝
|
||||
`);
|
||||
|
||||
@@ -170,4 +236,21 @@ export {
|
||||
emitFileChangeEvent,
|
||||
} from './sse.js';
|
||||
export { broadcastToSession } from './ws.js';
|
||||
export {
|
||||
initCore,
|
||||
isCoreAvailable,
|
||||
getAgentStats,
|
||||
processMessage,
|
||||
cancelProcessing,
|
||||
} from './agent/index.js';
|
||||
export {
|
||||
initAuth,
|
||||
getAuthConfig,
|
||||
generateToken,
|
||||
addToken,
|
||||
removeToken,
|
||||
setAuthEnabled,
|
||||
validateToken,
|
||||
maskToken,
|
||||
} from './auth/index.js';
|
||||
export * from './types.js';
|
||||
|
||||
Reference in New Issue
Block a user