Files
life-echo/api/pyproject.toml
Kevin 69a673e6c6 feat(api): 访谈人格/回复长度策略、口述归一、背景语气与输入净稿全链路
Chat 访谈
- 新增 persona 系统(default / warm_listener / curious_guide)与 background_voice 语气层
- 回复长度由 compute_reply_plan 统一决策(brief / standard / expanded),融合信息密度启发式
- 输入净稿(input_normalize):编排层可选 rules/llm 归一用户口语后再喂模型与记忆检索
- 记忆证据注入:按用户话检索 memory evidence 并注入 prompt

Memoir 回忆录
- 口述归一(oral_normalize):segment 原文保留,story 管线取派生净稿作叙事输入
- segment 入队批次门闸:累计字数 + 最长等待秒数,减少零碎提交
- fidelity_check / prompts / narrative_agent 微调
- Alembic 0005:清理跨章节 story 外键

Infra
- Dockerfile 加入 ffmpeg
- pyproject.toml 新增依赖并同步 uv.lock
- .env.example / .env.production 补全新配置项

Tests
- 新增 test_background_voice、test_chat_input_normalize、test_experience_regressions
- 扩展 test_interview_prompts、test_interview_reply_length、test_story_route_oral_invariant

Made-with: Cursor
2026-03-31 23:55:26 +08:00

92 lines
2.0 KiB
TOML

[project]
name = "api"
version = "0.2.0"
description = "Backend For Life Echo App"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"alembic>=1.18.4",
"bcrypt>=5.0.0",
"celery[redis]>=5.6.2",
"cos-python-sdk-v5>=1.9.41",
"fastapi[standard]>=0.135.1",
"faster-whisper>=1.2.1",
"greenlet>=3.3.2",
"httpx>=0.28.1",
"langchain>=1.2.12",
"langchain-openai>=1.1.11",
"loguru>=0.7.3",
"openai>=2.26.0",
"pgvector>=0.4.2",
"pillow>=12.1.1",
"psycopg[binary]>=3.2.0",
"pydantic>=2.12.5",
"pydantic-settings>=2.13.1",
"pydub>=0.25.1",
"pyjwt>=2.12.0",
"python-alipay-sdk>=3.4.0",
"redis>=6.4.0",
"reportlab>=4.4.10",
"sqlalchemy>=2.0.48",
"tencentcloud-sdk-python>=3.1.54",
"weasyprint>=68.1",
"wechatpayv3>=2.0.2",
"zai-sdk>=0.2.2",
]
[dependency-groups]
dev = [
"aiosqlite>=0.22.1",
"pyright>=1.1.408",
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=7.0.0",
"ruff>=0.15.6",
]
[tool.ruff]
line-length = 88
target-version = "py313"
[tool.ruff.lint]
select = ["E", "F", "I", "B"]
ignore = ["E501", "B008", "E712"]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"main.py" = ["E402", "I001"]
"app/tasks/celery_app.py" = ["E402"]
"tests/conftest.py" = ["E402", "I001"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "auto"
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["."]
python_files = ["test_*.py"]
markers = [
"integration: marks tests that require external services or real infrastructure",
"unit: marks isolated unit tests",
"slow: marks slow-running tests",
]
addopts = "-ra --strict-markers --strict-config --import-mode=importlib"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
asyncio_default_test_loop_scope = "function"
[tool.pyright]
include = ["."]
exclude = [
"**/__pycache__",
".venv",
"build",
"dist",
]
pythonVersion = "3.13"
typeCheckingMode = "standard"
reportMissingImports = "error"
reportMissingTypeStubs = false