feat: enhance Milkdown editor and file system functionality
- Normalize line endings in Markdown export for DOCX files. - Improve selection serialization to Markdown with better handling of empty documents. - Add a new `updateFile` function to the file system for updating file properties. - Introduce video transcoding capabilities using FFmpeg, supporting various video formats. - Update AGENTS.md for clearer plugin structure and responsibilities. - Add scoped styles for TreeNodeItem component to improve UI consistency. - Implement cross-origin isolation headers in Vite configuration for enhanced security. - Remove obsolete test_cross.py file.
This commit is contained in:
+114
-33
@@ -1,40 +1,121 @@
|
||||
# Backend 模块指南
|
||||
# Backend 后端指引
|
||||
|
||||
## OVERVIEW
|
||||
FastAPI 后端,处理 AI 补全、OCR、文档转换、TTS/ASR。
|
||||
本文件适用于 backend/ 下的后端实现。进入 backend/tests/ 后,以子目录 AGENTS.md 为准。
|
||||
|
||||
## STRUCTURE
|
||||
- main.py - API 入口、路由、CORS、启动逻辑
|
||||
- llm.py - Ollama 异步调用、超时控制、日志
|
||||
- prompt.py - Prompt 构建、上下文准备、语言处理
|
||||
- geoip.py - IP 地理位置查询
|
||||
- tts_asr.py - TTS/ASR 处理、Apple Silicon 优化
|
||||
- prompts/ - JSON 格式提示模板(PromptManager 单例)
|
||||
- tests/ - pytest 测试套件(见子目录 AGENTS.md)
|
||||
## 后端职责
|
||||
|
||||
## WHERE TO LOOK
|
||||
- 对外提供补全、取消补全、OCR、文档转换和 TTS 相关接口。
|
||||
- 组织 Prompt,上下文清洗,调用 Ollama 模型。
|
||||
- 负责 API Key 校验、日志记录和部分启动预热逻辑。
|
||||
|
||||
| 任务 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| API 路由定义 | main.py | /v1/completions、/v1/ocr、/v1/convert 等 |
|
||||
| LLM 调用封装 | llm.py | call_ollama、call_vlm_ocr、超时控制 |
|
||||
| Prompt 构建 | prompt.py | build_completion_prompts、语言处理 |
|
||||
| 提示模板 | prompts/__init__.py | PromptManager、JSON 模板加载 |
|
||||
| TTS/ASR | tts_asr.py | 模型预热、设备检测、音频处理 |
|
||||
| 测试 | tests/ | pytest 测试套件 |
|
||||
## 先看哪里
|
||||
|
||||
## CONVENTIONS
|
||||
- Python 4 空格缩进
|
||||
- 函数/变量:snake_case
|
||||
- 类:PascalCase
|
||||
- 文件名:全小写+短横线
|
||||
- API 入口和路由:main.py
|
||||
- Ollama 调用封装:llm.py
|
||||
- Prompt 清洗和拼装:prompt.py
|
||||
- 数据模型:models.py
|
||||
- 地理位置:geoip.py
|
||||
- TTS 路由:tts_asr.py
|
||||
- Prompt 模板:prompts/
|
||||
- 后端测试:tests/
|
||||
|
||||
## ANTI-PATTERNS
|
||||
- 硬编码 API_KEY(必须从环境变量读取)
|
||||
- 空 catch 块
|
||||
- 类型错误使用 as any / @ts-ignore
|
||||
## 当前接口面
|
||||
|
||||
## 注意事项
|
||||
- 端口:8001
|
||||
- 启动:`python backend/main.py` 或 `uvicorn backend.main:app --reload`
|
||||
- 依赖:`pip install -r backend/requirements.txt`
|
||||
- POST /v1/completions
|
||||
- POST /v1/completions/cancel
|
||||
- POST /v1/ocr
|
||||
- POST /v1/convert
|
||||
- /v1/tts-asr/* 由 tts_asr.py 延迟注册
|
||||
|
||||
## 请求流转
|
||||
|
||||
### /v1/completions
|
||||
|
||||
- 读取或生成 request_id。
|
||||
- privacy_mode 为 false 时,尝试根据客户端 IP 生成 location 文本。
|
||||
- 调用 prepare_prompt_context 清洗 prefix 和 suffix。
|
||||
- 调用 build_completion_prompts 生成 system_prompt 和 user_prompt。
|
||||
- 创建异步任务调用 call_ollama。
|
||||
- 用 request_id 把任务登记到 ACTIVE_COMPLETIONS。
|
||||
- 成功时返回 JSON:content 和 request_id。
|
||||
- finally 中清理当前 request_id 对应任务。
|
||||
|
||||
### /v1/completions/cancel
|
||||
|
||||
- 通过 request_id 在 ACTIVE_COMPLETIONS 中查找任务。
|
||||
- 未找到返回 not_found。
|
||||
- 已完成返回 already_done。
|
||||
- 仍在执行则调用 task.cancel() 并返回 ok。
|
||||
|
||||
### /v1/ocr
|
||||
|
||||
- 把 base64 图片解码成字节。
|
||||
- 调用 call_vlm_ocr。
|
||||
- 返回识别文本和原始文件名。
|
||||
|
||||
### /v1/convert
|
||||
|
||||
- 接收 base64 文件内容和文件名。
|
||||
- 当前允许的扩展名只有 txt、docx、pptx、pdf。
|
||||
- txt 直接解码后清洗。
|
||||
- 其他格式写入临时文件,用 MarkItDown 转换,再做 Markdown 清洗。
|
||||
- 清洗逻辑会移除图片 Markdown 和 img HTML 标签,并压缩多余空行。
|
||||
|
||||
### /v1/tts-asr/*
|
||||
|
||||
- 通过 _register_tts_asr_routes 延迟导入并挂到主应用。
|
||||
- 当前代码里的 tts_asr.py 主要是 TTS 能力,不要自行假设存在完整 ASR 实现。
|
||||
|
||||
## 开发命令
|
||||
|
||||
- 安装依赖:pip install -r backend/requirements.txt
|
||||
- 启动:python backend/main.py
|
||||
- 开发启动:uvicorn backend.main:app --reload --port 8001
|
||||
- 路由相关测试:
|
||||
- pytest backend/tests/test_main_endpoints.py -v
|
||||
- pytest backend/tests/test_main_cancel.py -v
|
||||
- Prompt 测试:
|
||||
- pytest backend/tests/test_prompt.py -v
|
||||
- pytest backend/tests/test_prompt_extended.py -v
|
||||
- LLM 测试:
|
||||
- pytest backend/tests/test_llm.py -v
|
||||
- pytest backend/tests/test_llm_extended.py -v
|
||||
|
||||
## 编码约定
|
||||
|
||||
- Python 使用 4 空格缩进。
|
||||
- 函数、变量使用 snake_case,类使用 PascalCase。
|
||||
- 新逻辑优先保留显式类型和明确的输入输出。
|
||||
- 异步边界要清晰;阻塞操作优先放进 asyncio.to_thread,而不是直接阻塞事件循环。
|
||||
- 异常要么转成 HTTPException,要么转成结构化 JSONResponse;不要静默吞掉后端错误。
|
||||
- 日志尽量带 request_id 或短 tag,便于把前后端一次请求串起来。
|
||||
|
||||
## 容易误判的点
|
||||
|
||||
- 补全接口当前不是流式响应,不要按 SSE 方式改造周边代码。
|
||||
- ACTIVE_COMPLETIONS 在补全和取消路径里都被读写,任务生命周期要谨慎处理。
|
||||
- main.py 里虽然有 _convert_docx_to_pdf 辅助函数,但当前 /v1/convert 路径实际走的是 MarkItDown,不要误以为 DOCX 转 PDF 桥接脚本已接入主流程。
|
||||
- API_KEY 存在占位默认值,这更像本地开发兜底,不是推荐的安全模式。
|
||||
- 历史 TTS/ASR 文档和部分测试覆盖的是旧实现;代码与文档冲突时,先确认产品方向,再决定修代码还是修文档。
|
||||
|
||||
## 改动时的定位建议
|
||||
|
||||
- 如果问题是补全结果不对,先查 prompt.py,再查 llm.py,不要只盯着 main.py。
|
||||
- 如果问题是取消不生效,先查 main.py 里的 request_id 生命周期,再对照前端的 X-Request-Id 和 cancel 调用。
|
||||
- 如果问题是 OCR 识别为空,先看 main.py 的 base64 解码,再看 llm.py 的 call_vlm_ocr。
|
||||
- 如果问题是转换结果脏,重点看 main.py 里的 _sanitize_converted_markdown。
|
||||
- 如果问题是 TTS 行为和文档不一致,以 tts_asr.py 为准,不要以 README 为准。
|
||||
|
||||
## 测试映射
|
||||
|
||||
- 路由主行为:tests/test_main_endpoints.py
|
||||
- 取消逻辑:tests/test_main_cancel.py
|
||||
- Prompt 逻辑:tests/test_prompt.py、tests/test_prompt_extended.py
|
||||
- LLM 包装层:tests/test_llm.py、tests/test_llm_extended.py
|
||||
- GeoIP:tests/test_geoip.py
|
||||
- TTS 相关:tests/test_tts_asr_*.py
|
||||
|
||||
## 文档使用原则
|
||||
|
||||
- README.md、TTS_ASR_MACOS_FIX.md、tests/TESTING_GUIDE.md 可以作为背景材料。
|
||||
- 一旦这些文档和 main.py、llm.py、prompt.py、tts_asr.py 冲突,以代码为准。
|
||||
|
||||
Reference in New Issue
Block a user