Skip to content

Add Microsoft Teams integration. Fixes #88#111

Open
striver-24 wants to merge 1 commit intojentic:mainfrom
striver-24:feature/teams-bot-integration
Open

Add Microsoft Teams integration. Fixes #88#111
striver-24 wants to merge 1 commit intojentic:mainfrom
striver-24:feature/teams-bot-integration

Conversation

@striver-24
Copy link

@striver-24 striver-24 commented Oct 2, 2025

Closes #88

  • Add teams_agent.py with Bot Framework integration
  • Include enterprise features: rate limiting, input validation, error handling
  • Add requirements.txt with production-ready dependencies
  • Add comprehensive README.md with setup documentation
  • Follow established patterns from Slack/Discord examples

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Microsoft Teams bot example with agent integration supporting multiple reasoning profiles
    • Implemented slash commands for API key configuration, reasoning profile selection, and agent control
    • Added rate limiting for per-user request management and health check endpoints
  • Documentation

    • Added comprehensive Teams bot deployment and usage guide with prerequisites, setup instructions, and troubleshooting

✏️ Tip: You can customize this high-level summary in your review settings.

- Add teams_agent.py with Bot Framework integration
- Include enterprise features: rate limiting, input validation, error handling
- Add requirements.txt with production-ready dependencies
- Add comprehensive README.md with setup documentation
- Follow established patterns from Slack/Discord examples
@striver-24 striver-24 requested a review from a team as a code owner October 2, 2025 14:10
@rishikesh-jentic
Copy link
Collaborator

Thanks so much for this PR and for taking the time to contribute to Standard Agent — welcome aboard 🙌
We’ll review and share feedback soon! 🚀

@striver-24
Copy link
Author

Thank you for the warm welcome! I’m excited to contribute more to Standard Agent and look forward to your feedback. 😊

@rishikesh-jentic
Copy link
Collaborator

@CodeRabbit review this PR

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

@rishikesh-jentic: I'll review the PR now and provide feedback on the Microsoft Teams integration implementation.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

A new Microsoft Teams bot example is added following patterns from existing Slack/Discord examples. The implementation includes configuration, agent runtime with profile selection, rate limiting, command handling, authentication, and a complete HTTP server for Teams integration.

Changes

Cohort / File(s) Summary
Setup and Configuration
examples/teams/README.md, examples/teams/requirements.txt
Comprehensive documentation covering Quick Start, prerequisites, Azure bot registration, deployment methods (Azure/Docker), local development with ngrok, environment variables, usage examples, troubleshooting, health checks, security, and architecture. Requirements file specifies Microsoft Bot Framework dependencies with compatible version ranges.
Teams Bot Implementation
examples/teams/teams_agent.py
TeamsConfig dataclass for environment-based configuration; TeamsAgentRuntime tracking profile, agent instance, credentials, and per-user rate limiting; RateLimiter enforcing request limits; TeamsAgentBot handling message activities with rate limit checks, goal extraction, lazy agent initialization, response chunking, and slash command support (/configure, /reasoner, /kill, /help); agent selection via ReasonerProfile enum (REWOO, REACT); authentication with lightweight token validation; HTTP server with /api/messages and /health endpoints; telemetry integration; robust error handling and logging.

Sequence Diagram

sequenceDiagram
    actor Teams as Teams User
    participant Bot as TeamsAgentBot
    participant Limiter as RateLimiter
    participant Agent as StandardAgent
    participant Teams_API as Teams Channel

    Teams->>Bot: on_message_activity()
    activate Bot
    
    Bot->>Limiter: is_allowed(user_id)
    activate Limiter
    Limiter-->>Bot: allowed: bool
    deactivate Limiter
    
    alt rate limit exceeded
        Bot-->>Teams_API: send error message
    else allowed
        Bot->>Bot: extract_goal_from_mention()
        Bot->>Bot: _build_agent(profile)
        activate Agent
        
        Bot->>Agent: process goal with timeout
        Agent-->>Bot: response text
        deactivate Agent
        
        Bot->>Bot: chunk_text(response)
        Bot->>Teams_API: send chunked responses
    end
    
    deactivate Bot
    Teams_API-->>Teams: display message(s)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰 Hops with glee, a Teams bot springs to life!
