Skip to content

feat(runtime): 以《追书人》JSON 跑通完整游戏流程 (#124) - #125

Draft
LMH168 wants to merge 9 commits into
1024XEngineer:mainfrom
LMH168:codex/issue-124-paper-chase-runtime
Draft

feat(runtime): 以《追书人》JSON 跑通完整游戏流程 (#124)#125
LMH168 wants to merge 9 commits into
1024XEngineer:mainfrom
LMH168:codex/issue-124-paper-chase-runtime

Conversation

@LMH168

@LMH168 LMH168 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

关联 Issue

Closes #124

主要变更

  • 删除前端所有虚构模组和静态模组注册表,以后端加载成功的《追书人》ModulePackage JSON 为唯一模组来源。
  • 增加不可变 ScenarioRevision、Loader 校验、权利门禁、两张预制调查员和玩家安全 DTO。
  • 建立版本化 GameState、幂等命令、事件日志、服务端 COC7 技能与 SAN 检定、六种结局和结构化复盘。
  • 接入单 KeeperAgent 架构:默认使用确定性 Fake Keeper,并提供 OpenAI Agents SDK、SQLAlchemySession 和 DeepSeek 配置化适配器。
  • 接通 WebSocket GameView、行动提交、确认掷骰、重连补发、SDK 类型与前端完整运行页面。
  • 更新 E2E:删除对多人假模组和未实现复盘桩的依赖,改为验证《追书人》单人容量和真实运行协议。

方案与取舍

完整 ModulePackage 只在后端 Loader 和规则引擎中使用,前端仅接收玩家安全投影,以降低 Keeper 真相、隐藏 Fact 和未授予线索泄漏风险。所有状态变更、骰值、线索和结局统一由 ActionExecutor 执行,AI 只负责从 PlayerView 选择 Intent 和叙事,不具备直接改写状态的权限。

真实模型默认关闭,CI 和离线开发使用确定性 Fake Keeper;DeepSeek 通过 OpenAI-compatible Chat Completions 配置接入。这样先固定运行边界和测试,再进行真实模型人工联调。

测试与验证

  • 后端 Ruff 格式与规则检查通过。
  • 后端 ty 类型检查通过。
  • 后端 pytest:129 passed,1 条 Starlette TestClient 弃用警告。
  • SDK Schema 导出和 codegen 无漂移。
  • SDK typecheck、9 项测试和构建通过。
  • 前端 lint 与生产构建通过。
  • SDK→后端 E2E:21 passed。
  • Alembic 全新升级、降级、再次升级通过。
  • 浏览器纵切通过:选择《追书人》 → 选择预制人物 → 开局 → 技能检定 → 获得线索 → SAN → 和平结局 → 真实复盘。

兼容性、风险与回滚

  • 《追书人》当前标记为权利未确认的开发样例;开发和测试可显式加载,生产默认拒绝。
  • 数据库迁移新增 revision、会话、状态快照、幂等命令和 Agent 会话表。回滚时先停止相关房间,再执行对应 Alembic downgrade,并回退本 PR 提交。
  • WebSocket action.submit、check.roll、san.check.roll 增加请求 ID 和状态版本;旧客户端需要同步升级 SDK。
  • 真实 DeepSeek 模型尚未纳入 CI,仅保留配置化人工联调入口。

UI 证据

已在本地浏览器完成完整和平结局纵切并核对真实复盘页面;本 Draft PR 暂未附截图,合并前由人工评审再次确认模组列表、开场、房间与复盘页面。

AI 使用

本实现由 Codex 按 Issue #124 的既定方案协助完成。核心关注点包括 Loader 的引用与权利校验、权威规则执行、玩家安全投影、单 Agent 工具边界、WebSocket 幂等与版本冲突,以及端到端验收。Loader、规则引擎、Keeper 适配器和状态持久化属于核心模块,合并前必须由维护者逐段审查并确认可维护性。

自检

  • 变更范围与 Issue 一致。
  • 未包含无关代码或本地数据库备份。
  • 测试、迁移和生成产物已同步。
  • 未发现密钥、个人数据或意外产物。
  • 已完成 AI 辅助质量检查。
  • 已完成人工代码审查。
  • 已补充 UI 截图或录屏。

LMH168 and others added 2 commits July 15, 2026 15:01
- 前端 (trpg-app): Vite + React + TypeScript,集成 trpg-sdk
- 后端 (backend): FastAPI + SQLAlchemy + SQLite,RESTful CRUD
- SDK (sdk): TypeScript 客户端 SDK,对接后端 API
- 验证: Examples 端到端 CRUD 联调通过

Co-authored-by: LMH <LMH168@github.com>
# Conflicts:
#	.gitignore
#	README.md
#	backend/app/main.py
#	backend/pyproject.toml
#	backend/tests/test_health.py
#	trpg-app/package-lock.json
#	trpg-app/package.json
#	trpg-app/src/App.tsx
#	trpg-app/src/styles.css
#	trpg-backend/.env.example
#	trpg-backend/.python-version
#	trpg-backend/app/controller/v1/__init__.py
#	trpg-backend/app/controller/v1/examples.py
#	trpg-backend/app/controller/v1/health.py
#	trpg-backend/app/controller/v1/router.py
#	trpg-backend/app/core/config.py
#	trpg-backend/app/core/db.py
#	trpg-backend/app/core/errors.py
#	trpg-backend/app/core/logging.py
#	trpg-backend/app/crud/__init__.py
#	trpg-backend/app/crud/example.py
#	trpg-backend/app/models/__init__.py
#	trpg-backend/app/models/example.py
#	trpg-backend/app/schemas/__init__.py
#	trpg-backend/app/schemas/common.py
#	trpg-backend/app/schemas/example.py
#	trpg-backend/tests/conftest.py
#	trpg-backend/tests/test_examples.py
#	trpg-backend/uv.lock
#	trpg-frontend/.env.example
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@LMH168
LMH168 force-pushed the codex/issue-124-paper-chase-runtime branch from 6ce68b8 to 20efe81 Compare July 23, 2026 05:07
@LMH168 LMH168 changed the title feat(runtime): 以《追书人》JSON 跑通完整游戏流程 feat(runtime): 以《追书人》JSON 跑通完整游戏流程 (#124) Jul 23, 2026
Lyltrum added a commit to Lyltrum/TRPG-master that referenced this pull request Jul 23, 2026
参考 upstream PR 1024XEngineer#125 的协议思路(check_request_id 确认制),落地设计文档
01 的多轮闭环:

  action.submit → 裁决判定需要检定 → 不掷!进 pending 队列
    → 叙事写到'需要掷骰'为止 → 广播 narration.push + check.request
  玩家前端出现掷骰卡片 → 点击发 check.roll{checkRequestId}
    → 服务端权威掷 d100 → 广播 check.result → 结算叙事(复用 narrate(),
      裁决器在历史里看到结果,可链式追加理智检定) → narration.push

要点:
- Narrator 接口升级:narrate() 返回 NarrationOutcome{text, check_requests,
  check_results};新增 resolve_check()(默认 NotImplementedError,非 keeper
  模式回 NOT_IMPLEMENTED);Fallback/DeepSeek/Delayed 同步适配
- keeper/pending.py:进程内待掷队列(单进程取舍同 action_lock);narrate()
  的 pending 守卫——待掷期间的新行动被拦下并重发请求(防刷新丢卡片)
- decision.execute_decision 拆为 execute_side_effects(hp/state 立即执行) +
  create_pending_checks(解析不掷骰);tools 增 roll_check_detail/
  san_check_detail 结构化返回
- 协议:1024XEngineer#77 铺的 check.request/check.result/check.roll/san.check.* 六个
  槽位全部接上真实逻辑;CheckRollPayload 改为 checkRequestId 确认制;
  codegen 同步 SDK
- 前端:待掷卡片(掷骰按钮/rolling 态) + check.result 渲染成骰子消息 +
  假 DiceModal 按钮从主持人频道移除
- ws:check.roll 与 action.submit 共用房间锁;LLM 失败宽捕获(掷骰已落库
  时玩家重发行动可续上,不丢骰);错误码 CHECK_NOT_PENDING
- 锁不长占:待掷期间锁已释放,玩家慢慢决定,房间不卡(多轮闭环)

真实 DeepSeek 冒烟:发起待掷不出结果→守卫拦截生效→侦查 85/70 失败(核心
奖励未泄)→话术 31/60 成功给出墓碑位置(看守名字正确+态度入状态)。
pytest 191、ruff/format/ty 全绿、SDK build+9 test、前端 tsc/lint/build、
e2e 26/26。
@LMH168 LMH168 closed this Jul 24, 2026
@LMH168 LMH168 reopened this Jul 24, 2026
@WELT5350

Copy link
Copy Markdown
Contributor

此 PR 覆盖 60 个文件、8 个模块层,是完整单人游戏实现的纵向切片。当前 MS2 MVP 基线见 #100(单人闭环验证)。建议:1)添加 prototype 标签,标注为独立验证分支;2)在正文中说明哪些模块与 #111/#108 共享逻辑、哪些是独立实现;3)后续若合入主线,需按模块拆分为独立 PR。当前不作为 MS2 MVP 合入基线。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal:基于 OpenAI Agents SDK 使用预制调查员完整跑通《追书人》

2 participants