fix(msteams): add per-call topLevel override on send action (fixes #93288)#93846
fix(msteams): add per-call topLevel override on send action (fixes #93288)#93846zenglingbiao wants to merge 5 commits into
Conversation
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
Codex review: needs real behavior proof before merge. Reviewed July 1, 2026, 2:02 AM ET / 06:02 UTC. Summary PR surface: Source +79, Tests +67. Total +146 across 4 files. Reproducibility: yes. source-level: current main has no Teams send-scoped Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Keep one canonical implementation that carries Do we have a high-confidence way to reproduce the issue? Yes, source-level: current main has no Teams send-scoped Is this the best way to solve the issue? No as implemented. The Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fc5ba0e58bb4. Label changesLabel justifications:
Evidence reviewedPR surface: Source +79, Tests +67. Total +146 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
…eams-toplevel-override
…s on outbound path (fixes openclaw#93288) Narrow the send handler to only intercept when topLevel is explicitly true. Normal send calls fall through to the outbound adapter, preserving media, payload, chunking, hooks, and receipt behavior for the established path. ClawSweeper P1: 'Keep Plain Sends On The Outbound Path'
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
…eams-toplevel-override
…ith replyStyleOverride - Replace topLevel boolean with replyStyleOverride (MSTeamsReplyStyle) in sendMessageMSTeams and sendAdaptiveCardMSTeams, passing through to resolveMSTeamsSendContext instead of mapping internally. - Add presentation guard in channel.ts: topLevel + card/presentation sends are explicitly rejected with a clear error message. - Use the full send params (mediaLocalRoots, mediaReadFile) in the topLevel intercept path so the established outbound pipeline stays intact. - Add send-context.test.ts coverage: replyStyleOverride honored before config-derived replyStyle, and fallback to config when omitted. Fixes openclaw#93288
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Summary
sendaction always uses the static channelreplyStyleconfig, preventing agents from creating a new root post / thread on demand.resolveMSTeamsSendContextderivesreplyStylesolely from the stored conversation reference and staticreplyStyleconfig with no per-call override path.replyStyleOverridethroughsendMessageMSTeams→resolveMSTeamsSendContextso callers can force"top-level"placement without changing static config. Presentation/card sends withtopLevelare explicitly rejected until the card path supports the override.extensions/msteams/src/send-context.ts— accept optionalreplyStyleOverrideparam, use??fallback to config-derived valueextensions/msteams/src/send.ts— exposereplyStyleOverrideonSendMSTeamsMessageParamsandSendMSTeamsCardParams, pass through toresolveMSTeamsSendContextextensions/msteams/src/channel.ts— addtopLevelschema property, intercepttopLevel=trueplain-text sends to callsendMessageMSTeamswithreplyStyleOverride: "top-level"; reject presentation+topLevel combinations with a clear error messagereplyStyleconfig behavior is untouched — whenreplyStyleOverrideis omitted, resolution falls back to the config-derived value exactly as beforereplyStyleOverrideis only meaningful for channel conversationsreplyStyleOverridein this PR (explicitly rejected)Reproduction
replyStyle: "thread"sendwithtopLevel: trueto create a new root postreplyStyle: "thread"(ignoring the caller's intent), posting the message as a thread reply rather than a new root postreplyStyle: "top-level"(honoring the per-call override), creating a new root post in the channelReal behavior proof
Behavior or issue addressed (#93288): MS Teams per-call
topLevelsend override must create a new root post / new thread in a channel, bypassing the staticreplyStyleconfig, while preserving existing config-derived behavior when no override is passed.Real environment tested: Linux, Node v22.19.0, OpenClaw built from source. The send-context harness exercises real
resolveMSTeamsProactiveReplyStyleintegration with conversation store entries and channel config.Exact steps or command run after this patch:
node scripts/run-vitest.mjs extensions/msteams/src/send-context.test.ts extensions/msteams/src/send.test.ts extensions/msteams/src/channel.test.tsEvidence before fix:
Evidence after fix:
Observed result after fix:
resolveMSTeamsSendContexthonors per-callreplyStyleOverridewhen present and falls back to config-derivedreplyStylewhen omitted. The channel action handler rejectstopLevel+ presentation/card combinations with a clear error.What was not tested: A live MS Teams tenant send was not driven — the tenant is unavailable in this environment. The override logic is verified through the send-context harness exercising real
resolveMSTeamsProactiveReplyStyleintegration with conversation store entries.Repro confirmation: Before fix:
resolveMSTeamsSendContextignores overrides, always uses config-derived replyStyle. After fix: two new cases confirm override honored and fallback preserved.Risk / Mitigation
topLevel=truesends use a separate intercept in the channel action handlerMitigation: The intercept calls the same
sendMessageMSTeamsfunction used by normal sends, passing the full param set (mediaLocalRoots, mediaReadFile). OnlyreplyStyleOverridediffers from the normal path.topLevelare not supportedMitigation: Explicitly rejected with a clear error.
sendAdaptiveCardMSTeamsalready acceptsreplyStyleOverrideso extending support is a straightforward follow-up.Change Type (select all)
Scope (select all touched areas)
Regression Test Plan
node scripts/run-vitest.mjs extensions/msteams/src/send-context.test.ts— replyStyleOverride honored and fallback verifiednode scripts/run-vitest.mjs extensions/msteams/src/send.test.ts— sendMessageMSTeams replyStyleOverride passthrough verifiednode scripts/run-vitest.mjs extensions/msteams/src/channel.test.ts— topLevel schema and action intercept verifiedReview Findings Addressed
N/A (initial submission — this push is the refactored approach aligning with ClawSweeper's "Repair Through Existing Outbound" maintainer option)
Linked Issue/PR
Fixes #93288