b55af1eff0
- Introduced `requirements.docker.txt` for Docker-specific dependencies. - Updated `requirements.txt` to include `psycopg[binary]` and `python-multipart`. - Enhanced test suite in `test_main_endpoints.py` to cover document CRUD operations. - Modified `docker-compose.yml` to include PostgreSQL and frontend services. - Added Nginx configuration for reverse proxying API requests. - Refactored file handling in Vue components to support new document storage backend. - Created new utility functions in `docsApi.js` for document management. - Updated configuration to support new API endpoints for document operations. - Adjusted Vite configuration to proxy API requests to the local backend.
8.7 KiB
8.7 KiB
LLM in Text 仓库指引
本文件适用于整个仓库。进入更深层目录后,子目录中的 AGENTS.md 优先于本文件。
项目定位
- 这是一个智能 Markdown 编辑器,前端负责编辑器 UI、上传导出、补全交互和设置状态,后端负责 LLM、OCR、文件转换和 TTS 接口。
- 前端技术栈:Vue 3 + Vite + Milkdown/Crepe + Pinia + Vue Router。
- 后端技术栈:FastAPI + Python + OpenAI-compatible LLM endpoint。
功能块系统(核心概念)
- 统一命名:文档块、PRO 块、上传块统称为"功能块"。
- 禁止嵌套:所有功能块的 schema 均设
atom: true, isolating: true,ProseMirror 层面强制禁止互相嵌套。DocBlockCrepe.vue 的嵌套 Crepe 编辑器不注册任何功能块插件,从架构上杜绝深层嵌套。 - 无数量限制:一篇文档可包含任意数量的功能块,彼此独立存在。
- 导入自动解析:从 Markdown 文件导入后,各功能块语法必须通过对应的 Remark/parseMarkdown 解析器自动识别并还原为交互卡片。
- 导出可复原:通过 toMarkdown/leafText 序列化器将功能块还原为 Markdown 语法,确保导出后再次导入能完整复原。doc_block toMarkdown 输出 legacy HTML tag,
getExportMarkdown()中通过transformLegacyDocBlocksForExport()转换为 fenced code block。
| 类型 | Node Type | Markdown 语法 | Plugin 文件 | Utility 文件 |
|---|---|---|---|---|
| 文档块 | doc_block |
```llm-file fenced code / <doc_type=...> legacy HTML tag |
plugins/docBlockPlugin.ts |
utils/docBlock.js |
| PRO 块 | pro_block |
[PRO] / [PRO]{指令} |
plugins/proBlockPlugin.ts |
utils/proBlock.js |
| 上传块 | upload_block |
{{{}}} / {{{upload file type:...}}} |
plugins/uploadBlockPlugin.ts |
utils/uploadBlock.js |
- 已验证:当前代码完全符合"禁止嵌套、自动解析复原"的要求。修改功能块相关逻辑时需验证:1) schema 的 atom/isolating 属性不被移除;2) Remark/parseMarkdown/toMarkdown 解析链路完整。
- 当前代码中可以确认的主功能是:AI 补全、OCR、文档转 Markdown、TTS、Markdown/DOCX/PDF 导入导出。
- 历史文档中有一部分 TTS/ASR、Apple Silicon、Whisper、离线模式说明已经落后于当前代码;出现冲突时以实际代码和测试为准。
先看哪里
- 项目概览和运行说明:README.md
- 前端入口:src/main.js
- 路由:src/router/index.js
- 编辑器主组件:src/components/MilkdownEditor.vue
- AI 补全核心:src/plugins/copilotPlugin.ts
- 前端请求层:src/utils/api.js
- 前端配置:src/utils/config.js
- 设置状态:src/stores/settings.js
- 后端入口和主路由:backend/main.py
- LLM 和 OCR 调用:backend/llm.py
- Prompt 组装:backend/prompt.py
- TTS 路由:backend/tts_asr.py
- 测试配置和入口:pytest.ini、backend/tests/run_tests.py
稳定事实
- 功能块禁止嵌套:
doc_block、pro_block、upload_block的 schema 均设atom: true, isolating: true,ProseMirror 层面强制禁止互相嵌套。DocBlockCrepe.vue 的嵌套 Crepe 编辑器仅注册 copilotPlugin + hiddenText*,不注册任何功能块插件。修改时不得移除 atom/isolating 属性或在嵌套编辑器中引入功能块插件。 - 功能块导入解析:各功能块的 Remark 插件(
docBlockRemark,proBlockRemark,uploadBlockRemark)负责从 Markdown AST 识别对应语法并转换为节点。doc_block Remark 同时支持 fenced code (llm-file) 和 legacy HTML tag (<doc_type=...>)。解析链路必须保持完整,否则导入后无法自动复原。 - 功能块导出序列化:doc_block 的
toMarkdownrunner 输出 legacy HTML tag,但getExportMarkdown()中通过transformLegacyDocBlocksForExport()转换为 fenced code block。pro_block/upload_block 的 toMarkdown/leafText 直接输出标准语法。修改时需验证导出后再次导入能完整复原。 - Store 同步格式:
scheduleMarkdownSync()emit markdown 不做转换(doc_block 为 legacy HTML tag),store 中始终是 legacy format。syncInitialMarkdown()/getExportMarkdown()负责格式转换。 - 上传块生命周期:upload_block 是临时占位符,文件上传后被替换为 image node(图片)或 doc_block(文档),不会与 pro_block 共存。
- PRO block escape/unescape:
escapeProBlockContent()/unescapeProBlockSyntax()处理\,],}, newline,确保指令 round-trip 正确。 - 补全接口当前不是 SSE;前端用普通 POST 请求拿 JSON 响应。
- 前端会生成 X-Request-Id,并在请求被中止时额外调用 /v1/completions/cancel。
- 文档超过 32 KB 时,AI 补全会在前端和插件层被禁用。
- OCR 文本和文档块内容会被注入补全上下文,但这些内容属于隐藏上下文,不应被直接当作用户可见文本重复输出。
- /v1/convert 当前支持 txt、docx、pptx、pdf,非 txt 文件通过 MarkItDown 转成 Markdown,之后会清理图片标记。
- 前端存在 /v1/export/pdf 调用点,但当前后端主路由中看不到同名端点;排查 PDF 导出问题前先确认服务端是否真正提供该接口。
- 当前 tts_asr.py 主要提供 TTS 相关能力。不要直接沿用 README 或历史修复文档里关于 ASR、Whisper、MPS/offline 的描述。
常用命令
- 前端安装:npm install
- 前端开发:npm run dev
- 前端构建:npm run build
- 后端安装:pip install -r backend/requirements.txt
- 后端启动:python backend/main.py
- 可选启动方式:uvicorn backend.main:app --reload --port 8001
- 全量测试:pytest
- 常用窄测试:
- pytest backend/tests/test_main_endpoints.py -v
- pytest backend/tests/test_main_cancel.py -v
- pytest backend/tests/test_prompt.py -v
- pytest backend/tests/test_llm.py -v
Docker 部署约定
- 本机部署目录固定在
/Volumes/New Volume/lit/下,不在仓库外再散落数据库或 Docker 持久化目录。 - 当前推荐的部署工作目录是
/Volumes/New Volume/lit/llm-in-text/;把仓库同步到该目录后,从该目录执行docker compose up -d --build。 - Docker 持久化数据统一落在部署目录内的
docker-data/,包括 PostgreSQL、Redis 和任务共享临时目录。 - 容器内访问宿主机模型服务时,不要继续使用
localhost;应改成host.docker.internal之类的容器可达地址。 - 当前 Docker 部署默认使用轻量后端依赖集(
backend/requirements.docker.txt),覆盖补全、OCR、转换、文档空间和队列,不默认包含本地torch/ TTS / ASR 模型栈。 - 修改 Docker 相关文件时,除了代码本身,还要同步检查:
docker-compose.ymlbackend/Dockerfilebackend/requirements.docker.txtDockerfile.frontenddocker/nginx.confbackend/.env.example与实际部署用backend/.env
代码约定
- 不要把整个仓库当成“全小写+短横线命名”项目。当前实际情况是:
- Vue 组件和视图多为 PascalCase
- 前端工具模块多为小写 .js
- 插件层使用 TypeScript
- Python 使用 snake_case
- 以就地风格为准,不要顺手做全仓格式统一。
- UI 文案和代理回复默认使用中文。
- 不要修改 milkdown-docs/,它是只读参考资料。
- 不要新增硬编码密钥、空 catch/except、as any、@ts-ignore 之类的扩散式技术债。
- 代理在这个仓库里应优先做局部、可验证的修改,不要做无关重构。
调试路径
-
补全问题: src/components/MilkdownEditor.vue -> src/plugins/copilotPlugin.ts -> src/utils/api.js -> backend/main.py -> backend/prompt.py / backend/llm.py
-
OCR 问题: src/components/MilkdownEditor.vue -> backend/main.py -> backend/llm.py
-
文档转换问题: src/utils/convert.js -> backend/main.py
-
TTS 问题: src/components/TTSMenu.vue / src/components/TTSPlayer.vue / src/components/MilkdownEditor.vue -> src/utils/api.js -> backend/tts_asr.py
测试和产物
- pytest.ini 对 backend.main、backend.llm、backend.prompt、backend.geoip、backend.prompts、backend.tts_asr 设了覆盖率门槛,低于 90% 会失败。
- 默认测试目录是 backend/tests。
- 常见生成产物包括 dist、htmlcov、.pytest_cache、api_performance_report.md;它们不是源代码。
文档注意事项
- README.md 对产品功能有参考价值,但其中补全、TTS/ASR 和部分接口说明已经比代码旧。
- backend/TTS_ASR_MACOS_FIX.md 和 backend/tests/TESTING_GUIDE.md 更适合作为历史背景,不应在与代码冲突时被当成事实来源。
- 修改行为时,优先参考实现代码和对应测试,再决定是否同步普通文档。