9.3 KiB
9.3 KiB
Everjoy Tech Stack
Everjoy is not only an IDE but a completely fresh AI workflow.
An ideal agent tool with a TUI interacting interface, divided into several workspaces: file editing, vibe interacting, and project/life management.
1. TUI 渲染与交互框架
| 库 | 用途 |
|---|---|
| ratatui | TUI 渲染核心,多工作区布局、面板分割、状态管理 |
| crossterm | 跨平台输入输出(键鼠事件、颜色、光标、屏幕缓冲) |
| tui-textarea | 编辑器工作区的文本编辑组件 |
| tui-term | 内置终端面板(Agent 执行命令时展示实时输出) |
为什么选 ratatui
- 工作区(Workspace)需要复杂布局:侧边栏 + 编辑区 + AI 对话面板 + 状态栏
- 支持鼠标点击切换面板、拖拽分割线
- 活跃的组件生态,适合快速组装多面板界面
cargo add ratatui crossterm tui-textarea tui-term
2. 异步运行时与网络通信
| 库 | 用途 |
|---|---|
| tokio | 异步运行时,同时处理 UI 事件、AI 流式响应、文件监听 |
| reqwest | HTTP 客户端,调用 LLM API(OpenAI、Claude、本地 Ollama 等) |
| tokio-tungstenite | WebSocket 客户端(实时连接、本地服务通信) |
| futures | 流处理工具 |
AI 流式响应处理
cargo add tokio --features full
cargo add reqwest --features json,stream,rustls-tls
cargo add tokio-tungstenite
cargo add futures
3. Agent 核心引擎
这是 Everjoy 的灵魂。不依赖现有框架,自研一个轻量但可扩展的 Agent 循环。
核心架构
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Observer │ --> │ Thinker │ --> │ Actor │
│ (观察环境) │ │ (推理决策) │ │ (执行动作) │
└─────────────┘ └─────────────┘ └─────────────┘
^ |
└────────────── Feedback <─────────────┘
Agent 相关依赖
| 库 | 用途 |
|---|---|
| serde + serde_json | LLM API 请求/响应的结构化序列化 |
| schemars | 为工具函数生成 JSON Schema,供 LLM function calling 使用 |
| async-trait | Agent 组件的异步 trait 抽象 |
cargo add serde --features derive
cargo add serde_json
cargo add schemars
cargo add async-trait
工具系统(Tools)
Agent 需要能操作环境的工具集:
| 工具 | 实现方式 |
|---|---|
| 文件读写 | std::fs + ropey(大文件) |
| 命令执行 | tokio::process::Command + tui-term 展示输出 |
| 代码搜索 | regex + ignore(支持 .gitignore) |
| 网络请求 | reqwest(Agent 自主查询文档/API) |
| 任务管理 | 调用 SQLite 存储层(见第 5 节) |
cargo add regex ignore
4. 记忆系统(Memory)
Agent 不能金鱼脑。需要短期对话记忆 + 长期知识记忆。
短期记忆:对话上下文
直接维护 Vec<Message>,按 token 限制滑动窗口截断。
长期记忆:向量检索
| 库 | 用途 |
|---|---|
| rusqlite | 主数据库(对话历史、任务、配置、笔记) |
| sqlite-vec 或 pgvector 本地版 | 向量存储与相似度检索 |
| fastembed-rs | 本地文本 Embedding(不依赖外部 API) |
如果追求极简,可以先只用 SQLite 全文搜索(
fts5),后期再上向量。
cargo add rusqlite --features bundled
# 向量检索后续按需添加
5. 数据持久化层
Everjoy 管理项目和人生,需要稳定的数据层。
| 库 | 用途 |
|---|---|
| rusqlite | 嵌入式数据库,存储一切 |
| chrono | 时间处理、截止日期、日历事件 |
| uuid | 任务/对话/项目的唯一标识 |
数据库表设计(初版)
-- 对话历史
CREATE TABLE conversations (
id TEXT PRIMARY KEY,
title TEXT,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE messages (
id TEXT PRIMARY KEY,
conversation_id TEXT,
role TEXT, -- 'user' | 'assistant' | 'system' | 'tool'
content TEXT,
tool_calls TEXT, -- JSON
created_at DATETIME
);
-- 任务/项目管理
CREATE TABLE tasks (
id TEXT PRIMARY KEY,
title TEXT,
description TEXT,
status TEXT, -- 'todo' | 'doing' | 'done' | 'archived'
priority INTEGER,
due_date DATETIME,
project TEXT,
tags TEXT, -- JSON array
created_at DATETIME
);
-- 笔记/知识
CREATE TABLE notes (
id TEXT PRIMARY KEY,
title TEXT,
content TEXT,
tags TEXT,
linked_file TEXT,
created_at DATETIME
);
cargo add chrono --features serde
cargo add uuid --features v4,serde
6. 内容渲染与解析
| 库 | 用途 |
|---|---|
| pulldown-cmark | 解析 AI 回复的 Markdown,渲染到 TUI 面板 |
| syntect | 代码块语法高亮(Markdown 中的 ```rust 块) |
| syntect-tui | syntect 与 ratatui 的桥接 |
AI 回复基本是 Markdown,需要解析成 ratatui 的
Text/Span结构渲染。
cargo add pulldown-cmark
cargo add syntect syntect-tui
7. 文件系统与项目感知
| 库 | 用途 |
|---|---|
| ropey | 大文件高效编辑(编辑工作区核心) |
| notify | 监听文件变化,Agent 实时感知项目改动 |
| ignore | 按 .gitignore 规则遍历文件树 |
| walkdir | 目录遍历 |
cargo add ropey notify ignore walkdir
8. 配置管理
| 库 | 用途 |
|---|---|
| toml | 用户配置(AI API key、主题、快捷键、Agent 人设) |
| serde | 配置反序列化 |
| directories | 跨平台定位配置目录 ~/.config/everjoy/ |
配置文件结构
# ~/.config/everjoy/config.toml
[ai]
provider = "openai"
api_key = "sk-..."
model = "gpt-4o"
stream = true
[agent]
personality = "你是一位高效且略带幽默的编程伙伴..."
auto_execute_tools = false -- 危险操作需确认
[ui]
theme = "everforest"
sidebar_width = 30
editor_tab_size = 4
[keymap]
"ctrl+space" = "toggle_agent_panel"
"ctrl+shift+a" = "ask_agent"
cargo add toml serde --features derive directories
9. 实用工具库
| 库 | 用途 |
|---|---|
| anyhow | 快速原型期的错误处理 |
| thiserror | 后期结构化错误定义 |
| parking_lot | 更轻量的同步原语 |
| indexmap | 有序 HashMap(保持面板顺序、配置项顺序) |
| which | 查找系统命令路径(检查 git、node 等是否存在) |
| tempfile | 临时文件(Agent 编辑前备份) |
| glob | 文件通配匹配 |
cargo add anyhow thiserror parking_lot indexmap which tempfile glob
10. 完整 Cargo.toml
[package]
name = "everjoy"
version = "0.1.0"
edition = "2024"
[dependencies]
# TUI 渲染
ratatui = "0.29"
crossterm = "0.28"
tui-textarea = "0.7"
tui-term = "0.2"
# 异步 + 网络
tokio = { version = "1.4", features = ["full"] }
reqwest = { version = "0.12", features = ["json", "stream", "rustls-tls"] }
tokio-tungstenite = "0.26"
futures = "0.3"
# 序列化 + Agent 协议
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
schemars = "0.8"
async-trait = "0.1"
# 数据持久化
rusqlite = { version = "0.34", features = ["bundled", "chrono"] }
chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "1.16", features = ["v4", "serde"] }
# 文本 + 文件
ropey = "1.6"
pulldown-cmark = "0.13"
syntect = "5.2"
# syntect-tui = "..." # 视情况选择或自研桥接
notify = "8.0"
ignore = "0.4"
walkdir = "2.5"
# 配置 + 工具
toml = "0.8"
directories = "5.0"
regex = "1.11"
which = "7.0"
tempfile = "3.19"
glob = "0.3"
# 基础设施
anyhow = "1.0"
thiserror = "2.0"
parking_lot = "0.12"
indexmap = "2.7"
[dev-dependencies]
# 测试工具后续添加
12. 关键设计决策
| 维度 | 决策 | 理由 |
|---|---|---|
| 编辑模式 | 非模态(直接打字) | 开箱即用,AI 随时可介入 |
| Agent 架构 | 自研 ReAct 循环 | 现有框架太重,自研更灵活 |
| LLM 接入 | 多 Provider 抽象 | 支持 OpenAI/Claude/Ollama/本地模型 |
| 流式响应 | SSE 实时渲染 | AI 思考过程实时展示在对话面板 |
| 数据存储 | SQLite 单文件 | 用户项目 + 人生数据一盘棋 |
| 工具执行 | 人工确认 + 自动执行分级 | 读文件自动,写文件/执行命令需确认 |
| 文件编辑 | 临时缓冲 + 用户确认写入 | Agent 的修改先预览,用户 OK 再落盘 |
13. 开发里程碑(建议)
| 阶段 | 目标 | 核心组件 |
|---|---|---|
| MVP | TUI 多面板 + 基本编辑器 + 能聊天的 Agent | ratatui, tui-textarea, reqwest, 简单 ReAct |
| v0.2 | 文件工具 + 项目内代码问答 | ropey, ignore, notify, 文件读写工具 |
| v0.3 | 任务/笔记管理 + SQLite 持久化 | rusqlite, chrono, 任务面板 |
| v0.4 | 内嵌终端 + Agent 自主执行命令 | tui-term, tokio-process, 命令工具 |
| v0.5 | 记忆系统 + 跨对话上下文 | sqlite-vec, embedding, 长期记忆检索 |
for Hoshu Chiu & Everjoy Chiu 🐕 Just have fun with Everjoy.