Skip to content

iter93 cluster-093: type card action workflow resume + LLM selection payloads#1005

Merged
loning merged 2 commits into
auto-refact-devfrom
iter93/cluster-093-card-action-typed
May 24, 2026
Merged

iter93 cluster-093: type card action workflow resume + LLM selection payloads#1005
loning merged 2 commits into
auto-refact-devfrom
iter93/cluster-093-card-action-typed

Conversation

@loning
Copy link
Copy Markdown
Contributor

@loning loning commented May 24, 2026

Summary

  • chat_activity.proto:加 WorkflowResumeActionPayload + LlmSelectionActionPayload typed sub-messages
  • arguments map 降级 open-extension-only
  • Lark / Telegram composer + FeishuCardHumanInteractionPort:emit typed payload(adapter JSON compat 在边界)
  • NyxIdRelayTransport.BuildCardActionSubmission:known JSON → typed sub-message
  • ChannelConversationTurnRunner + InboundMessage.Extra:workflow/LLM handoff typed access;literal-key 路径 deprecated inbound fallback only
  • ChannelCardActionRouting:消费 typed WorkflowResumeActionPayload
  • TextUserLlmOptionsRenderer:LLM selection 走 typed payload
  • Tests:Lark card round-trip + negative

15 files: +547 / -81。

Phase 9 consensus

META_JUDGE_DONE:consensus:type-card-action-workflow-resume-and-llm-selection-payloads

Closes #1004

⟦AI:AUTO-LOOP⟧

…control payloads (#1004)

Phase 9 r1 consensus type-card-action-workflow-resume-and-llm-selection-payloads:
- chat_activity.proto: add WorkflowResumeActionPayload + LlmSelectionActionPayload typed sub-messages on ActionElement / CardActionSubmission; arguments map demoted to open-extension-only.
- FeishuCardHumanInteractionPort + LarkMessageComposer + TelegramMessageComposer: emit typed payload, keep adapter JSON compat at composer boundary.
- NyxIdRelayTransport.BuildCardActionSubmission: map known callback JSON fields to typed sub-message.
- ChannelConversationTurnRunner.ToInboundMessage + InboundMessage.Extra: workflow/LLM handoff via typed access; literal-key path becomes deprecated inbound fallback only.
- ChannelCardActionRouting: consume typed WorkflowResumeActionPayload; literal-key rebuild path explicitly deprecated.
- TextUserLlmOptionsRenderer: route LLM selection through typed payload.
- Tests: Lark card round-trip (typed payload → relay → workflow resume); negative tests for missing/malformed typed payload.

Closes #1004

⟦AI:AUTO-LOOP⟧
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🤖 Phase 8 Reviewer — quality (round 1)

TL;DR


详细说明

主要问题不是实现风格,而是流程质量门禁:本轮 reviewer-quality.md 明确要求 cluster 级重构必须有 // Refactor (iterN/cluster-XXX): 的 Old/New 自说明,并把“major refactor 缺失或不可读 self-doc”列为 reject 条件。

本 PR 在 chat_activity.proto 新增 WorkflowResumeActionPayload / LlmSelectionActionPayload,在 ChannelCardActionRouting 将 workflow resume 从 Extra map 权威读取切到 CardAction.WorkflowResume,并在 NyxIdRelayTransport 做 JSON 边界兼容到 typed payload 的映射。这些都是核心语义迁移,但 touched production files 里没有 // Refactor (iter93/cluster-093): 说明。建议在主 seam 附近补一句清晰说明:Old 是 workflow resume / LLM selection 控制语义放在 open arguments map;New 是仓库内用 typed payload,arguments 只保留 adapter/第三方扩展和旧 callback JSON 入站兼容。


📎 完整 codex 原始输出(存档备查)
---
pr: 1005
role: quality
verdict: reject
---

## Verdict
Reject from the quality checklist because the major typed card-action refactor is missing the mandated `// Refactor (iter93/cluster-093):` self-documentation block.

## Evidence
- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181` adds new repository-owned typed payload contracts (`WorkflowResumeActionPayload` / `LlmSelectionActionPayload`) and `ActionElement` / `CardActionSubmission` fields, but no touched production file contains the required `// Refactor (iter93/cluster-093): Old/New` explanation.
- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:21` changes workflow resume routing from `Extra` map authority to typed `CardAction.WorkflowResume` plus deprecated fallback. This is exactly the kind of major semantic refactor the quality prompt asks to self-document for future readers.
- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213` introduces boundary JSON-to-typed-payload mapping and strips known semantic keys from the open extension map, also without the mandated refactor self-doc comment.

## What would change your verdict
Add a concise `// Refactor (iter93/cluster-093):` comment near the main routing/boundary seam, with clear `Old:` and `New:` clauses that explain that workflow resume and LLM selection used to ride the open `arguments` map and now use typed payloads internally, while JSON compatibility remains only at adapter boundaries.

REVIEW_DONE:1005:quality-r1:reject
⟦AI:AUTO-LOOP

REVIEW_DONE:1005:quality-r1:reject
⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🤖 Phase 8 Reviewer — architect (round 1)

TL;DR


详细说明

本轮改动把 workflow resume 与 LLM selection 这两类仓库内可控控制语义,从 ActionElement.arguments / CardActionSubmission.Arguments 这种开放 map 前移到 WorkflowResumeActionPayload / LlmSelectionActionPayload typed payload。Arguments 仍保留为第三方或平台扩展 map,旧 callback JSON 也只在 NyxId relay、Lark、Telegram 这类 adapter 边界兼容解析;这个方向符合「核心语义强类型」和「外部协议 JSON 只在边界转换」的架构要求。

我没有发现新的架构阻塞项:diff 中没有新增 Task.Delay(GetAwaiter().GetResult()TypeUrl.Contains(...)SubscribeAsync<EventEnvelope>、raw HttpClient constructor、跳过测试或 generic actor query/reply。新增的 Dictionary<> 是方法内临时映射,不是中间层跨请求事实注册表;新增的 JsonSerializer 使用点在 adapter/test callback JSON 兼容路径,不是 actor state 或 committed payload 的内部持久化。

唯一 comment 是流程性/治理项:prompt 的 architect checklist 要求每个 refactored type/method 带 Refactor (iterN/cluster-XXX): Old pattern: ... New principle: ... 注释。当前新增/改造的 chat_activity.proto typed payload contract、ChannelCardActionRouting.TryBuildWorkflowResumeCommandNyxIdRelayTransport.MapKnownPayloads、Lark/Telegram composer payload projection 方法都没有这类 Old/New pattern 注释。建议在这些边界补一条简短说明,说明旧模式是把控制语义塞入 Arguments map,新原则是仓库内控制语义走 typed payload,JSON/map 只留作 adapter/open-extension compat。


📎 完整 codex 原始输出(存档备查)
---
pr: 1005
role: architect
verdict: comment
---

## Verdict
comment-only: the typed card action payload architecture is directionally compliant, but the refactor-loop Old/New pattern comments are missing on the newly refactored typed-payload boundary methods/contracts.

## Evidence
- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181`: adds `WorkflowResumeActionPayload` / `LlmSelectionActionPayload` and `workflow_resume` / `llm_selection` fields, but no `Refactor (iter93/cluster-093): Old pattern: ... New principle: ...` comment is present near the refactored card action contract. This misses the reviewer checklist item: "Old/New pattern comment: each refactored type/method has `// Refactor (iterN/cluster-XXX): Old pattern: …  New principle: …`."
- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:21`: `TryBuildWorkflowResumeCommand` now prefers `CardAction.WorkflowResume` and only falls back to deprecated `Extra` literal keys, which matches CLAUDE/AGENTS strong-typing intent, but the refactored routing method lacks the required Old/New pattern comment.
- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213`: `MapKnownPayloads` maps legacy adapter JSON callback fields into typed payloads and removes known keys from `Arguments`, keeping JSON compatibility at the adapter boundary. This is architecturally acceptable under the serialization rule allowing JSON at Host/Adapter boundaries, but the new mapping boundary lacks the required Old/New pattern comment.
- `agents/platforms/Aevatar.GAgents.Platform.Lark/LarkMessageComposer.cs:333` and `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:224`: composer methods project typed payloads back into platform callback JSON/compact callback data. This keeps platform compatibility at the adapter boundary, but the newly refactored methods also lack the required Old/New pattern comment.
- Anti-pattern scan over the PR diff found no new `Task.Delay(`, `GetAwaiter().GetResult()`, `TypeUrl.Contains(...)`, `SubscribeAsync<EventEnvelope>`, raw `HttpClient` constructor, skipped test, or generic actor query/reply pattern. The `Dictionary<>` additions are method-local projection/adapter maps, not service-level cross-request fact registries. The `JsonSerializer` additions are in adapter/test callback JSON compatibility paths, not actor state or committed payload storage.
- Proto evolution looks safe from this diff: new fields use previously unused field numbers (`ActionElement` 11/12 and `CardActionSubmission` 6/7); no field renumbering or field removals are visible in this PR.

## What would change your verdict
Add concise refactor-loop comments to the newly refactored type/method boundaries, for example around the proto typed payload contract and the adapter/routing methods:

`Refactor (iter93/cluster-093): Old pattern: workflow resume / LLM selection control fields were encoded in ActionElement.arguments / CardActionSubmission.Arguments. New principle: repository-owned control semantics use typed payloads; JSON maps remain adapter/open-extension compatibility only.`

No blocking CLAUDE/AGENTS architecture violation found.

REVIEW_DONE:1005:architect:comment
⟦AI:AUTO-LOOP

REVIEW_DONE:1005:architect-r1:comment
⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🤖 Phase 8 Reviewer — tests (round 1)

TL;DR

  • 这是什么: PR iter93 cluster-093: type card action workflow resume + LLM selection payloads #1005 的 tests 角色审查,范围只看测试覆盖与测试质量。
  • 结论: reject;现有新增测试覆盖了 typed workflow resume 和 typed LLM select_service happy path,但漏了 typed apply_preset 与 Telegram adapter callback emission 分支。
  • 需要 maintainer 做什么: 补 3 个聚焦行为测试后可重新请求 tests reviewer。

详细说明

LlmSelectionActionPayload 是把仓库内 LLM 选择语义从开放 Arguments map 迁到强类型字段的新路径。当前 ChannelConversationTurnRunner 对 typed payload 同时处理 select_serviceapply_preset,但测试只证明了 typed select_service 能调用选择服务;没有 card action 测试证明 typed PresetId 会调用 ApplyPresetAsync。同样,NyxIdRelayTransport 新增了把 compact/action-id lp / llm_apply_preset 映射成 typed apply_preset 并填充 PresetId 的分支,但现有 relay 测试只覆盖 llm_select_service / service_id

另外,TelegramMessageComposer 新增了从 ActionElement.LlmSelection 生成 callback JSON 兼容键的逻辑,这正是本 PR 的 adapter 边界 JSON compat 目标之一;目前没有测试断言 Telegram callback_data.v 中包含 llm_action/service_id/preset_id,因此该 adapter 分支没有被行为测试钉住。

验证情况: bash tools/ci/test_stability_guards.sh 通过;过滤运行相关测试项目通过 105 个测试、0 skipped。结论不是现有测试红,而是 net-new 逻辑分支缺覆盖。


📎 完整 codex 原始输出(存档备查)
---
pr: 1005
role: tests
verdict: reject
---

## Verdict
Reject from the tests angle: the added tests cover the typed workflow resume and typed LLM service-selection happy paths, but leave the new typed preset path and adapter callback emission branches unpinned.

## Evidence
- `agents/Aevatar.GAgents.NyxidChat/ChannelConversationTurnRunner.cs:677` adds typed `LlmSelectionActionPayload` routing for both `select_service` and `apply_preset`, but `test/Aevatar.GAgents.ChannelRuntime.Tests/ChannelConversationTurnRunnerTests.cs:680` only exercises typed `select_service`; the only preset-related hits are slash-command tests or the recording fake implementation, not a card-action typed `PresetId` path that proves `ApplyPresetAsync` receives the typed value.
- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:283` maps compact/action-id `"lp"` / `"llm_apply_preset"` into typed `apply_preset`, and `:305` maps `preset_id` / submitted value into `LlmSelectionActionPayload.PresetId`; `test/Aevatar.GAgents.ChannelRuntime.Tests/NyxIdRelayTransportTests.cs:269` covers only `"llm_select_service"` / `service_id`, so the new typed preset parsing branch has no regression test.
- `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:224` now injects typed `LlmSelection` into Telegram callback arguments, but the touched test set has no `TelegramMessageComposer` behavior test asserting `callback_data.v.llm_action/service_id/preset_id`. This is a net-new adapter branch and should be pinned because the PR explicitly moves those values out of `ActionElement.Arguments`.

## What would change your verdict
Add focused behavior tests for:
- typed card action `apply_preset` in `ChannelConversationTurnRunnerTests`, asserting `RecordingUserLlmSelectionService.PresetId` receives the typed `LlmSelectionActionPayload.PresetId`;
- Nyx relay parsing for compact/apply-preset callback input, asserting `CardActionSubmission.LlmSelection.Action == "apply_preset"` and `PresetId` is populated from both `preset_id` or submitted value as intended;
- Telegram callback composition from an `ActionElement` with `LlmSelection`, asserting callback JSON carries the compatibility keys consumed by `NyxIdRelayTransport`.

Checked: `bash tools/ci/test_stability_guards.sh` passed; filtered `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --filter "FullyQualifiedName~ChannelCardActionRoutingTests|FullyQualifiedName~ChannelConversationTurnRunnerTests|FullyQualifiedName~FeishuCardHumanInteractionPortRoundTripTests|FullyQualifiedName~NyxIdRelayTransportTests"` passed 105 tests, 0 skipped.

REVIEW_DONE:1005:tests-r1:reject
⟦AI:AUTO-LOOP

REVIEW_DONE:1005:tests-r1:reject
⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🔧 Phase 8 r1 评审 — 2/3 reject + 1 comment → fix r2 派出

  • 🤖 architect: comment(only self-doc)
  • 🤖 tests: reject(typed apply_preset + NyxIdRelayTransport + Telegram callback emission 测试缺)
  • 🤖 quality: reject(Refactor (iter93/cluster-093) 自说明缺)

🔧 fix r2 codex 派出。

⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr1005-architect-r1 (⏳ 进行中; 已跑 7 min)

+## Verdict
+comment-only: the typed card action payload architecture is directionally compliant, but the refactor-loop Old/New pattern comments are missing on the newly refactored typed-payload boundary methods/contracts.
+
+## Evidence
+- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181`: adds `WorkflowResumeActionPayload` / `LlmSelectionActionPayload` and `workflow_resume` / `llm_selection` fields, but no `Refactor (iter93/cluster-093): Old pattern: ... New principle: ...` comment is present near the refactored card action contract. This misses the reviewer checklist item: "Old/New pattern comment: each refactored type/method has `// Refactor (iterN/cluster-XXX): Old pattern: …  New principle: …`."
+- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:21`: `TryBuildWorkflowResumeCommand` now prefers `CardAction.WorkflowResume` and only falls back to deprecated `Extra` literal keys, which matches CLAUDE/AGENTS strong-typing intent, but the refactored routing method lacks the required Old/New pattern comment.
+- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213`: `MapKnownPayloads` maps legacy adapter JSON callback fields into typed payloads and removes known keys from `Arguments`, keeping JSON compatibility at the adapter boundary. This is architecturally acceptable under the serialization rule allowing JSON at Host/Adapter boundaries, but the new mapping boundary lacks the required Old/New pattern comment.
+- `agents/platforms/Aevatar.GAgents.Platform.Lark/LarkMessageComposer.cs:333` and `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:224`: composer methods project typed payloads back into platform callback JSON/compact callback data. This keeps platform compatibility at the adapter boundary, but the newly refactored methods also lack the required Old/New pattern comment.
+- Anti-pattern scan over the PR diff found no new `Task.Delay(`, `GetAwaiter().GetResult()`, `TypeUrl.Contains(...)`, `SubscribeAsync<EventEnvelope>`, raw `HttpClient` constructor, skipped test, or generic actor query/reply pattern. The `Dictionary<>` additions are method-local projection/adapter maps, not service-level cross-request fact registries. The `JsonSerializer` additions are in adapter/test callback JSON compatibility paths, not actor state or committed payload storage.
+- Proto evolution looks safe from this diff: new fields use previously unused field numbers (`ActionElement` 11/12 and `CardActionSubmission` 6/7); no field renumbering or field removals are visible in this PR.
+
+## What would change your verdict
+Add concise refactor-loop comments to the newly refactored type/method boundaries, for example around the proto typed payload contract and the adapter/routing methods:
+
+`Refactor (iter93/cluster-093): Old pattern: workflow resume / LLM selection control fields were encoded in ActionElement.arguments / CardActionSubmission.Arguments. New principle: repository-owned control semantics use typed payloads; JSON maps remain adapter/open-extension compatibility only.`
+
+No blocking CLAUDE/AGENTS architecture violation found.
+
+REVIEW_DONE:1005:architect:comment
+⟦AI:AUTO-LOOP⟧

tokens used
83,651
Posted the architect round 1 review comment to PR #1005:

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr1005-quality-r1 (⏳ 进行中; 已跑 7 min)

@@ -0,0 +1,19 @@
+---
+pr: 1005
+role: quality
+verdict: reject
+---
+
+## Verdict
+Reject from the quality checklist because the major typed card-action refactor is missing the mandated `// Refactor (iter93/cluster-093):` self-documentation block.
+
+## Evidence
+- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181` adds new repository-owned typed payload contracts (`WorkflowResumeActionPayload` / `LlmSelectionActionPayload`) and `ActionElement` / `CardActionSubmission` fields, but no touched production file contains the required `// Refactor (iter93/cluster-093): Old/New` explanation.
+- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:21` changes workflow resume routing from `Extra` map authority to typed `CardAction.WorkflowResume` plus deprecated fallback. This is exactly the kind of major semantic refactor the quality prompt asks to self-document for future readers.
+- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213` introduces boundary JSON-to-typed-payload mapping and strips known semantic keys from the open extension map, also without the mandated refactor self-doc comment.
+
+## What would change your verdict
+Add a concise `// Refactor (iter93/cluster-093):` comment near the main routing/boundary seam, with clear `Old:` and `New:` clauses that explain that workflow resume and LLM selection used to ride the open `arguments` map and now use typed payloads internally, while JSON compatibility remains only at adapter boundaries.
+
+REVIEW_DONE:1005:quality-r1:reject
+⟦AI:AUTO-LOOP⟧

tokens used
131,493
Posted the Phase 8 quality review comment for PR #1005:

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr1005-tests-r1 (⏳ 进行中; 已跑 7 min)

+- `agents/Aevatar.GAgents.NyxidChat/ChannelConversationTurnRunner.cs:677` adds typed `LlmSelectionActionPayload` routing for both `select_service` and `apply_preset`, but `test/Aevatar.GAgents.ChannelRuntime.Tests/ChannelConversationTurnRunnerTests.cs:680` only exercises typed `select_service`; the only preset-related hits are slash-command tests or the recording fake implementation, not a card-action typed `PresetId` path that proves `ApplyPresetAsync` receives the typed value.
+- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:283` maps compact/action-id `"lp"` / `"llm_apply_preset"` into typed `apply_preset`, and `:305` maps `preset_id` / submitted value into `LlmSelectionActionPayload.PresetId`; `test/Aevatar.GAgents.ChannelRuntime.Tests/NyxIdRelayTransportTests.cs:269` covers only `"llm_select_service"` / `service_id`, so the new typed preset parsing branch has no regression test.
+- `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:224` now injects typed `LlmSelection` into Telegram callback arguments, but the touched test set has no `TelegramMessageComposer` behavior test asserting `callback_data.v.llm_action/service_id/preset_id`. This is a net-new adapter branch and should be pinned because the PR explicitly moves those values out of `ActionElement.Arguments`.
+
+## What would change your verdict
+Add focused behavior tests for:
+- typed card action `apply_preset` in `ChannelConversationTurnRunnerTests`, asserting `RecordingUserLlmSelectionService.PresetId` receives the typed `LlmSelectionActionPayload.PresetId`;
+- Nyx relay parsing for compact/apply-preset callback input, asserting `CardActionSubmission.LlmSelection.Action == "apply_preset"` and `PresetId` is populated from both `preset_id` or submitted value as intended;
+- Telegram callback composition from an `ActionElement` with `LlmSelection`, asserting callback JSON carries the compatibility keys consumed by `NyxIdRelayTransport`.
+
+Checked: `bash tools/ci/test_stability_guards.sh` passed; filtered `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --filter "FullyQualifiedName~ChannelCardActionRoutingTests|FullyQualifiedName~ChannelConversationTurnRunnerTests|FullyQualifiedName~FeishuCardHumanInteractionPortRoundTripTests|FullyQualifiedName~NyxIdRelayTransportTests"` passed 105 tests, 0 skipped.
+
+REVIEW_DONE:1005:tests-r1:reject
+⟦AI:AUTO-LOOP⟧

tokens used
99,290
已按 `reviewer-tests.md` 流程完成 PR #1005 tests-r1 审查,并直接发了 GitHub 评论:

`https://github.com/aevatarAI/aevatar/pull/1005#issuecomment-4529776287`

结论是 `reject`:现有测试通过,但 tests 角度认为 net-new typed `apply_preset` 路径、Nyx relay preset parsing、Telegram typed callback emission 仍缺行为覆盖。

验证已跑:
- `bash tools/ci/test_stability_guards.sh` 通过

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

…ply_preset + adapter callback emission tests

- chat_activity.proto + ChannelCardActionRouting.TryBuildWorkflowResumeCommand + NyxIdRelayTransport.MapKnownPayloads + Lark/Telegram composer projection: add Refactor (iter93/cluster-093) Old/New self-doc blocks; old = workflow resume + LLM selection control in open arguments map; new = typed payload in repo-owned contract, arguments only for adapter/3p extension + inbound callback JSON compat.
- ChannelConversationTurnRunnerTests: typed apply_preset behavior test (LlmSelection.PresetId → ApplyPresetAsync called with PresetId).
- NyxIdRelayTransportTests: lp / llm_apply_preset action id maps to typed apply_preset with PresetId filled.
- TelegramMessageComposerTests: ActionElement.LlmSelection projects into callback JSON v with llm_action/service_id/preset_id keys.

⟦AI:AUTO-LOOP⟧
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🔧 Phase 8 r2 fix applied

FIX_DONE:1005:round-2:applied-2:rejected-0:blocked-0

  • Refactor (iter93/cluster-093) Old/New 自说明到 proto + ChannelCardActionRouting + NyxIdRelayTransport + Lark/Telegram composer
  • 补 3 net-new 行为测试:typed apply_preset(Runner)+ lp action id → typed apply_preset(NyxIdRelayTransport)+ Telegram LlmSelection → callback JSON vllm_action/service_id/preset_id

👀 r2 reviewer 派出。

⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🤖 Phase 8 Reviewer — quality (round 2)

TL;DR


详细说明

r2 修复覆盖了上一轮 quality reject 的核心问题:chat_activity.proto 的 typed payload 契约、ChannelCardActionRouting 的入站路由、NyxIdRelayTransport 的 JSON 边界映射,以及 Lark/Telegram composer 的 callback 投影处,都补了 Refactor (iter93/cluster-093) Old/New 说明。说明内容能让读者直接看懂旧模式是把 workflow resume / LLM selection 控制语义放进开放 arguments map,新模式是仓库内用 WorkflowResumeActionPayload / LlmSelectionActionPayload,map/JSON 只保留 adapter 与旧 callback 兼容边界。

我没有看到新的 quality 阻塞点:新增 helper 都有调用链,命名表达了业务意图,方法拆分没有引入单实现空抽象,r2 新增测试也聚焦在 typed apply_preset、relay compact apply-preset 解析、Telegram typed callback emission 这几个变更路径。已检查 git diff --check origin/auto-refact-dev...origin/iter93/cluster-093-card-action-typed,无 whitespace 问题;本轮 quality reviewer 没跑全量测试。


📎 完整 codex 原始输出(存档备查)
---
pr: 1005
role: quality
verdict: approve
---

## Verdict
Approve from the quality checklist: the r2 patch resolves the missing self-doc concern and the typed card-action changes remain readable, focused, and free of obvious dead code or over-engineering.

## Evidence
- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181` and `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:203` now include clear `Refactor (iter93/cluster-093)` Old/New comments before the typed payload contracts, explaining that repository-owned workflow resume and LLM selection semantics moved out of the open `arguments` map.
- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:15` now documents the main routing seam, and the helper split (`HasWorkflowResumeIdentity`, `CopyWorkflowResumePayload`, `TryBuildDeprecatedWorkflowResumeValues`) keeps the method readable without adding unused abstraction.
- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213`, `agents/platforms/Aevatar.GAgents.Platform.Lark/LarkMessageComposer.cs:355`, and `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:228` document the adapter compatibility seam where typed payloads are projected to or recovered from platform callback JSON.
- The r2 test additions are behavior-focused and stay on the changed paths: typed `apply_preset` in `ChannelConversationTurnRunnerTests`, compact apply-preset relay parsing in `NyxIdRelayTransportTests`, and Telegram typed LLM callback projection in `TelegramMessageComposerTests`.
- `git diff --check origin/auto-refact-dev...origin/iter93/cluster-093-card-action-typed` reported no whitespace errors.

REVIEW_DONE:1005:quality-r2:approve
⟦AI:AUTO-LOOP

REVIEW_DONE:1005:quality-r2:approve
⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🤖 Phase 8 Reviewer — tests (round 2)

TL;DR

  • 这是什么: PR iter93 cluster-093: type card action workflow resume + LLM selection payloads #1005 tests 角色 r2 复审,范围只看测试覆盖与测试质量。
  • 结论: approve;r1 要求的 typed apply_preset、Nyx relay preset parsing、Telegram callback emission 三项行为测试已补齐。
  • 需要 maintainer 做什么: tests 角度无需继续修改,可进入其他 reviewer / controller 后续流程。

详细说明

r2 新增测试不是 bump-only:ChannelConversationTurnRunnerTests 现在用 typed LlmSelectionActionPayload(Action=apply_preset, PresetId=work-fast) 走完整 card action 路径,并断言 RecordingUserLlmSelectionService.PresetId、binding context、direct reply 与回复文案;NyxIdRelayTransportTests 覆盖 lpllm_apply_preset compact callback 映射到 typed LlmSelection.Action == "apply_preset" / PresetId == "work-fast"TelegramMessageComposerTests 解析 callback_data.v 并断言 typed LlmSelection 投影出 llm_action/service_id/preset_id 兼容键。

测试质量扫描未发现新增 Task.DelayThread.Sleep[Skip]、manual trait、Assert.True(true) 或明显断言弱化。验证已跑:bash tools/ci/test_stability_guards.sh 通过;ChannelRuntime 相关过滤测试通过 108 个、0 skipped;Telegram composer 过滤测试通过 16 个、0 skipped。


📎 完整 codex 原始输出(存档备查)
---
pr: 1005
role: tests
verdict: approve
---

## Verdict
Approve from the tests angle: r2 adds behavior tests for the r1 gaps and does not introduce test-stability or assertion-quality regressions.

## Evidence
- `test/Aevatar.GAgents.ChannelRuntime.Tests/ChannelConversationTurnRunnerTests.cs:776` adds `RunInboundAsync_ShouldApplyTypedLlmPreset_WhenPayloadCarriesPresetId`, which sends a typed `LlmSelectionActionPayload` with `Action = apply_preset` and asserts `RecordingUserLlmSelectionService.PresetId == "work-fast"`, the binding context, direct-reply receipt, and user-facing reply.
- `test/Aevatar.GAgents.ChannelRuntime.Tests/NyxIdRelayTransportTests.cs:302` adds `Parse_ShouldMapCompactApplyPresetActionId_ToTypedLlmSelection` for both `lp` and `llm_apply_preset`, asserting the adapter callback becomes typed `LlmSelection.Action == "apply_preset"` and `PresetId == "work-fast"` while removing the known semantic key from `Arguments`.
- `test/Aevatar.GAgents.Platform.Telegram.Tests/TelegramMessageComposerTests.cs:129` adds `Compose_with_typed_llm_selection_projects_callback_arguments`, parsing Telegram `callback_data` and asserting `v.llm_action`, `v.service_id`, and `v.preset_id` are emitted from typed `ActionElement.LlmSelection`.
- Diff scan found no added `Task.Delay`, `Thread.Sleep`, `[Skip]`, manual-category trait, `Assert.True(true)`, or assertion-loosening pattern that would change the tests verdict. The added `NotBeNull` checks are followed by concrete field assertions.
- Checked: `bash tools/ci/test_stability_guards.sh` passed.
- Checked: `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --filter "FullyQualifiedName~ChannelCardActionRoutingTests|FullyQualifiedName~ChannelConversationTurnRunnerTests|FullyQualifiedName~FeishuCardHumanInteractionPortRoundTripTests|FullyQualifiedName~NyxIdRelayTransportTests"` passed 108 tests, 0 skipped.
- Checked: `dotnet test test/Aevatar.GAgents.Platform.Telegram.Tests/Aevatar.GAgents.Platform.Telegram.Tests.csproj --nologo --filter FullyQualifiedName~TelegramMessageComposerTests` passed 16 tests, 0 skipped.

REVIEW_DONE:1005:tests-r2:approve
⟦AI:AUTO-LOOP

REVIEW_DONE:1005:tests-r2:approve
⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

🤖 Phase 8 Reviewer — architect (round 2)

TL;DR


详细说明

本轮重点复查 r1 architect 指出的 self-doc 缺口,以及 arguments 从控制语义降级为边界扩展 map 后有没有形成第二套权威路径。WorkflowResumeActionPayload / LlmSelectionActionPayload 已在 proto、NyxID relay adapter、Lark/Telegram composer、workflow resume routing 等关键 seam 补上 Refactor (iter93/cluster-093) Old/New 说明。

架构上认可当前形态:typed payload 是仓库内可控控制语义的主路径;Lark/Telegram/NyxID 的 JSON 仍只在 adapter/platform 边界投影;Extra / Arguments 的 literal-key 路径被标注为 deprecated inbound compatibility,不作为新的事实源。PR diff 的反模式扫描未发现新的 actor.HandleEventAsync(SubscribeAsync<EventEnvelope>、生产 Task.Delay(GetAwaiter().GetResult()TypeUrl.Contains(...)、raw HttpClient、disabled tests 或中间层跨请求事实字典。

验证已跑过:dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --no-restore 861 passed;dotnet test test/Aevatar.GAgents.Platform.Telegram.Tests/Aevatar.GAgents.Platform.Telegram.Tests.csproj --nologo --no-restore 19 passed;bash tools/ci/architecture_guards.sh passed。


📎 完整 codex 原始输出(存档备查)
---
pr: 1005
role: architect
verdict: approve
---

## Verdict
approve: r2 addresses the r1 architecture self-doc gap and keeps the typed card-action payload refactor inside the intended adapter/proto/channel boundaries.

## Evidence
- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181`: the new `WorkflowResumeActionPayload` / `LlmSelectionActionPayload` contracts now carry the required `Refactor (iter93/cluster-093)` Old/New block, and the proto fields are additive (`ActionElement.workflow_resume = 11`, `ActionElement.llm_selection = 12`, `CardActionSubmission.workflow_resume = 6`, `CardActionSubmission.llm_selection = 7`) with no field-number reuse or renumbering.
- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213`: relay callback JSON is mapped at the NyxID adapter boundary into typed payloads and known repository-owned keys are removed from `Arguments`; JSON stays confined to the external adapter boundary, matching the serialization rule that external JSON is allowed only at Host/Adapter conversion boundaries.
- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:15` and `agents/Aevatar.GAgents.NyxidChat/ChannelConversationTurnRunner.cs:677`: workflow resume and LLM selection consume typed `CardActionSubmission` payloads first; literal-key lookup remains explicitly deprecated inbound compatibility, not a new authoritative path.
- `agents/platforms/Aevatar.GAgents.Platform.Lark/LarkMessageComposer.cs:355` and `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:228`: composers project typed payloads back into platform callback JSON only at platform emission boundaries, which preserves current NyxID relay surface without requiring changes to the external `../NyxID` repository.
- `docs/canon/aevatar-channel-architecture.md:410`: the canonical channel document now states the typed card action payload rule and limits `Arguments` to third-party/platform extension and deprecated inbound compatibility.
- Anti-pattern scan over the PR diff found no new `actor.HandleEventAsync(`, `SubscribeAsync<EventEnvelope>`, production `Task.Delay(`, `GetAwaiter().GetResult()`, `TypeUrl.Contains(...)`, raw `HttpClient` constructors, disabled tests, or service-level middle-layer ID dictionaries. The added dictionaries are method-local/platform serialization maps rather than cross-request fact stores.
- Verification passed: `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --no-restore` (861 passed), `dotnet test test/Aevatar.GAgents.Platform.Telegram.Tests/Aevatar.GAgents.Platform.Telegram.Tests.csproj --nologo --no-restore` (19 passed), and `bash tools/ci/architecture_guards.sh` (passed, including docs lint and channel card literal guard).

REVIEW_DONE:1005:architect-r2:approve

⟦AI:AUTO-LOOP

REVIEW_DONE:1005:architect-r2:approve

⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

✅ Phase 8 r2 集中评审

  • 🤖 architect r2: approve
  • 🤖 tests r2: approve
  • 🤖 quality r2: approve

3/3 → auto-merge。

⟦AI:AUTO-LOOP⟧

@loning loning merged commit 04d3a53 into auto-refact-dev May 24, 2026
10 of 11 checks passed
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr1005-architect-r2 (⏳ 进行中; 已跑 5 min)

+## Evidence
+- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181`: the new `WorkflowResumeActionPayload` / `LlmSelectionActionPayload` contracts now carry the required `Refactor (iter93/cluster-093)` Old/New block, and the proto fields are additive (`ActionElement.workflow_resume = 11`, `ActionElement.llm_selection = 12`, `CardActionSubmission.workflow_resume = 6`, `CardActionSubmission.llm_selection = 7`) with no field-number reuse or renumbering.
+- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213`: relay callback JSON is mapped at the NyxID adapter boundary into typed payloads and known repository-owned keys are removed from `Arguments`; JSON stays confined to the external adapter boundary, matching the serialization rule that external JSON is allowed only at Host/Adapter conversion boundaries.
+- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:15` and `agents/Aevatar.GAgents.NyxidChat/ChannelConversationTurnRunner.cs:677`: workflow resume and LLM selection consume typed `CardActionSubmission` payloads first; literal-key lookup remains explicitly deprecated inbound compatibility, not a new authoritative path.
+- `agents/platforms/Aevatar.GAgents.Platform.Lark/LarkMessageComposer.cs:355` and `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:228`: composers project typed payloads back into platform callback JSON only at platform emission boundaries, which preserves current NyxID relay surface without requiring changes to the external `../NyxID` repository.
+- `docs/canon/aevatar-channel-architecture.md:410`: the canonical channel document now states the typed card action payload rule and limits `Arguments` to third-party/platform extension and deprecated inbound compatibility.
+- Anti-pattern scan over the PR diff found no new `actor.HandleEventAsync(`, `SubscribeAsync<EventEnvelope>`, production `Task.Delay(`, `GetAwaiter().GetResult()`, `TypeUrl.Contains(...)`, raw `HttpClient` constructors, disabled tests, or service-level middle-layer ID dictionaries. The added dictionaries are method-local/platform serialization maps rather than cross-request fact stores.
+- Verification passed: `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --no-restore` (861 passed), `dotnet test test/Aevatar.GAgents.Platform.Telegram.Tests/Aevatar.GAgents.Platform.Telegram.Tests.csproj --nologo --no-restore` (19 passed), and `bash tools/ci/architecture_guards.sh` (passed, including docs lint and channel card literal guard).
+
+REVIEW_DONE:1005:architect-r2:approve
+
+⟦AI:AUTO-LOOP⟧

tokens used
140,293
已完成 PR #1005 Phase 8 architect r2 review,并已直接评论到 GitHub:

https://github.com/aevatarAI/aevatar/pull/1005#issuecomment-4529810733

结论:`approve`

本地 artifact 已写入:
`.refactor-loop/runs/reviewer-architect-pr1005-r2.md`

验证已跑:

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr1005-quality-r2 (⏳ 进行中; 已跑 5 min)

+---
+pr: 1005
+role: quality
+verdict: approve
+---
+
+## Verdict
+Approve from the quality checklist: the r2 patch resolves the missing self-doc concern and the typed card-action changes remain readable, focused, and free of obvious dead code or over-engineering.
+
+## Evidence
+- `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:181` and `agents/Aevatar.GAgents.Channel.Abstractions/protos/chat_activity.proto:203` now include clear `Refactor (iter93/cluster-093)` Old/New comments before the typed payload contracts, explaining that repository-owned workflow resume and LLM selection semantics moved out of the open `arguments` map.
+- `agents/Aevatar.GAgents.NyxidChat/ChannelCardActionRouting.cs:15` now documents the main routing seam, and the helper split (`HasWorkflowResumeIdentity`, `CopyWorkflowResumePayload`, `TryBuildDeprecatedWorkflowResumeValues`) keeps the method readable without adding unused abstraction.
+- `agents/channels/Aevatar.GAgents.Channel.NyxIdRelay/NyxIdRelayTransport.cs:213`, `agents/platforms/Aevatar.GAgents.Platform.Lark/LarkMessageComposer.cs:355`, and `agents/platforms/Aevatar.GAgents.Platform.Telegram/TelegramMessageComposer.cs:228` document the adapter compatibility seam where typed payloads are projected to or recovered from platform callback JSON.
+- The r2 test additions are behavior-focused and stay on the changed paths: typed `apply_preset` in `ChannelConversationTurnRunnerTests`, compact apply-preset relay parsing in `NyxIdRelayTransportTests`, and Telegram typed LLM callback projection in `TelegramMessageComposerTests`.
+- `git diff --check origin/auto-refact-dev...origin/iter93/cluster-093-card-action-typed` reported no whitespace errors.
+
+REVIEW_DONE:1005:quality-r2:approve
+⟦AI:AUTO-LOOP⟧

tokens used
102,739
Posted the PR comment:

`POSTED:quality:1005:https://github.com/aevatarAI/aevatar/pull/1005#issuecomment-4529807997:## 🤖 Phase 8 Reviewer — quality (round 2)`

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr1005-tests-r2 (⏳ 进行中; 已跑 5 min)

+Approve from the tests angle: r2 adds behavior tests for the r1 gaps and does not introduce test-stability or assertion-quality regressions.
+
+## Evidence
+- `test/Aevatar.GAgents.ChannelRuntime.Tests/ChannelConversationTurnRunnerTests.cs:776` adds `RunInboundAsync_ShouldApplyTypedLlmPreset_WhenPayloadCarriesPresetId`, which sends a typed `LlmSelectionActionPayload` with `Action = apply_preset` and asserts `RecordingUserLlmSelectionService.PresetId == "work-fast"`, the binding context, direct-reply receipt, and user-facing reply.
+- `test/Aevatar.GAgents.ChannelRuntime.Tests/NyxIdRelayTransportTests.cs:302` adds `Parse_ShouldMapCompactApplyPresetActionId_ToTypedLlmSelection` for both `lp` and `llm_apply_preset`, asserting the adapter callback becomes typed `LlmSelection.Action == "apply_preset"` and `PresetId == "work-fast"` while removing the known semantic key from `Arguments`.
+- `test/Aevatar.GAgents.Platform.Telegram.Tests/TelegramMessageComposerTests.cs:129` adds `Compose_with_typed_llm_selection_projects_callback_arguments`, parsing Telegram `callback_data` and asserting `v.llm_action`, `v.service_id`, and `v.preset_id` are emitted from typed `ActionElement.LlmSelection`.
+- Diff scan found no added `Task.Delay`, `Thread.Sleep`, `[Skip]`, manual-category trait, `Assert.True(true)`, or assertion-loosening pattern that would change the tests verdict. The added `NotBeNull` checks are followed by concrete field assertions.
+- Checked: `bash tools/ci/test_stability_guards.sh` passed.
+- Checked: `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --filter "FullyQualifiedName~ChannelCardActionRoutingTests|FullyQualifiedName~ChannelConversationTurnRunnerTests|FullyQualifiedName~FeishuCardHumanInteractionPortRoundTripTests|FullyQualifiedName~NyxIdRelayTransportTests"` passed 108 tests, 0 skipped.
+- Checked: `dotnet test test/Aevatar.GAgents.Platform.Telegram.Tests/Aevatar.GAgents.Platform.Telegram.Tests.csproj --nologo --filter FullyQualifiedName~TelegramMessageComposerTests` passed 16 tests, 0 skipped.
+
+REVIEW_DONE:1005:tests-r2:approve
+⟦AI:AUTO-LOOP⟧

tokens used
86,388
Posted PR #1005 tests r2 review:

https://github.com/aevatarAI/aevatar/pull/1005#issuecomment-4529808131

Verdict: `approve`

Verified:
- `bash tools/ci/test_stability_guards.sh` passed
- ChannelRuntime filtered tests passed: 108 passed, 0 skipped

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

@loning loning mentioned this pull request May 25, 2026
loning added a commit that referenced this pull request May 25, 2026
…d-await dispatch port

Coverage-quality CI on r2 still failed 39 tests in Aevatar.GAgents.ChannelRuntime.Tests because production callers (SkillRunnerCommandPort, UserAgentCatalogCommandPort, DeviceCommandFacade, ChannelRegistrationCommandFacade, ChannelBotRegistrationStartupService, TurnStreamingReplySink, NyxLark/NyxTelegram ProvisioningService) still used IActorDispatchPort admission-only contract but tests expected old handled-await semantics.

r3 fix:
- New OrleansActorHandledDispatchPort + HandledActorCommandTargetDispatcher providing handled-await semantics on Orleans path (parallel to Local r2 LocalActorHandledDispatchPort).
- Production callers (SkillRunner / UserAgentCatalog / DeviceCommand / ChannelRegistration / TurnStreamingReplySink / NyxLark+NyxTelegram Provisioning / AgentRunReplyGenerationExecutor) migrated to IHandledActorDispatchPort for the dispatch paths that must await committed state.
- DI registration (Orleans + Device + NyxIdRelay) wires the handled port.
- NyxIdRelayTransport content parsing tests updated to match typed card action payload schema (from #1005 typed payload migration).
- Test files updated to assert against new admission ACK shape OR handled completion as appropriate per call site.

23 files: r2 7 fail + r3 39 fail全过本地。r1 5 fail + Script integration 不回归。

⟦AI:AUTO-LOOP⟧
loning added a commit that referenced this pull request May 25, 2026
…rkflowResume payload

r3 fixed 39/40, only Aevatar.AI.Tests.NyxIdChatEndpointsCoverageTests.HandleRelayWebhookAsync_ShouldDispatchCardAction_ToConversationActor_ForWorkflowResumeSubmit still failed.

Test asserted cardAction.Arguments["actor_id"] but #1005 typed card action migration moved actor_id/run_id/step_id/approved from Arguments map to cardAction.WorkflowResume.ActorId/RunId/StepId/Approved typed payload.

1 file, test assertions updated to read typed payload.

⟦AI:AUTO-LOOP⟧
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 25, 2026

📊 codex 进展 hotfix-trunk-red-2026-05-25-r4 (⏳ 进行中; 已跑 7 min)

-        cardAction.Arguments.Should().ContainKey("step_id").WhoseValue.Should().Be("approval-1");
-        cardAction.Arguments.Should().ContainKey("approved").WhoseValue.Should().Be("False");
-        cardAction.FormFields.Should().ContainKey("user_input")
-            .WhoseValue.Should().Be("Need stronger hook");
+        cardAction!.WorkflowResume.Should().NotBeNull();
+        cardAction.WorkflowResume!.ActorId.Should().Be("workflow-actor-1");
+        cardAction.WorkflowResume.RunId.Should().Be("run-1");
+        cardAction.WorkflowResume.StepId.Should().Be("approval-1");
+        cardAction.WorkflowResume.Approved.Should().BeFalse();
+        cardAction.WorkflowResume.UserInput.Should().Be("Need stronger hook");
     }
 
     [Fact]

tokens used
98,055
Fixed [NyxIdChatEndpointsCoverageTests.cs](/Users/auric/aevatar-wt-hotfix-trunk-r4/test/Aevatar.AI.Tests/NyxIdChatEndpointsCoverageTests.cs:1689): the workflow resume card action assertions now read `WorkflowResume.ActorId/RunId/StepId/Approved/UserInput` instead of the deprecated `Arguments` / `FormFields` keys.

Verification passed:

```bash
dotnet test test/Aevatar.AI.Tests/Aevatar.AI.Tests.csproj --nologo --filter "FullyQualifiedName~Aevatar.AI.Tests.NyxIdChatEndpointsCoverageTests.HandleRelayWebhookAsync_ShouldDispatchCardAction_ToConversationActor_ForWorkflowResumeSubmit"

Result: 1 passed. Final scan found no remaining old actor_id/run_id/step_id/approved argument-map assertions in that file. No git operations performed.


> 自动更新每 10 分钟;edit-in-place 不堆评论;**codex 完成后此 comment 自动删除**(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

loning added a commit that referenced this pull request May 25, 2026
…DispatchAdmission contract (#1015)

* hotfix(trunk-r2): restore Script integration test compatibility with DispatchAdmission contract

r1 hotfix 修了 5 个 fail 但破了 7 个 Script integration test。r2 修法:
- 加 LocalActorHandledDispatchPort 提供旧"handled-await"语义给 Script 路径(integration test 期望 Script Bind/Replay 完成后才返回)
- IActorDispatchPort 区分 admission-only(default) vs handled-await(opt-in)
- ServiceCollectionExtensions: Local + Scripting + ConfiguredConnectorRegistry 走 handled-await
- RuntimeScriptCommandService + RuntimeScriptProvisioningService 显式 await handled
- HybridServiceUpgradeContinuityTests 调整断言适配新 ACK shape
- architecture_guards.sh 新 guard 防新增 admission-only 路径触发 Script lifecycle await 漏洞

9 files: r1 5 test + r2 7 test 全 pass(本地),不回归。

⟦AI:AUTO-LOOP⟧

* hotfix(trunk-r3): migrate ChannelRuntime production callers to handled-await dispatch port

Coverage-quality CI on r2 still failed 39 tests in Aevatar.GAgents.ChannelRuntime.Tests because production callers (SkillRunnerCommandPort, UserAgentCatalogCommandPort, DeviceCommandFacade, ChannelRegistrationCommandFacade, ChannelBotRegistrationStartupService, TurnStreamingReplySink, NyxLark/NyxTelegram ProvisioningService) still used IActorDispatchPort admission-only contract but tests expected old handled-await semantics.

r3 fix:
- New OrleansActorHandledDispatchPort + HandledActorCommandTargetDispatcher providing handled-await semantics on Orleans path (parallel to Local r2 LocalActorHandledDispatchPort).
- Production callers (SkillRunner / UserAgentCatalog / DeviceCommand / ChannelRegistration / TurnStreamingReplySink / NyxLark+NyxTelegram Provisioning / AgentRunReplyGenerationExecutor) migrated to IHandledActorDispatchPort for the dispatch paths that must await committed state.
- DI registration (Orleans + Device + NyxIdRelay) wires the handled port.
- NyxIdRelayTransport content parsing tests updated to match typed card action payload schema (from #1005 typed payload migration).
- Test files updated to assert against new admission ACK shape OR handled completion as appropriate per call site.

23 files: r2 7 fail + r3 39 fail全过本地。r1 5 fail + Script integration 不回归。

⟦AI:AUTO-LOOP⟧

* hotfix(trunk-r4): update NyxIdChat webhook test assertion to typed WorkflowResume payload

r3 fixed 39/40, only Aevatar.AI.Tests.NyxIdChatEndpointsCoverageTests.HandleRelayWebhookAsync_ShouldDispatchCardAction_ToConversationActor_ForWorkflowResumeSubmit still failed.

Test asserted cardAction.Arguments["actor_id"] but #1005 typed card action migration moved actor_id/run_id/step_id/approved from Arguments map to cardAction.WorkflowResume.ActorId/RunId/StepId/Approved typed payload.

1 file, test assertions updated to read typed payload.

⟦AI:AUTO-LOOP⟧

* hotfix(trunk-r5): fix ScopeDraftRunActor query test after dev merge

dev_sync_daemon 自动 merge auto-refact-dev 进 PR1015 后(含 dev 22 commits + PR1014 skill update)
引入 1 新 fail:
- Aevatar.GAgentService.Integration.Tests.ScopeDraftRunActorQueryIntegrationTests.DraftRunEndpoint_ShouldExposeCompletedActorSnapshotViaActorQuery

调整 test assertion 适配新 DispatchAdmission + ScopeDraftRun actor snapshot path。

1 test file。

⟦AI:AUTO-LOOP⟧

* hotfix(trunk-r6): WorkflowRunGAgent await RoleGAgent creation via handled dispatch

dev merge 引入 1 fail:
- "给定 WorkflowGAgent 加载了 YAML,当触发时应创建 3 个 RoleGAgent 子 Agent"

根因:DispatchAdmission contract 后 WorkflowGAgent.HandleAsync 通过 admission-only port 派 RoleGAgent
创建,test 期望 RoleGAgent 实际可用 → 切 handled port + await committed。

1 file。

⟦AI:AUTO-LOOP⟧
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant