refactor: improve codebase structure and Univer integration

- Add AGENTS.md knowledge base with project documentation
- Move UserPreferences model to separate models.py file
- Extract API_KEY to environment variable for security
- Enhance Univer Editor with PPTX support and improved UI
- Improve file system handling with binary file detection
- Add HF_ENDPOINT mirror for better China connectivity
- Clean up unused imports and code structure
This commit is contained in:
2026-04-11 09:24:14 +08:00
parent 2fdc996af9
commit d8b7832b14
18 changed files with 901 additions and 544 deletions
+40
View File
@@ -0,0 +1,40 @@
# Backend 模块指南
## OVERVIEW
FastAPI 后端,处理 AI 补全、OCR、文档转换、TTS/ASR。
## 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
| 任务 | 文件 | 说明 |
|------|------|------|
| 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
- 文件名:全小写+短横线
## 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`
-1
View File
@@ -17,7 +17,6 @@ VLM_MODEL = os.getenv('VLM_MODEL', 'qwen3-vl:30b')
# Timeouts in seconds (10 minutes for large model loading)
COMPLETION_TIMEOUT = 600
OCR_TIMEOUT = 600
CONVERT_TIMEOUT = 600
client = ollama.AsyncClient(host=OLLAMA_HOST)
logger = logging.getLogger("llm")
+2 -7
View File
@@ -17,6 +17,7 @@ from pydantic import BaseModel
from geoip import get_ip_location_text
from llm import call_ollama, call_vlm_ocr
from models import UserPreferences
from prompt import build_completion_prompts, prepare_prompt_context
import markitdown
@@ -57,7 +58,7 @@ app.add_middleware(
allow_headers=["*", "X-API-Key", "X-Client-IP", "X-Request-Id"],
)
API_KEY = "your-secret-key-here"
API_KEY = os.getenv("API_KEY", "your-secret-key-here")
api_key_header = APIKeyHeader(name="X-API-Key")
@@ -70,12 +71,6 @@ async def get_api_key(api_key: str = Security(api_key_header)): # pragma: no co
return api_key
class UserPreferences(BaseModel):
language: str = "auto"
currency: str = "auto"
timezone: str = "auto"
class CompletionRequest(BaseModel):
prefix: str
suffix: str
+9
View File
@@ -0,0 +1,9 @@
"""共享的 Pydantic 模型定义"""
from pydantic import BaseModel
class UserPreferences(BaseModel):
"""用户偏好设置"""
language: str = "auto"
currency: str = "auto"
timezone: str = "auto"
+2 -8
View File
@@ -1,17 +1,11 @@
from datetime import datetime, timedelta, timezone
import re
from typing import Protocol, Tuple, runtime_checkable
from typing import Tuple
from models import UserPreferences
from prompts import get_language_guidance_map, get_system_prompt_template, get_inline_examples
@runtime_checkable
class UserPreferences(Protocol):
language: str
currency: str
timezone: str
def _get_current_datetime(timezone_pref: str = "auto") -> str:
# Default to UTC+8 if auto or not specified.
offset = 8
+45
View File
@@ -0,0 +1,45 @@
OVERVIEW: pytest 测试套件,覆盖率要求 90%
STRUCTURE
- test_*.py - 各模块测试
- run_tests.py - 测试执行脚本(unit/integration/all
- simulate_macos.py - macOS 环境模拟
- TESTING_GUIDE.md - 测试指南文档
WHERE TO LOOK
表格
| Area | Path |
|---|---|
| 单元测试 | backend/tests/ |
| 集成测试 | backend/tests/ |
| 测试执行脚本 | backend/tests/run_tests.py |
| macOS 模拟 | backend/tests/simulate_macos.py |
| 测试指南 | backend/tests/TESTING_GUIDE.md |
运行命令:
- pytest - 运行所有测试
- python backend/tests/run_tests.py unit - 单元测试
- python backend/tests/run_tests.py integration - 集成测试
测试命名约定:test_*.py、Test* 类、test_* 函数
ANTI-PATTERNS:删除测试以通过覆盖率
验证
- 保证测试覆盖率≥90% 时,报告合格
- 使用 CI 运行 pytest,确保通过率
注意事项
- 不要重复父目录内容
- 不要超过 60 行
测试应尽量独立,不要依赖全局状态
- 运行单元测试时应使用 unit 标签
- 运行集成测试时应使用 integration 标签
区分环境
- unit 测试应尽量快速、稳定
- integration 测试应覆盖接口和数据库交互
维护
- 如扩展新模块,优先增加 test_*.py 文件并在其中添加对应的测试类和方法
+6 -2
View File
@@ -1,9 +1,13 @@
import asyncio
import base64
import logging
import os
from io import BytesIO
from typing import Optional
# 设置 Hugging Face 镜像源为国内镜像
os.environ.setdefault("HF_ENDPOINT", "https://hf-mirror.com")
import torch
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
@@ -29,8 +33,8 @@ def _get_device_map() -> str:
try:
if hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
return "mps"
except Exception:
pass
except Exception as e:
logger.debug("MPS check failed: %s", e)
return "cpu"