Skip to content

msteams: allow replyStyle config override for DMs#27765

Closed
mattjcorner wants to merge 1 commit intoopenclaw:mainfrom
mattjcorner:fix/msteams-dm-reply-style
Closed

msteams: allow replyStyle config override for DMs#27765
mattjcorner wants to merge 1 commit intoopenclaw:mainfrom
mattjcorner:fix/msteams-dm-reply-style

Conversation

@mattjcorner
Copy link
Copy Markdown

Summary

Direct message conversations currently hardcode replyStyle: "thread" in resolveMSTeamsReplyPolicy(), ignoring any config override. This causes reply failures in DMs when agent processing exceeds the Bot Framework TurnContext lifetime.

The problem: The "thread" reply style reuses the original webhook TurnContext. Bot Framework revokes this TurnContext proxy after the HTTP handler returns (~15-30 seconds). When agent processing takes longer — LLM inference, tool calls, multi-step workflows — the final reply attempt hits the revoked proxy and fails silently:

msteams final reply failed: Cannot perform 'set' on a proxy that has been revoked
msteams final reply failed: Cannot perform 'get' on a proxy that has been revoked

The user sees the agent's "thinking" preamble but never receives the actual response.

The fix: The "top-level" reply style uses adapter.continueConversation() which creates a fresh TurnContext per send — no proxy expiry issue. This change makes DMs respect the same config cascade (channelConfig → teamConfig → globalConfig) as group conversations, while preserving "thread" as the default for backwards compatibility.

After this change, operators hitting proxy-revoked errors in DMs can set replyStyle: "top-level" in their msteams channel config to resolve the issue.

Changes

  • extensions/msteams/src/policy.ts: Replace hardcoded "thread" return for DMs with config cascade resolution (same pattern as non-DM path), defaulting to "thread"
  • extensions/msteams/src/policy.test.ts: Update test to verify default behavior + add test for config override

Test plan

  • pnpm test -- --run extensions/msteams/src/policy.test.ts — all 17 tests pass
  • Deploy with replyStyle: "top-level" in msteams config — verify DM replies deliver reliably regardless of agent processing time
  • Deploy without explicit replyStyle — verify DMs still default to "thread" (backwards compat)

🤖 Generated with Claude Code

DM conversations were hardcoded to replyStyle "thread", which reuses
the original webhook TurnContext. Bot Framework revokes this proxy
after the HTTP handler returns (~15-30s). When agent processing takes
longer (LLM inference, tool calls), the final reply hits the revoked
proxy and fails silently — the user sees "Let me try..." but never
gets the actual response.

The "top-level" replyStyle uses adapter.continueConversation() which
creates a fresh TurnContext per send with no expiry. This change lets
DMs respect the same config cascade (channel → team → global) as
group conversations, defaulting to "thread" for backwards compat.

Operators hitting proxy-revoked errors in DMs can now set
replyStyle: "top-level" in their msteams channel config.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@openclaw-barnacle openclaw-barnacle bot added channel: msteams Channel integration: msteams size: XS labels Feb 26, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Replaces hardcoded "thread" reply style for DMs with config cascade resolution (channelConfig → teamConfig → globalConfig → "thread" default), matching the pattern used for group conversations.

Changes:

  • policy.ts:223-229: DM path now respects replyStyle config overrides while preserving "thread" as the default
  • policy.test.ts: Updated test name to reflect "defaults" behavior and added test for config override

Why this matters:
The "thread" reply style reuses the original Bot Framework TurnContext, which expires after ~15-30 seconds. When agent processing exceeds this window (LLM inference, tool calls, etc.), DM replies fail silently with proxy revocation errors. The "top-level" style uses adapter.continueConversation() to create fresh contexts per send, avoiding the expiry issue. This change allows operators to configure replyStyle: "top-level" for DMs when needed.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The change is minimal (7 lines), follows existing patterns, preserves backwards compatibility (defaults to "thread"), and includes proper test coverage. The fix addresses a real production issue (proxy revocation errors) while maintaining the same config cascade used throughout the codebase.
  • No files require special attention

Last reviewed commit: 4e3d709

@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle bot added the stale Marked as stale due to inactivity label Mar 4, 2026
@BradGroux BradGroux self-assigned this Mar 10, 2026
@BradGroux
Copy link
Copy Markdown
Contributor

Hi @mattjcorner — thanks for the submission. I’m the new Microsoft Teams maintainer for OpenClaw. Please give me a day or two to work through the open Teams backlog. Also, join the Twitter community for daily MS Teams feedback + updates: https://x.com/i/communities/2031170403607974228

1 similar comment
@BradGroux
Copy link
Copy Markdown
Contributor

Hi @mattjcorner — thanks for the submission. I’m the new Microsoft Teams maintainer for OpenClaw. Please give me a day or two to work through the open Teams backlog. Also, join the Twitter community for daily MS Teams feedback + updates: https://x.com/i/communities/2031170403607974228

@BradGroux
Copy link
Copy Markdown
Contributor

Closing this stale Microsoft-tracker item for cleanup. If this is still an issue or still worth pursuing, please re-open it. We now have dedicated Microsoft maintainers watching this area.

@BradGroux BradGroux closed this Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: msteams Channel integration: msteams size: XS stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants