- Replace overlay-based GhostTextOverlay.vue with ProseMirror Mark system - Add AI toggle button with enable/disable functionality - Implement new copilotPlugin.ts using copilotGhostMark for inline suggestions - Fix cursor position offset in prompt.py by moving first suffix char to prefix - Improve API error handling with abort signal support and debug logging - Update model configuration from gpt-oss:120b to gpt-oss:20b - Add button tooltips and improve editor styling - Remove deprecated inlineSuggestionPlugin.ts - Update README with new architecture diagram and feature documentation
3.1 KiB
3.1 KiB
LLM in Text - 智能写作助手
基于 Vue3 和 FastAPI 的智能 Markdown 编辑器,集成大语言模型(LLM)实时补全建议功能。
功能特性
Markdown 编辑器
- 基于 Milkdown Crepe 的所见即所得编辑体验
- 支持完整 Markdown 语法和 LaTeX 公式
- 导入/导出 Markdown 文件
AI 智能补全
- 实时生成文本补全建议(灰色显示)
- 流式响应,低延迟体验
- 多种交互方式:
- Tab 键:接受建议
- Esc 键:拒绝建议
- 点击灰色文本:接受建议
- 继续输入:自动拒绝建议
AI 开关控制
- 右下角 AI 开关按钮
- 白色 = AI 启用,黑色 = AI 禁用
- 禁用时自动清除灰色文本并停止 API 调用
技术架构
flowchart LR
subgraph Frontend
A[Vue3] --> B[Milkdown Editor]
B --> C[ProseMirror Plugin]
C --> D[Ghost Text Mark]
end
subgraph Backend
E[FastAPI] --> F[LLM API]
F --> G[Stream Response]
end
D -->|SSE| E
G -->|text| D
项目结构
llm-in-text/
├── src/
│ ├── components/
│ │ └── MilkdownEditor.vue # 主编辑器组件
│ ├── plugins/
│ │ └── copilotPlugin.ts # ProseMirror AI 补全插件
│ ├── utils/
│ │ ├── api.js # API 调用封装
│ │ └── config.js # 配置文件
│ ├── App.vue
│ └── main.js
├── backend/
│ ├── main.py # FastAPI 服务器
│ ├── llm.py # LLM API 调用
│ ├── prompt.py # Prompt 构建
│ └── requirements.txt
└── README.md
快速开始
环境要求
- Node.js 18+
- Python 3.8+
- OpenAI API Key 或 Ollama 服务
安装
# 前端
npm install
# 后端
cd backend
pip install -r requirements.txt
配置
在 backend/.env 中配置:
OPENAI_API_KEY=your_api_key
OLLAMA_BASE_URL=http://localhost:11434/v1/
OLLAMA_MODEL=gpt-4
启动
# 后端(端口 8000)
cd backend
python main.py
# 前端(端口 5173)
npm run dev
API 接口
POST /v1/completions
流式获取补全建议
请求:
{
"prefix": "# Title\n\nContent ",
"suffix": "",
"languageId": "markdown"
}
响应(SSE):
data: {"content": "here"}
data: {"content": "here is"}
data: {"done": true}
核心实现
ProseMirror Mark 系统
使用 ProseMirror 的 Mark 系统实现灰色建议文本:
// 定义 ghost mark
export const copilotGhostMark = $markSchema('copilot_ghost', () => ({
excludes: '_',
inclusive: true,
toDOM: () => ['span', {
'data-copilot-ghost': '',
class: 'copilot-ghost-text'
}, 0]
}))
// CSS 样式
.copilot-ghost-text {
color: #999;
opacity: 0.6;
}
交互处理
- 点击灰色文本区域:接受建议(移除 mark,保留文本)
- 点击其他区域:拒绝建议(删除灰色文本)
- Tab 键:接受建议
- Esc 键:拒绝建议
许可证
MIT License