forked from admin/PlantAI-rag-new
- paper_writer_service(8097):FastAPI + MCP streamable-http 单端点,9 工具
(propose_paper_outline/write_paper_section/get_paper_progress/search_refs/
revise_paper_section/revise_paper/get_paper/complete_paper/cancel_paper),
SQLite 三表(papers/paper_sections/citations,WAL),GB/T 7714 引用协议
- BFF:services/paper/{mcp_client,agent}.py(裸 JSON-RPC 客户端 + 规则状态机)、
routers/paper.py、schemas.py 4 个 Paper*Block + ArtifactBlock 加 paper_id/citation_count、
config.py 开关、main.py 条件注册、docgen.py 抽 insert_artifact 公共 helper
- 前端:intent.js paperIntent 纯函数、Composer docgen 分支 sub-route、sendPaper/轮询、
PaperBriefCard/PaperOutlineCard/PaperProgressCard、DocPane cite-chip
- deploy/paper_restart.sh + toggle_paper.sh;compile_sdk.sh 白名单追加 paper 文件
- tests/paper 26 条(工具逻辑 + MCP 协议 + BFF 状态机 + 块 schema + 前端 intent 单测)
54 lines
1.5 KiB
Python
54 lines
1.5 KiB
Python
"""config.py —— paper 服务(8097)环境变量驱动配置(pydantic-settings)。
|
||
|
||
全部键可用环境变量覆盖(前缀 PAPER_;LLM 沿用 docgen 的 DOCGEN_LLM_* 直连模式,
|
||
由 services/paper/llm.py 直接读 os.environ)。零硬编码宿主路径:相对路径按 __file__ 推导。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from functools import lru_cache
|
||
from pathlib import Path
|
||
|
||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||
|
||
_SERVICE_ROOT = Path(__file__).resolve().parent.parent # paper_writer_service/
|
||
|
||
|
||
def _resolve(v: str) -> str:
|
||
"""仓库内相对路径按 __file__ 推导服务根解析为绝对路径。"""
|
||
p = Path(v).expanduser()
|
||
if not p.is_absolute():
|
||
p = _SERVICE_ROOT / p
|
||
return str(p)
|
||
|
||
|
||
class Settings(BaseSettings):
|
||
model_config = SettingsConfigDict(
|
||
env_file=".env",
|
||
env_file_encoding="utf-8",
|
||
extra="ignore",
|
||
env_prefix="PAPER_",
|
||
)
|
||
|
||
app_name: str = "plantai-paper-writer-service"
|
||
version: str = "0.1.0"
|
||
|
||
db_path: str = "paper.db" # 独立 SQLite(与 BFF 完全隔离)
|
||
vstore_base_url: str = "http://127.0.0.1:8094"
|
||
read_timeout: float = 360.0 # write_paper_section 同步长调用读超时
|
||
|
||
@property
|
||
def db_path_abs(self) -> str:
|
||
return _resolve(self.db_path)
|
||
|
||
@property
|
||
def vstore_base(self) -> str:
|
||
return self.vstore_base_url.rstrip("/")
|
||
|
||
|
||
@lru_cache(maxsize=1)
|
||
def get_settings() -> Settings:
|
||
return Settings()
|
||
|
||
|
||
settings = get_settings()
|