feat: 重构为 Monorepo 架构并实现 HTTP Server
架构变更: - 采用 pnpm workspaces 实现 Monorepo 结构 - 将现有代码迁移到 packages/core - 新增 packages/server HTTP 服务层 Server 功能: - REST API: 会话管理、工具管理、配置管理 - WebSocket: 实时双向通信支持 - SSE: 服务端事件推送 - Hono + Bun 作为运行时 API 端点: - GET/POST /api/sessions - 会话 CRUD - GET/POST /api/sessions/:id/messages - 消息管理 - GET /api/sessions/:id/events - SSE 事件流 - WS /api/ws/:sessionId - WebSocket 连接 - GET/POST /api/tools - 工具管理 - GET/PUT /api/config - 配置管理
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Session Manager
|
||||
*
|
||||
* 管理所有活跃的会话
|
||||
*/
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { Session, CreateSessionInput, Message, SessionStatus } from '../types.js';
|
||||
|
||||
export class SessionManager {
|
||||
private sessions: Map<string, Session> = new Map();
|
||||
private messages: Map<string, Message[]> = new Map();
|
||||
|
||||
/**
|
||||
* 创建新会话
|
||||
*/
|
||||
create(input: CreateSessionInput = {}): Session {
|
||||
const now = new Date().toISOString();
|
||||
const session: Session = {
|
||||
id: uuidv4(),
|
||||
name: input.name,
|
||||
workdir: input.workdir || process.cwd(),
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
status: 'idle',
|
||||
messageCount: 0,
|
||||
};
|
||||
|
||||
this.sessions.set(session.id, session);
|
||||
this.messages.set(session.id, []);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有会话
|
||||
*/
|
||||
list(): Session[] {
|
||||
return Array.from(this.sessions.values()).sort(
|
||||
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个会话
|
||||
*/
|
||||
get(id: string): Session | undefined {
|
||||
return this.sessions.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除会话
|
||||
*/
|
||||
delete(id: string): boolean {
|
||||
this.messages.delete(id);
|
||||
return this.sessions.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新会话状态
|
||||
*/
|
||||
updateStatus(id: string, status: SessionStatus): Session | undefined {
|
||||
const session = this.sessions.get(id);
|
||||
if (!session) return undefined;
|
||||
|
||||
session.status = status;
|
||||
session.updatedAt = new Date().toISOString();
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话消息
|
||||
*/
|
||||
getMessages(sessionId: string): Message[] {
|
||||
return this.messages.get(sessionId) || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加消息
|
||||
*/
|
||||
addMessage(sessionId: string, message: Omit<Message, 'id' | 'sessionId' | 'createdAt'>): Message | undefined {
|
||||
const session = this.sessions.get(sessionId);
|
||||
if (!session) return undefined;
|
||||
|
||||
const fullMessage: Message = {
|
||||
...message,
|
||||
id: uuidv4(),
|
||||
sessionId,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const messages = this.messages.get(sessionId) || [];
|
||||
messages.push(fullMessage);
|
||||
this.messages.set(sessionId, messages);
|
||||
|
||||
// 更新会话
|
||||
session.messageCount = messages.length;
|
||||
session.updatedAt = new Date().toISOString();
|
||||
|
||||
return fullMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话数量
|
||||
*/
|
||||
count(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查会话是否存在
|
||||
*/
|
||||
exists(id: string): boolean {
|
||||
return this.sessions.has(id);
|
||||
}
|
||||
}
|
||||
|
||||
// 单例
|
||||
let instance: SessionManager | null = null;
|
||||
|
||||
export function getSessionManager(): SessionManager {
|
||||
if (!instance) {
|
||||
instance = new SessionManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
Reference in New Issue
Block a user