Skip to content

Feature/add teams integration#202

Open
pulinduvidmal wants to merge 79 commits intodevelopfrom
feature/add_teams_integration
Open

Feature/add teams integration#202
pulinduvidmal wants to merge 79 commits intodevelopfrom
feature/add_teams_integration

Conversation

@pulinduvidmal
Copy link
Contributor

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update
  • CI/CD update
  • Other (please describe):

Related Issues

Fixes #
Relates to #

Changes Made

  • Added Teams handler: AgentTeamsRequestHandler
  • Created example app in examples/api/teams/
  • Added config and build scripts
  • Updated documentation and README

Testing

  • Unit tests pass locally
  • Integration tests pass locally
  • Manual testing completed
  • New tests added for changes

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Additional Notes

pulinduvidmal and others added 30 commits December 23, 2025 21:13
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 34 changed files in this pull request and generated 18 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings February 25, 2026 19:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 36 out of 42 changed files in this pull request and generated 11 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


config = getattr(AKConfig.get(), "multimodal", None)
if config and config.enabled:
self.override_system_prompt(session=None, prompt=self.get_system_prompt_suffix())
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

override_system_prompt is called with session=None here, but the abstract method is typed as requiring a Session. Update the abstract/implementations to accept Session | None (or remove the unused session parameter) to keep the API contract consistent.

Suggested change
self.override_system_prompt(session=None, prompt=self.get_system_prompt_suffix())
self.override_system_prompt(session=Session(), prompt=self.get_system_prompt_suffix())

Copilot uses AI. Check for mistakes.
```bash
export AK_MULTIMODAL__ENABLED=true # Enable multimodal support (default: false)
export AK_MULTIMODAL__MAX_ATTACHMENTS=5 # Keep last N files in session (default: 5)
export AK_MULTIMODAL__ATTACHMENT_TTL=604800 # File lifetime in seconds (default: 604800 = 1 week)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

AK_MULTIMODAL__ATTACHMENT_TTL is documented here, but there is no corresponding config field/implementation in AKConfig.multimodal or the storage driver. Either implement TTL-based expiry or remove this variable from the docs to avoid configuration drift.

Suggested change
export AK_MULTIMODAL__ATTACHMENT_TTL=604800 # File lifetime in seconds (default: 604800 = 1 week)

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +11
# For local development of agentkernel, you can force reinstall from local dist
uv sync --find-links ../../../ak-py/dist --all-extras
uv pip install --force-reinstall --find-links ../../../ak-py/dist agentkernel[api,openai,teams] || true
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The install step is allowed to fail silently (|| true), which can leave the environment in a broken state while still exiting successfully (hard to debug). Prefer failing the script on install errors, or at least print a clear warning and exit non-zero if the expected package/extras are not installed.

Copilot uses AI. Check for mistakes.
Comment on lines +118 to +122
description = await describe_attachment_briefly(
data=req.image_data,
mime_type=req.mime_type or "image/jpeg",
)

Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

description_max_length is configurable but not enforced when generating/storing descriptions. Without truncation, long model outputs can bloat injected prompts and session cache entries. Truncate description using config.description_max_length before saving/injecting.

Copilot uses AI. Check for mistakes.
enabled_routes: _RoutesConfig = Field(description="API route flags", default_factory=_RoutesConfig)
custom_router_prefix: str = Field(default="/custom", description="Custom router prefix")
max_file_size: int = Field(default=2097152, description="Maximum file size in bytes (default: 2 MB)")
max_file_size: int = Field(default=20971520, description="Maximum file size in bytes (default: 20 MB)")
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The default api.max_file_size is increased from 2MB to 20MB. This can significantly increase memory/network usage for integrations that base64-encode uploads (Telegram/Teams) and for session caches. If the higher limit is required for multimodal, consider making this integration-specific (or documenting the operational impact) rather than changing the global default.

Suggested change
max_file_size: int = Field(default=20971520, description="Maximum file size in bytes (default: 20 MB)")
max_file_size: int = Field(default=2097152, description="Maximum file size in bytes (default: 2 MB)")

Copilot uses AI. Check for mistakes.

```bash
export AK_MULTIMODAL__ENABLED=true # Enable multimodal support (default: false)
export AK_MULTIMODAL__MAX_ATTACHMENTS=5 # Keep last N files in session (default: 5)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The docs state AK_MULTIMODAL__MAX_ATTACHMENTS defaults to 5, but AKConfig.multimodal.max_attachments defaults to 20. Align the documentation with the actual default (or change the default) to avoid unexpected per-session storage growth.

Suggested change
export AK_MULTIMODAL__MAX_ATTACHMENTS=5 # Keep last N files in session (default: 5)
export AK_MULTIMODAL__MAX_ATTACHMENTS=20 # Keep last N files in session (default: 20)

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +100
# Bot Framework expects a dict with 'body' as parsed JSON
req_dict = {"body": json.loads(body_text), "headers": {"Authorization": auth_header}} # Parse JSON

# Process the activity using Bot Framework adapter
async def bot_logic(turn_context: TurnContext):
await self._handle_teams_message(turn_context)

# Process the request - Bot Framework validates auth internally
await self._adapter.process_activity(req_dict, auth_header, bot_logic)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

process_activity is typically called with an Activity object (or a raw Activity dict), not a wrapper dict containing {body, headers}. Passing req_dict here is likely to break message handling at runtime. Deserialize the request JSON into an Activity and pass that to process_activity per the BotBuilder SDK signature.

Suggested change
# Bot Framework expects a dict with 'body' as parsed JSON
req_dict = {"body": json.loads(body_text), "headers": {"Authorization": auth_header}} # Parse JSON
# Process the activity using Bot Framework adapter
async def bot_logic(turn_context: TurnContext):
await self._handle_teams_message(turn_context)
# Process the request - Bot Framework validates auth internally
await self._adapter.process_activity(req_dict, auth_header, bot_logic)
# Parse the request body JSON into an Activity dict for the Bot Framework adapter
activity = json.loads(body_text)
# Process the activity using Bot Framework adapter
async def bot_logic(turn_context: TurnContext):
await self._handle_teams_message(turn_context)
# Process the request - Bot Framework validates auth internally
await self._adapter.process_activity(activity, auth_header, bot_logic)

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +43
export AK_MULTIMODAL__ENABLED=true # Enable multimodal support (default: false)
export AK_MULTIMODAL__MAX_ATTACHMENTS=5 # Keep last N files in session (default: 5)
export AK_MULTIMODAL__ATTACHMENT_TTL=604800 # File lifetime in seconds (default: 604800 = 1 week)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The docs claim multimodal supports AK_MULTIMODAL__MAX_ATTACHMENTS=5 by default, but AKConfig.multimodal.max_attachments defaults to 20. Either align the documented default with config, or change the config default to match the docs to avoid surprising memory growth per session.

Copilot uses AI. Check for mistakes.
Comment on lines +58 to +62
import litellm

response = litellm.completion(
model=model_name,
messages=[{"role": "user", "content": content}],
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

analyze_attachments depends on litellm, but litellm is not installed by agentkernel[openai] / agentkernel[telegram] / agentkernel[teams] extras. This makes multimodal analysis fail at runtime even when enabled. Consider adding a dedicated multimodal extra (or including litellm in relevant extras) and catch ImportError here to return an actionable install message.

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +152
"""Configuration for multimodal attachment memory."""

enabled: bool = Field(
default=False,
description="Enable multimodal memory for images and files.",
)
max_attachments: int = Field(default=20, description="Maximum number of attachments to keep per session")
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

With multimodal enabled, attachments are cached per session; max_attachments defaults to 20, which combined with a 20MB max file size can allow very large per-session storage (plus base64 overhead). Consider lowering the default or documenting this tradeoff clearly so deployments don’t unexpectedly consume large amounts of cache/memory.

Suggested change
"""Configuration for multimodal attachment memory."""
enabled: bool = Field(
default=False,
description="Enable multimodal memory for images and files.",
)
max_attachments: int = Field(default=20, description="Maximum number of attachments to keep per session")
"""Configuration for multimodal attachment memory.
Attachments are cached in memory on a per-session basis. Large values combined
with large attachment sizes and many concurrent sessions can significantly
increase memory usage; tune these settings according to your deployment limits.
"""
enabled: bool = Field(
default=False,
description="Enable multimodal memory for images and files.",
)
max_attachments: int = Field(
default=20,
description=(
"Maximum number of attachments to keep per session in the in-memory cache. "
"Higher values, especially with large attachments and many concurrent sessions, "
"can substantially increase cache/memory usage; adjust based on deployment limits."
),
)

Copilot uses AI. Check for mistakes.
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.

3 participants