Configuration blooms, no more Discord strife.
Rate limits set, commands dance with flair,
ReACT and ReWOO profiles floating through the air!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change as adding Microsoft Teams integration and references the linked issue.
Linked Issues check ✅ Passed The PR successfully addresses all acceptance criteria: implements teams_agent.py [#88], follows Slack/Discord patterns [#88], adds setup documentation [#88], includes error handling [#88], and provides rate limiting and validation [#88].
Out of Scope Changes check ✅ Passed All changes are directly related to the Teams integration objective; no unrelated modifications to existing files or out-of-scope additions are present.
Docstring Coverage ✅ Passed Docstring coverage is 80.95% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@examples/teams/requirements.txt`:
- Around line 1-18: The cryptography dependency line currently reads
"cryptography>=41.0.0" and lacks an upper bound; update that requirement to
include an upper bound (e.g., change to "cryptography>=41.0.0,<47.0.0") so the
cryptography package is constrained to a safe major-version range.

In `@examples/teams/teams_agent.py`:
- Around line 267-271: The except block that calls
logger.exception("teams_message_error", error=str(exc), user_id=user_id) can
raise a NameError if user_id wasn't set earlier; update the except handler in
the teams_agent.py except Exception as exc block to resolve user_id safely
(e.g., derive it from turn_context.activity.from_property.id if present, or use
a fallback like None or "unknown") before passing it to logger.exception and
sending the error message; ensure you reference the same safe variable name
(user_id) when logging so the logger call can never reference an undefined
symbol.
- Around line 513-518: The exception handler references turn_context which may
not be defined if the error occurs before it's created; update the except block
in the same scope to safely handle that by checking for the variable (e.g., if
"turn_context" in locals() and turn_context is not None) before calling
turn_context.send_activity, otherwise fall back to a safe alternative such as
using the bot adapter to send a proactive message or simply logging the error
and returning web.Response(status=200); ensure the check uses the exact symbol
turn_context and that any fallback uses existing adapter/logger symbols
available in the surrounding function.
- Around line 404-440: The authenticate_request function currently does only a
superficial token-length check and ignores app_credentials; replace that stub
with a real Bot Framework JWT validation by parsing the incoming request body
into an Activity (e.g., await request.json() -> Activity(...)) and calling await
JwtTokenValidation.authenticate_request(activity, auth_header, app_credentials);
return True when that call succeeds, catch and log JwtTokenValidation exceptions
and return False on failure, ensure the app_credentials argument is used, and if
you keep the TEAMS_DEV_MODE bypass preserve it only for explicit local dev use
with a clear log entry.
🧹 Nitpick comments (5)
examples/teams/teams_agent.py (3)

75-84: Unused rate_limiter field in TeamsAgentRuntime.

The rate_limiter field is initialized in __post_init__ but never used. The actual rate limiting is performed by a separate RateLimiter instance created in TeamsAgentBot.__init__ (line 167). This is confusing and appears to be dead code.

Consider removing the unused field:

♻️ Proposed fix
 `@dataclass`(slots=True)
 class TeamsAgentRuntime:
     chosen_profile: ReasonerProfile = ReasonerProfile.REWOO
     current_agent: Optional[StandardAgent] = None
     app_credentials: Optional[MicrosoftAppCredentials] = None
-    rate_limiter: Dict[str, deque] = None
-    
-    def __post_init__(self):
-        if self.rate_limiter is None:
-            self.rate_limiter = defaultdict(deque)

87-117: Consider cleanup mechanism for inactive users in RateLimiter.

The requests dictionary grows unboundedly as new users interact with the bot. While individual user deques are pruned of old timestamps, entries for inactive users are never removed. In a long-running bot with many transient users, this could lead to gradual memory growth.

For a production deployment, consider adding periodic cleanup of users with empty deques or using a TTL-based cache.


143-156: Unused bot_mention parameter.

The bot_mention parameter is declared but never used in the function body. Either remove it or implement the intended functionality (e.g., removing a specific bot mention pattern).

♻️ Proposed fix
-def extract_goal_from_mention(text: str, bot_mention: str = None) -> str:
+def extract_goal_from_mention(text: str) -> str:
     """Extract goal from message text, removing bot mentions."""
     if not text:
         return ""
examples/teams/README.md (2)

204-226: Add language specifiers to fenced code blocks.

The usage example code blocks (lines 208-210, 214-216, 220-226) are missing language specifiers, which affects syntax highlighting and linting.

📝 Proposed fix
 ### In Teams Channels or Group Chats
 Mention the bot with your goal:
-```
+```text
 `@StandardAgent` find recent articles about machine learning

Direct Messages

Send a direct message to the bot:
- +text
Help me plan a software architecture for a web application


### Commands
Use slash commands for configuration:
-```
+```text
/help
/configure
/reasoner react
/reasoner list
/kill
</details>

---

`341-346`: **Rate limiting is already implemented — update documentation.**

The documentation suggests "consider implementing rate limiting" as a future consideration, but the code already implements per-user rate limiting in `RateLimiter` class (20 requests per 300 seconds). Update this section to reflect the actual implementation.


<details>
<summary>📝 Proposed fix</summary>

```diff
 ### Rate Limiting
 
-Consider implementing rate limiting to prevent abuse:
-- Per-user rate limits
-- Per-conversation rate limits
-- Global rate limits
+Rate limiting is implemented to prevent abuse:
+- Per-user rate limits: 20 requests per 5 minutes (configurable)
+
+Consider adding for enhanced protection:
+- Per-conversation rate limits
+- Global rate limits
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df03617 and 48253dc.

📒 Files selected for processing (3)
  • examples/teams/README.md
  • examples/teams/requirements.txt
  • examples/teams/teams_agent.py
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
examples/teams/README.md

208-208: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


214-214: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


220-220: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 Ruff (0.14.11)
examples/teams/teams_agent.py

71-71: Avoid specifying long messages outside the exception class

(TRY003)


143-143: Unused function argument: bot_mention

(ARG001)


143-143: PEP 484 prohibits implicit Optional

Convert to T | None

(RUF013)


225-225: Do not catch blind exception: Exception

(BLE001)


226-226: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


251-251: Do not catch blind exception: Exception

(BLE001)


252-252: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


276-276: Do not catch blind exception: Exception

(BLE001)


277-277: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


395-395: Do not catch blind exception: Exception

(BLE001)


396-396: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


404-404: Unused function argument: app_credentials

(ARG001)


432-432: Consider moving this statement to an else block

(TRY300)


434-434: Do not catch blind exception: Exception

(BLE001)


435-435: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


438-438: Do not catch blind exception: Exception

(BLE001)


439-439: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


484-484: Do not catch blind exception: Exception

(BLE001)


485-485: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


494-494: Do not catch blind exception: Exception

(BLE001)


495-495: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


524-524: Unused function argument: request

(ARG001)


549-549: Possible binding to all interfaces

(S104)


573-573: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (3)
examples/teams/teams_agent.py (2)

549-549: Binding to all interfaces is intentional for container deployment.

The 0.0.0.0 binding is appropriate for Docker/Kubernetes deployments where the container needs to accept connections from the host network. The README documents this deployment pattern.


1-51: Good overall structure and patterns.

The implementation follows a clean architecture with proper separation of concerns:

  • Configuration loading via TeamsConfig.from_env()
  • Runtime state management via TeamsAgentRuntime
  • Bot handler with comprehensive error handling
  • Input validation and rate limiting
  • Async patterns with proper timeout handling

The code aligns well with the existing Slack/Discord examples as intended by the issue requirements.

examples/teams/README.md (1)

1-4: Comprehensive and well-structured documentation.

The README provides thorough setup instructions covering Azure bot registration, Teams app manifest creation, local development with ngrok, and deployment options. This meets the acceptance criteria from issue #88 for setup documentation.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1 to +18
# Microsoft Bot Framework dependencies
botbuilder-core>=4.15.0,<5.0.0
botframework-connector>=4.15.0,<5.0.0
botbuilder-schema>=4.15.0,<5.0.0

# Web server dependencies
aiohttp>=3.8.0,<4.0.0
aiohttp-cors>=0.7.0,<1.0.0

# Configuration and environment
python-dotenv>=1.0.0,<2.0.0

# Security and authentication (optional but recommended)
cryptography>=41.0.0

# Development and testing (optional)
pytest>=7.0.0
pytest-asyncio>=0.21.0 No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and look at its exact content including the end
cat -n examples/teams/requirements.txt | tail -5
# Also check with hexdump to see if there's a trailing newline
tail -c 20 examples/teams/requirements.txt | od -c

Repository: jentic/standard-agent

Length of output: 255


🌐 Web query:

latest version of botbuilder-core python package

💡 Result:

The latest botbuilder-core (Python) release is 4.17.1 — uploaded to PyPI on January 5, 2026. [1][2]

Sources:
[1] PyPI project page for botbuilder-core.
[2] piwheels release listing for botbuilder-core.


🌐 Web query:

cryptography python package latest version 2025

💡 Result:

The PyCA "cryptography" package latest release in 2025 was version 46.0.3, published on October 15, 2025. [1][2]

Sources:

  • PyPI release details for cryptography. [1]
  • cryptography changelog (46.0.0 release notes). [2]

🌐 Web query:

aiohttp python package latest stable version 2025

💡 Result:

The latest stable aiohttp release in 2025 was version 3.13.1 (released October 17, 2025). [1][2]

Sources:

  • aiohttp changelog (3.13.1 entry). [1]
  • PyPI release history (shows v3.13.3 uploaded Jan 3, 2026 — outside 2025). [2]

Add an upper bound to cryptography for safety.

The version ranges for Bot Framework packages and aiohttp are well-constrained. However:

Line 14: cryptography>=41.0.0 lacks an upper bound, which could break on a major version bump (latest is 46.0.3). Add <47.0.0 to constrain to compatible versions.

The dev dependencies without upper bounds (pytest, pytest-asyncio) are acceptable for development packages.

🤖 Prompt for AI Agents
In `@examples/teams/requirements.txt` around lines 1 - 18, The cryptography
dependency line currently reads "cryptography>=41.0.0" and lacks an upper bound;
update that requirement to include an upper bound (e.g., change to
"cryptography>=41.0.0,<47.0.0") so the cryptography package is constrained to a
safe major-version range.

Comment on lines +267 to +271
except Exception as exc:
logger.exception("teams_message_error", error=str(exc), user_id=user_id)
error_msg = "🚨 An unexpected error occurred. Our team has been notified."
await turn_context.send_activity(MessageFactory.text(error_msg))

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential NameError if exception occurs before user_id is assigned.

If an exception occurs before line 177 (e.g., if turn_context.activity is malformed), user_id will be undefined, causing a NameError on line 268.

🐛 Proposed fix
     async def on_message_activity(self, turn_context: TurnContext):
         """Handle incoming messages with rate limiting and security."""
+        user_id = "unknown"
         try:
             # Get user ID for rate limiting
             user_id = turn_context.activity.from_property.id if turn_context.activity.from_property else "unknown"
🤖 Prompt for AI Agents
In `@examples/teams/teams_agent.py` around lines 267 - 271, The except block that
calls logger.exception("teams_message_error", error=str(exc), user_id=user_id)
can raise a NameError if user_id wasn't set earlier; update the except handler
in the teams_agent.py except Exception as exc block to resolve user_id safely
(e.g., derive it from turn_context.activity.from_property.id if present, or use
a fallback like None or "unknown") before passing it to logger.exception and
sending the error message; ensure you reference the same safe variable name
(user_id) when logging so the logger call can never reference an undefined
symbol.

Comment on lines +347 to +354
async def _handle_kill_command(self, turn_context: TurnContext):
"""Handle the kill command."""
self.runtime.current_agent = None
os.environ.pop("JENTIC_AGENT_API_KEY", None)
logger.warning("agent_killed")
await turn_context.send_activity(
MessageFactory.text("Agent killed. API key cleared; new requests will be rejected until reconfigured.")
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

/kill command affects all users in shared deployment.

The /kill command clears the API key from the process environment (os.environ.pop), which affects all users of the bot instance. In a shared deployment, any user could disable the bot for everyone.

Consider:

  1. Adding authorization checks (e.g., only admins can run /kill)
  2. Making the API key per-conversation rather than global
  3. At minimum, documenting this behavior clearly

Comment on lines +404 to +440
async def authenticate_request(request: Request, app_credentials: MicrosoftAppCredentials) -> bool:
"""Authenticate incoming requests from Teams."""
try:
auth_header = request.headers.get("Authorization", "")
if not auth_header:
logger.warning("missing_auth_header")
return False

# Extract the token from the auth header
parts = auth_header.split(" ")
if len(parts) != 2 or parts[0].lower() != "bearer":
logger.warning("invalid_auth_header_format")
return False

token = parts[1]

if os.getenv("TEAMS_DEV_MODE", "").lower() == "true":
logger.warning("teams_dev_mode_enabled_skipping_auth")
return True

# Validate the JWT token using Bot Framework validation
# Note: This is a simplified implementation
# In production, implement proper JWT validation with claims verification
try:
if not token or len(token) < 50:
logger.warning("invalid_token_format")
return False

return True

except Exception as validation_exc:
logger.error("token_validation_failed", error=str(validation_exc))
return False

except Exception as exc:
logger.error("auth_failed", error=str(exc))
return False
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the teams_agent.py file
find . -name "teams_agent.py" -type f

Repository: jentic/standard-agent

Length of output: 96


🏁 Script executed:

# Check the imports at the top of the file to see if JwtTokenValidation is imported
head -50 examples/teams/teams_agent.py

Repository: jentic/standard-agent

Length of output: 1238


🏁 Script executed:

# Examine the authenticate_request function more closely
sed -n '404,440p' examples/teams/teams_agent.py

Repository: jentic/standard-agent

Length of output: 1485


🏁 Script executed:

# Search for any JwtTokenValidation usage in the codebase
rg "JwtTokenValidation" --type py

Repository: jentic/standard-agent

Length of output: 118


🏁 Script executed:

# Check if app_credentials is used anywhere in the authenticate_request function
sed -n '404,440p' examples/teams/teams_agent.py | rg "app_credentials"

Repository: jentic/standard-agent

Length of output: 164


🏁 Script executed:

# Also check the full imports section to see what's available
rg "from botframework" examples/teams/teams_agent.py

Repository: jentic/standard-agent

Length of output: 157


🌐 Web query:

botframework-connector JwtTokenValidation authenticate_activity Python documentation

💡 Result:

The Python Bot Framework connector exposes JwtTokenValidation.authenticate_request(...) (not authenticate_activity). See the API docs for the class and the authenticate_request signature and parameters. [1][2]

References

  • JwtTokenValidation class (authenticate_request signature). [1]
  • botframework-connector package (PyPI). [2]

Authentication is effectively a no-op — critical security vulnerability.

The authenticate_request function does not perform actual JWT token validation. It only checks that:

  1. An Authorization header exists
  2. It follows Bearer format
  3. The token is at least 50 characters

The app_credentials parameter is unused, and the comment on lines 425-426 acknowledges this is "simplified." However, this allows any request with a valid-looking header to pass authentication, potentially enabling unauthorized access.

Additionally, TEAMS_DEV_MODE=true bypasses authentication entirely, and JwtTokenValidation is imported but never used.

Implement proper JWT validation using the Bot Framework's JwtTokenValidation.authenticate_request() method instead of the stub length check:

claims = await JwtTokenValidation.authenticate_request(
    activity, 
    auth_header,
    app_credentials
)
🧰 Tools
🪛 Ruff (0.14.11)

404-404: Unused function argument: app_credentials

(ARG001)


432-432: Consider moving this statement to an else block

(TRY300)


434-434: Do not catch blind exception: Exception

(BLE001)


435-435: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


438-438: Do not catch blind exception: Exception

(BLE001)


439-439: Use logging.exception instead of logging.error

Replace with exception

(TRY400)

🤖 Prompt for AI Agents
In `@examples/teams/teams_agent.py` around lines 404 - 440, The
authenticate_request function currently does only a superficial token-length
check and ignores app_credentials; replace that stub with a real Bot Framework
JWT validation by parsing the incoming request body into an Activity (e.g.,
await request.json() -> Activity(...)) and calling await
JwtTokenValidation.authenticate_request(activity, auth_header, app_credentials);
return True when that call succeeds, catch and log JwtTokenValidation exceptions
and return False on failure, ensure the app_credentials argument is used, and if
you keep the TEAMS_DEV_MODE bypass preserve it only for explicit local dev use
with a clear log entry.

Comment on lines +513 to +518
except Exception as processing_exc:
logger.exception("activity_processing_failed", error=str(processing_exc))
await turn_context.send_activity(
MessageFactory.text("Sorry, I encountered an error processing your request. Please try again.")
)
return web.Response(status=200)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential NameError: turn_context may be undefined.

If an exception occurs on lines 499-505 (before turn_context is created on line 506), the error handler on line 515 will raise a NameError when trying to use turn_context.

🐛 Proposed fix
+            turn_context = None
             try:
                 credentials = MicrosoftAppCredentials(
                     runtime.app_credentials.microsoft_app_id,
                     runtime.app_credentials.microsoft_app_password
                 )
                 
                 connector_client = ConnectorClient(credentials, base_url=activity.service_url)
                 
                 turn_context = TurnContext(bot, activity)
                 turn_context.turn_state[TurnContext.connector_client_key] = connector_client
                 
                 await bot.on_turn(turn_context)
                 
                 return web.Response(status=200)
                 
             except Exception as processing_exc:
                 logger.exception("activity_processing_failed", error=str(processing_exc))
-                await turn_context.send_activity(
-                    MessageFactory.text("Sorry, I encountered an error processing your request. Please try again.")
-                )
+                if turn_context:
+                    await turn_context.send_activity(
+                        MessageFactory.text("Sorry, I encountered an error processing your request. Please try again.")
+                    )
                 return web.Response(status=200)
🤖 Prompt for AI Agents
In `@examples/teams/teams_agent.py` around lines 513 - 518, The exception handler
references turn_context which may not be defined if the error occurs before it's
created; update the except block in the same scope to safely handle that by
checking for the variable (e.g., if "turn_context" in locals() and turn_context
is not None) before calling turn_context.send_activity, otherwise fall back to a
safe alternative such as using the bot adapter to send a proactive message or
simply logging the error and returning web.Response(status=200); ensure the
check uses the exact symbol turn_context and that any fallback uses existing
adapter/logger symbols available in the surrounding function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Good First Issue] [Examples] Create Microsoft Teams bot example

2 participants