Interaction:提交、结算与续跑
从用户提交到恢复执行
Interaction 定义 pending、resolved、cancelled、expired、failed。一次 settlement attempt 有独立状态,所以提交失败或重试不能直接解释为整个 Interaction 重开。客户端携带版本提交,服务端校验当前权威状态。
accepted 的关键是把 settlement 与持久化 resume intent 交接起来,再由 owner 恢复执行。终态不可重开。桌面上的输入草稿、按钮位置和收件箱展示只影响交互体验,不拥有业务迁移权。Business effect batch 保留一次明确业务意图下的有界成员集合:根 ActionProposal 保存范围,Interaction 只结算这一份授权;成员 proposal 不是可独立发现的待授权请求,也不是第二个 Interaction Kernel。
材料全家桶(Save As / batch / critical-fields / inbox vs Kernel / 聊天附件):见 ../interaction-materials/NOTES.md。
Interaction Protocol v2 ↔ Local File V5 附件交接
- 前置:migration 113(
conversation_interactions.protocol_version IN (1,2),schema identityinteraction-protocol-v2)是 mig 114(对话级附件列)的硬前置;114 再前置 115。附件 schema 升级叠在 Interaction v2 清仓之后,不是并行无关变更。 - 附件 vs Interaction:对话附件走 chat 提交路径——
chat-submission-store在同一事务写入 user message 后LocalFileMessageAttachmentStore.insertSubmitted;后续 run 组装用listForConversation(ADR-0079)。这是 conversation/message relation + operation ledger,不是 Interaction Kernel 的 settlement 对象。 - 交叉点:Local File 的 Save As / change authorize 以 Interaction producer 注册(
local_file_save_as、local_file_change类),kind 如local_file_save_as_v4;它们挂在 Kernel protocol v2 上,与「对话级 path-free 附件行」分层——前者是人机门/材料收集,后者是聊天上下文里的 folder/file relation。 - 协议门:Interaction API 用头
Aida-Interaction-Protocol-Version;未接受则426 interaction_protocol_upgrade_required。Desktop 协议 v3 的426 DESKTOP_UPGRADE_REQUIRED是另一扇门(见desktop-runtime);Interaction Kernel 协议仍是 2,与 Desktop 协议 3 互不相干。
钉点:aida-agent e2adc9a3c325a258a88d68103de87e6630a3b676。
业务复核卡改由后台 owner 执行(2026-10-14 钉点)
business_effect / business_progress 加入 BACKGROUND_OWNED_RESUME_BINDINGS:结算后由后台 owner 经 dispatchExact 立即执行,响应 transport=background;此前继承 attended_stream,需等 outbox 周期 drain(≤60s),点卡片与打字确认两条路径不一致(ADR-0089)。
卡过期后原任务怎么收口(钉点 Agent e2adc9a3c325 · Desktop 8eecd12081db)
expired 是 Interaction 终态,但它等着的那个任务树原来会一直挂着。现在两端各有收口:Agent 在新消息受理时(以及会话 lease 恢复,只限 legacy)关闭「只等过期卡」的任务树,判定 fail-closed;Desktop 的过期卡提供「结束原任务」,只停这张卡绑定的原始 Root(Runtime Work 走 Main 持久 Stop,legacy 沿用 cancel),对话已被别的工作占用时不停任何任务。细节见 state-authority 与 desktop-client。
四表结算与 Outbox 精确唤醒微追踪(视图 kernel-settlement-outbox)
当模型调用 ask_user / plugin_view / file_access / route_clarification 挂起载体后,用户点击卡片提交答复的完整 4 表状态机流转如下(见视图 kernel-settlement-outbox):
| 阶段 | 核心函数与 SQL 表 | 状态跳变与不变量校验 |
|---|---|---|
| 1. 策略校验与 Begin | InteractionKernel.settle (kernel.ts L776–821) → store.beginSettlement |
1) 解析 actorDecision(若为 client_resource 或 local_file_access 则额外调 isVerifiedClientResourceSettlement 验签);<br>2) conversation_interactions 必须处于 lifecycle_status = 'pending',插入 conversation_interaction_settlement_attempts (attempt_status = 'submitting', interaction_version = v, payload_hash);<br>3) 若交互已非 pending,alreadyWritten 检查最近一条 accepted attempt 是否同 actorRef + 同 payloadHash,命中则返回 status: 'duplicate' 幂等放行。 |
| 2. 领域验证与 Complete | validateSubmittedAnswerWithDeadline + authorityCoordinator.verify → store.completeSettlement (kernel.ts L828–874) |
1) 校验 resolution.actorPolicyVersion === actorDecision.policyVersion;<br>2) 在同一事务中将 conversation_interactions 推进至 lifecycle_status = 'resolved', version = v + 1,将 conversation_interaction_settlement_attempts 置为 attempt_status = 'accepted';<br>3) 同时写入 conversation_interaction_resume_commands(command_id = attempt_id, owner_kind = 'runtime_work_activation', status = 'pending', 冻结 destination)与 conversation_interaction_outbox。 |
| 3. 冻结目的地 3 表 Join 唤醒 | activateRuntimeWorkFromAcceptedSettlement (run-work-control.ts L3398–3583) |
1) lockRoot 下执行 3 表 Join(conversation_interaction_resume_commands c ⋈ conversation_interaction_settlement_attempts a ⋈ conversation_interactions i);<br>2) 强制校验五项铁律:a.attempt_status === 'accepted'、i.lifecycle_status === 'resolved'、a.interaction_version + 1 === i.version(严防过期修订覆盖)、canonicalJsonSha256(i.envelope.resumeDestinationBinding) === canonicalJsonSha256({kind, rootRunId, targetPosition})(创建时冻结的目的地必须与结算时一致)、以及 run_checkpoints.pending_interaction_id === interactionId;<br>3) 调 settleRuntimeWorkInteractionInTx 写入交互结算消息并更新 message_cursor_id;将 agent_runs 置为 status = 'pending'、runtime_invocations 置为 'pending'、run_checkpoints 置为 `status = 'active', resume_point = 'settlement:<settlementId>' |
| 4. 死信与失败隔离 | recoverRuntimeWorkChildInteraction (run-work-control.ts L3283–3389) |
若子交互唤醒遭遇永久错误或重试耗尽,在 lockRoot 下同步关闭 conversation_interaction_resume_commands 与 conversation_interaction_outbox(均置 dead_letter),防止崩溃重启后死信复活。 |
证据与范围
-
aida-agent·packages/agent/src/shared/interaction-kernel-state.tsL11–41 ·INTERACTION_STATUSES·e2adc9a3c325 -
aida-agent·docs/architecture/lifecycle-map.mdL42–98 ·e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT) -
aida-agent·docs/architecture/lifecycle-map.mdL110–198 ·e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT) -
aida-agent·packages/agent/src/shared/interaction-kernel-state.tsL137–157 ·e2adc9a3c325 -
aida-agent·packages/agent/src/session/chat-submission-store.tsL541–556 ·closeRunsWaitingOnlyOnExpiredInteractions·e2adc9a3c325 -
aida-desktop·apps/desktop/src/chat/interaction-workbench/endOriginalWork.tsL33–74 ·endOriginalWorkForExpiredCard·4346d79eb364 -
aida-agent·CONTEXT.mdL858–863 ·Business effect batch·e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT) -
aida-agent·packages/agent/src/runtime/continuation/interaction-delivery-mode.tsL1–13 ·business_effect·e2adc9a3c325 -
aida-agent·packages/agent/src/interaction-kernel/contract.tsL24–54 ·CONVERSATION_INTERACTION_PROTOCOL_VERSION·e2adc9a3c325 -
aida-agent·packages/agent/migrations/113_interaction_protocol_v2.sqlL1–28 ·113·e2adc9a3c325 -
aida-agent·packages/agent/migrations/114_local_file_v5_conversation_attachments.sqlL1–8 ·114·e2adc9a3c325 -
aida-agent·packages/agent/src/session/chat-submission-store.tsL1742–1782 ·insertSubmitted·e2adc9a3c325 -
aida-agent·packages/agent/src/interaction-kernel/producer-inventory.tsL17–47 ·local_file_save_as·e2adc9a3c325
结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。