# M4 module-ai SpacetimeDB 基座记录(2026-04-21) 更新时间:`2026-04-21` ## 0. 文档目标 本文件只记录一件事: **把 `module-ai` 从“只有领域模型和内存态服务”推进到“SpacetimeDB 侧已有最小 AI 任务真相表与 procedure 骨架”的真实落地结果。** 本轮只做最小可编译基座,不扩到真实模型请求、SSE 输出或前端订阅联调。 --- ## 1. 本轮落地范围 本轮只落实下面 5 件事: 1. 在 `server-rs/crates/module-ai/` 中补齐面向 `SpacetimeDB` 接线的输入类型。 2. 在 `server-rs/crates/spacetime-module/` 中新增 `ai_task / ai_task_stage / ai_text_chunk / ai_result_reference` 四张 private 表。 3. 在 `spacetime-module` 中新增 AI 任务的最小 reducer / procedure。 4. 把 `module-ai` 的领域快照与 `SpacetimeDB` 行结构之间的转换 helper 固定下来。 5. 补充 crate README 与技术索引,明确当前 AI 真相源边界。 --- ## 2. 新增的真实工程落点 ### 2.1 `module-ai` 1. `server-rs/crates/module-ai/src/lib.rs` - 补充 `AiTaskStartInput` - 补充 `AiTaskStageStartInput` - 补充 `AiTextChunkAppendInput` - 补充 `AiResultReferenceInput` - 补充 `AiTaskFinishInput` - 补充 `AiTaskCancelInput` - 补充 `AiTaskFailureInput` - 补充 `AI_TASK_STAGE_ID_PREFIX` - 补充 `AiTaskStageKind::as_str()` - 补充 `generate_ai_task_stage_id()` ### 2.2 `spacetime-module` 1. `server-rs/crates/spacetime-module/src/lib.rs` - 新增 `ai_task` - 新增 `ai_task_stage` - 新增 `ai_text_chunk` - 新增 `ai_result_reference` - 新增 `create_ai_task` - 新增 `create_ai_task_and_return` - 新增 `start_ai_task` - 新增 `start_ai_task_stage` - 新增 `append_ai_text_chunk_and_return` - 新增 `complete_ai_stage_and_return` - 新增 `attach_ai_result_reference_and_return` - 新增 `complete_ai_task_and_return` - 新增 `fail_ai_task_and_return` - 新增 `cancel_ai_task_and_return` --- ## 3. 当前冻结的数据口径 ### 3.1 `ai_task` 当前首版字段冻结为: 1. `task_id` 2. `task_kind` 3. `owner_user_id` 4. `request_label` 5. `source_module` 6. `source_entity_id` 7. `request_payload_json` 8. `status` 9. `failure_message` 10. `latest_text_output` 11. `latest_structured_payload_json` 12. `version` 13. `created_at` 14. `started_at` 15. `completed_at` 16. `updated_at` 当前策略: 1. `ai_task` 只保留任务级聚合字段,不在单行内嵌套 `Vec`。 2. 阶段、增量文本、结果引用全部拆到独立表,避免后续更新整行大对象。 3. `version` 继续沿用 `module-ai` 的任务快照版本语义。 ### 3.2 `ai_task_stage` 当前首版字段冻结为: 1. `task_stage_id` 2. `task_id` 3. `stage_kind` 4. `label` 5. `detail` 6. `order` 7. `status` 8. `text_output` 9. `structured_payload_json` 10. `warning_messages` 11. `started_at` 12. `completed_at` 当前策略: 1. 一条 stage 一行。 2. `task_stage_id` 使用 `generate_ai_task_stage_id(task_id, stage_kind)`,保持同任务内幂等。 3. 当前不单独存“阶段版本”,统一归任务版本递增。 ### 3.3 `ai_text_chunk` 当前首版字段冻结为: 1. `text_chunk_row_id` 2. `chunk_id` 3. `task_id` 4. `stage_kind` 5. `sequence` 6. `delta_text` 7. `created_at` 当前策略: 1. `chunk_id` 保留领域侧 ID 语义。 2. 表级主键使用 `text_chunk_row_id`,避免 `generate_ai_text_chunk_id(seed, sequence)` 在不同任务之间碰撞。 3. 流式文本聚合结果仍写回 `ai_task_stage.text_output` 和 `ai_task.latest_text_output`。 ### 3.4 `ai_result_reference` 当前首版字段冻结为: 1. `result_reference_row_id` 2. `result_ref_id` 3. `task_id` 4. `reference_kind` 5. `reference_id` 6. `label` 7. `created_at` 当前策略: 1. `result_ref_id` 保留领域侧 ID 语义。 2. 表级主键使用 `result_reference_row_id`,避免只按时间种子生成的领域 ID 在并发情况下直接作为主键带来碰撞风险。 --- ## 4. 当前 reducer / procedure 口径 ### 4.1 `create_ai_task` 当前负责: 1. 校验 `AiTaskCreateInput` 2. 拒绝重复 `task_id` 3. 写入 `ai_task` 4. 按蓝图写入 `ai_task_stage` ### 4.2 `start_ai_task` 当前负责: 1. 校验目标任务存在 2. 把 `ai_task.status` 从 `Pending` 推进到 `Running` 3. 填充 `started_at` ### 4.3 `start_ai_task_stage` 当前负责: 1. 校验目标任务与目标阶段存在 2. 推进任务为 `Running` 3. 推进对应 stage 为 `Running` ### 4.4 `append_ai_text_chunk_and_return` 当前负责: 1. 校验任务与阶段存在 2. 追加 `ai_text_chunk` 3. 按 `task_id + stage_kind + sequence` 聚合文本 4. 回写 `ai_task_stage.text_output` 5. 回写 `ai_task.latest_text_output` ### 4.5 `complete_ai_stage_and_return` 当前负责: 1. 更新 stage 状态、阶段输出、warning 列表 2. 回写 `ai_task.latest_text_output` 3. 回写 `ai_task.latest_structured_payload_json` 4. 递增任务版本 ### 4.6 `attach_ai_result_reference_and_return` 当前负责: 1. 追加 `ai_result_reference` 2. 更新任务 `updated_at` 3. 递增任务版本 ### 4.7 `complete_ai_task_and_return` 当前负责: 1. 推进任务为 `Completed` 2. 填充 `completed_at` ### 4.8 `fail_ai_task_and_return` 当前负责: 1. 推进任务为 `Failed` 2. 写入 `failure_message` 3. 填充 `completed_at` ### 4.9 `cancel_ai_task_and_return` 当前负责: 1. 推进任务为 `Cancelled` 2. 填充 `completed_at` --- ## 5. 当前刻意未做 本轮明确没有扩到以下范围: 1. 还没有做 AI 任务公开订阅表。 2. 还没有做 `api-server` 的 AI facade 路由。 3. 还没有做 `platform-llm` 真实流式回调接线。 4. 还没有做 story / custom-world / quest / runtime-item 对 AI 任务的自动建链。 5. 还没有做清理旧任务、旧 chunk 的 schedule reducer。 也就是说,本轮只是把 AI 任务真相表和最小写入口立起来,不宣称已经完成 AI runtime 主链迁移。 --- ## 6. 当前边界判断 当前仍保持以下职责划分: 1. `module-ai` - 负责领域模型、校验、快照结构与最小内存服务。 2. `spacetime-module` - 负责任务真相表、事务性持久化与 procedure 聚合返回。 3. `platform-llm` - 后续负责真实模型调用、超时、重试、供应商错误。 4. `api-server` - 后续负责 HTTP / SSE / 鉴权与外部 contract。 --- ## 7. 下一步建议 按当前节奏,后续应继续按下面顺序推进: 1. 先把 `platform-llm` 的文本网关正式接到 `append_ai_text_chunk_and_return / complete_ai_stage_and_return`。 2. 再给 `api-server` 增加 AI 任务 facade,把 HTTP/SSE 对外 contract 冻结下来。 3. 再把 story、custom-world、quest、runtime-item 各自的 AI 编排入口切到 `module-ai + spacetime-module`。 4. 最后再根据订阅需求评估是否补 public projection 表或事件表。