mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
11 KiB
11 KiB
重构总结文档
概述
本次重构将 MemoHome CLI 项目分离成了清晰的两个层次,并实现了 Telegram Bot 的多用户登录鉴权系统。
重构目标
- ✅ 分离关注点: CLI UI 层和核心业务逻辑完全分离
- ✅ 可复用性: Core 层可被任何平台使用(CLI、Telegram、Web 等)
- ✅ 多存储后端: 支持不同的存储方式(文件、Redis 等)
- ✅ 多用户支持: Telegram bot 支持多个 TG 账号绑定多个 MemoHome 账号
架构变化
之前 (单体架构)
packages/cli/
├── src/
│ ├── client.ts # 混合了 API 调用和配置管理
│ ├── config.ts # 硬编码文件存储
│ ├── utils.ts
│ ├── types.ts
│ └── commands/ # CLI 命令直接调用 API
│ ├── auth.ts
│ ├── user.ts
│ └── ...
问题:
- CLI 和业务逻辑耦合
- 配置硬编码为文件存储
- 无法在其他平台复用
- 单用户设计
之后 (分层架构)
packages/cli/
├── src/
│ ├── core/ # 核心业务逻辑(可复用)
│ │ ├── context.ts # 上下文管理
│ │ ├── storage.ts # 存储接口定义
│ │ ├── storage/
│ │ │ ├── file.ts # 文件存储实现
│ │ │ └── index.ts
│ │ ├── client.ts # API 客户端(支持多种存储)
│ │ ├── auth.ts # 认证逻辑
│ │ ├── user.ts # 用户管理
│ │ ├── agent.ts # AI 对话
│ │ └── ...
│ ├── cli/ # CLI UI 层
│ │ ├── index.ts # CLI 入口
│ │ └── commands/ # 命令定义(使用 core)
│ │ ├── auth.ts
│ │ ├── user.ts
│ │ └── ...
│ ├── types/ # 类型定义
│ └── utils/ # 工具函数
packages/platform-telegram/ # Telegram 平台
├── src/
│ ├── storage.ts # Redis 存储实现
│ ├── auth.ts # Telegram 认证处理
│ ├── index.ts # Bot 实现(使用 cli/core)
│ └── bot.ts # 独立启动入口
核心改进
1. 存储抽象层
接口定义 (cli/src/core/storage.ts):
export interface TokenStorage {
getApiUrl(): Promise<string> | string
setApiUrl(url: string): Promise<void> | void
getToken(userId?: string): Promise<string | null> | string | null
setToken(token: string, userId?: string): Promise<void> | void
clearToken(userId?: string): Promise<void> | void
}
实现:
-
FileTokenStorage (CLI 用)
- 存储位置:
~/.memohome/config.json - 单用户
- 同步操作
- 存储位置:
-
TelegramRedisStorage (Telegram Bot 用)
- 存储位置: Redis
- 多用户:
memohome:tg:token:{telegram_user_id} - 异步操作
- 30 天过期
2. 上下文管理
MemoHomeContext (cli/src/core/context.ts):
export interface MemoHomeContext {
storage: TokenStorage // 存储后端
currentUserId?: string // 当前用户 ID(用于多用户场景)
}
使用方式:
// CLI 场景(单用户,文件存储)
import { setContext, FileTokenStorage } from '@memohome/cli/core'
setContext({
storage: new FileTokenStorage()
})
// Telegram 场景(多用户,Redis 存储)
import { createContext } from '@memohome/cli/core'
import { TelegramRedisStorage } from '@memohome/platform-telegram'
const storage = new TelegramRedisStorage()
const context = createContext({
storage,
userId: telegramUserId // 不同的 TG 用户
})
3. 同步/异步 API 支持
为了同时支持同步存储(文件)和异步存储(Redis),提供了两套 API:
// 同步版本(CLI 用)
export function login(params: LoginParams, context?: MemoHomeContext)
export function isLoggedIn(context?: MemoHomeContext): boolean
export function getToken(context?: MemoHomeContext): string | null
// 异步版本(Telegram Bot 用)
export async function loginAsync(params: LoginParams, context?: MemoHomeContext)
export async function isLoggedInAsync(context?: MemoHomeContext): Promise<boolean>
export async function getTokenAsync(context?: MemoHomeContext): Promise<string | null>
4. Telegram Bot 多用户架构
存储结构:
Redis:
memohome:tg:token:123456 -> "token_abc..." (Telegram User 123456)
memohome:tg:user:123456 -> { username, role }
memohome:tg:token:789012 -> "token_def..." (Telegram User 789012)
memohome:tg:user:789012 -> { username, role }
工作流程:
- 用户 A (TG ID: 123456) 发送:
/login userA passwordA - Bot 验证 -> 获取 token -> 存储到 Redis:
token:123456 - 用户 B (TG ID: 789012) 发送:
/login userB passwordB - Bot 验证 -> 获取 token -> 存储到 Redis:
token:789012 - 两个用户独立聊天,使用各自的 token
鉴权中间件:
bot.command('chat', requireAuth(storage), async (ctx) => {
// 自动检查用户是否已登录
// 获取该用户的 token
// 执行命令
})
使用示例
CLI 使用(不变)
# CLI 仍然使用文件存储
memohome auth login -u admin -p password
memohome agent chat "Hello"
作为库使用
import { login, chat } from '@memohome/cli'
// 默认使用文件存储
await login({ username: 'admin', password: 'password' })
const response = await chat({ message: 'Hello' })
Telegram Bot 使用
# 配置环境变量
export BOT_TOKEN="your_bot_token"
export REDIS_URL="redis://localhost:6379"
export API_BASE_URL="http://localhost:7002"
# 启动 bot
cd packages/platform-telegram
pnpm start
用户操作:
User A: /login adminA passwordA
Bot: ✅ Login successful! Username: adminA
User B: /login userB passwordB
Bot: ✅ Login successful! Username: userB
User A: 今天天气怎么样?
Bot: 🤖 今天天气...
User B: 讲个笑话
Bot: 🤖 好的,听好了...
在其他项目中使用 Core
import {
createContext,
loginAsync,
chatStreamAsync
} from '@memohome/cli/core'
import { TelegramRedisStorage } from '@memohome/platform-telegram'
// 创建自定义存储
const storage = new TelegramRedisStorage({
redisUrl: 'redis://localhost:6379'
})
// 为用户创建上下文
const userContext = createContext({
storage,
userId: 'user_12345'
})
// 登录
await loginAsync({
username: 'user',
password: 'pass'
}, userContext)
// 聊天
await chatStreamAsync({
message: 'Hello'
}, async (event) => {
if (event.type === 'text-delta') {
console.log(event.text)
}
}, userContext)
关键文件清单
CLI 包
| 文件 | 作用 |
|---|---|
src/core/storage.ts |
存储接口定义 |
src/core/storage/file.ts |
文件存储实现(CLI 用) |
src/core/context.ts |
上下文管理 |
src/core/client.ts |
API 客户端(支持上下文) |
src/core/auth.ts |
认证逻辑(同步/异步版本) |
src/core/agent.ts |
AI 对话(同步/异步版本) |
src/core/index.ts |
统一导出 |
src/cli/commands/* |
CLI 命令(使用 core) |
Telegram 平台包
| 文件 | 作用 |
|---|---|
src/storage.ts |
Redis 存储实现 |
src/auth.ts |
Telegram 认证处理器 |
src/index.ts |
Bot 主逻辑 |
src/bot.ts |
独立启动入口 |
README.md |
使用文档 |
SETUP.md |
设置指南 |
迁移指南
如果你有旧代码需要迁移:
旧代码
import { createClient, getToken } from './client'
import { loadConfig } from './config'
const client = createClient()
const token = getToken()
新代码
// 方式 1: 使用默认上下文(CLI 场景)
import { createClient, getToken } from '@memohome/cli/core'
const client = createClient()
const token = getToken()
// 方式 2: 使用自定义上下文(多用户场景)
import { createContext, createClientAsync, getTokenAsync } from '@memohome/cli/core'
import { TelegramRedisStorage } from '@memohome/platform-telegram'
const storage = new TelegramRedisStorage()
const context = createContext({ storage, userId: 'user123' })
const client = await createClientAsync(context)
const token = await getTokenAsync(context)
测试
CLI 测试
cd packages/cli
pnpm start auth login -u admin -p password
pnpm start agent chat "Hello"
Telegram Bot 测试
- 启动 Redis:
redis-server - 启动 API:
cd packages/api && pnpm start - 启动 Bot:
cd packages/platform-telegram && pnpm start - 在 Telegram 中测试:
/start/login admin password/chat 你好
优势总结
1. 关注点分离
- ✅ Core 层: 纯业务逻辑,无 UI 依赖
- ✅ CLI 层: 只负责用户交互
- ✅ Platform 层: 平台特定实现
2. 可扩展性
- ✅ 轻松添加新的存储后端
- ✅ 轻松添加新的平台(Web、Desktop、Discord 等)
- ✅ 轻松添加新功能到 core
3. 可测试性
- ✅ Core 层可独立测试,无需模拟 UI
- ✅ Storage 可以 mock
- ✅ Context 可以独立创建
4. 多用户支持
- ✅ Telegram bot 支持多个用户同时使用
- ✅ 每个用户独立的 session
- ✅ Token 自动管理和过期
5. 类型安全
- ✅ 完整的 TypeScript 类型定义
- ✅ 导出所有类型供外部使用
未来扩展
基于这个架构,可以轻松添加:
-
Discord Bot
// packages/platform-discord import { createContext, loginAsync } from '@memohome/cli/core' import { DiscordRedisStorage } from './storage' const storage = new DiscordRedisStorage() // 类似 Telegram 实现 -
Web 应用
// packages/web import { createContext, loginAsync, chatStreamAsync } from '@memohome/cli/core' import { BrowserStorage } from './storage' const storage = new BrowserStorage() // localStorage // 在 React/Vue 中使用 -
移动应用
// packages/mobile import { createContext } from '@memohome/cli/core' import { SecureStorage } from './storage' const storage = new SecureStorage() // React Native AsyncStorage
总结
本次重构实现了:
- ✅ 完全分离 CLI 和 Core 层
- ✅ 抽象存储 支持多种后端
- ✅ 多用户支持 Telegram bot 可服务多个用户
- ✅ 同步/异步 API 适配不同场景
- ✅ 可扩展 易于添加新平台和功能
- ✅ 文档完善 README、SETUP、示例齐全
现在你可以:
- 继续使用 CLI(体验不变)
- 启动 Telegram bot 服务多个用户
- 在其他项目中复用 Core 功能
- 轻松添加新的平台支持