Files
agent-framework/python/AGENTS.md
Eduard van Valkenburg e5a6e35843 Python: feat(python): cross-channel hosting improvements (endpoint paths, Activity push, Telegram/Teams fixes) (#6307)
* Update hosting channel endpoint paths

Treat channel paths as concrete endpoint paths so built-in channels can be mounted at their defaults or at the app root without sample-specific subclasses. Update docs, tests, and the Foundry Telegram Invocations sample accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add push support to ActivityProtocolChannel

Implement the ChannelPush protocol so the Activity Protocol channel can
receive cross-channel fan-out (ResponseTarget.all_linked) and echo_input
replay as a non-originating destination:

- Add push() that reconstructs a proactive Bot Framework activity (bot/user
  swap) from the stored conversation reference and POSTs it to
  /v3/conversations/{id}/activities.
- Record a ChannelIdentity (service_url, conversation, bot, user, channel_id,
  locale) on ChannelRequest.identity so the host registers the channel under
  its isolation key for fan-out resolution.
- Route the streaming path through deliver_response so Activity-originated
  turns broadcast like Telegram/Discord.
- Add tests for push delivery, service_url validation, ChannelPush instance
  check, and inbound identity recording.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Don't delete Telegram webhook on shutdown by default

The TelegramChannel deleted its webhook on shutdown in webhook mode. During
a rolling redeploy the new revision registers the webhook on startup, then
the old revision's shutdown deletes it, silently breaking inbound delivery
until the next boot. setWebhook is overwriting/idempotent, so startup
re-asserts the webhook every boot and no teardown is needed.

Add a delete_webhook_on_shutdown flag (default False) so teardown is opt-in
for ephemeral deployments, and leave the webhook in place otherwise.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix Activity channel streaming on non-Teams channels (405 on updateActivity)

The Activity Protocol channel streamed replies the Teams way: POST a
placeholder, then PUT-edit it as tokens arrive. Only Teams supports the
updateActivity REST op; Web Chat, Direct Line and the Emulator return
405 Method Not Allowed on the PUT, so the user saw only the placeholder.

Gate the placeholder+edit flow on edit-capable channels (msteams). Other
channels now buffer the stream and POST a single final message, mirroring
the non-streaming path's fan-out and response-hook semantics. Also add a
defensive 405 fallback inside the Teams edit loop so an unexpected 405
can never strand the user on the placeholder.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(hosting-activity-protocol): don't parse Teams inline attachment content as a URI

Teams message activities include a text/html attachment whose inline
`content` is raw HTML (not a URL). _parse_activity fell back to
`attachment["content"]` and passed it to Content.from_uri, raising
ContentError ("URI must contain a scheme") and failing the whole turn,
so Teams users got no response.

Only treat `contentUrl` as a URI, require an absolute scheme, and skip
unparseable attachments defensively instead of failing the message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat(hosting-activity-protocol): native slash-command dispatch for Teams/Activity

Add a commands= parameter to ActivityProtocolChannel that intercepts a
leading /command (after stripping the bot's own @mention) and dispatches
to ChannelCommand handlers, mirroring the Telegram channel. Unknown
commands fall through to the agent. The channel run_hook is applied to
command requests so handlers observe the same resolved isolation key as
ordinary messages, and handler errors are swallowed (200, no Bot Service
retry of non-idempotent commands).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat(hosting): silent attributed Telegram echoes + Teams markdown rendering

- hosting-telegram: send cross-channel input echoes with disable_notification
  (silent) and detect echo payloads so they aren't re-broadcast.
- hosting-activity-protocol: render outbound + push activities as textFormat
  'markdown' so Teams shows formatted replies (enables per-channel variants).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(hosting-activity-protocol): address PR #6307 review feedback

Consult the host delivery pipeline even for empty streamed replies so
ResponseTarget.none is honoured and non-originating fan-out is consulted
instead of always emitting an originating "(no response)" message. Applies
to both the progressive-edit (Teams) and buffered (Web Chat/Direct Line)
streaming paths.

Re-validate service_url against the allow-list in push(): the identity is
read from a persisted store and push runs out-of-band, so the captured
service_url must be re-checked before a bearer token is sent.

Adds tests for empty-stream host consultation/suppression on both streaming
paths and for push rejecting a disallowed service_url.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-03 16:37:03 +02:00

5.5 KiB

AGENTS.md

Instructions for AI coding agents working in the Python codebase.

Key Documentation:

Agent Skills (.github/skills/) — detailed, task-specific instructions loaded on demand:

  • python-development — coding standards, type annotations, docstrings, logging, performance
  • python-testing — test structure, fixtures, async mode, running tests
  • python-code-quality — linting, formatting, type checking, prek hooks, CI workflow
  • python-feature-lifecycle — package vs feature lifecycle stages, decorators, enums, and promotion guidance
  • python-package-management — monorepo structure, lazy loading, versioning, new packages
  • python-samples — sample file structure, PEP 723, documentation guidelines

Maintaining Documentation

When making changes to a package, check if the following need updates:

  • The package's AGENTS.md file (adding/removing/renaming public APIs, architecture changes, import path changes)
  • The agent skills in .github/skills/ if conventions, commands, or workflows change

At the end of every run, re-read AGENTS.md and the relevant skill files and update any guidance that the conversation revealed to be out of date, incomplete, or misleading (renamed files, changed commands, new conventions the user confirmed, etc.). Before adding a new principle or rule, ask the user whether they want it captured as a durable principle — do not invent team norms from a single conversation without explicit confirmation.

Terminology

  • Avoid "GA" for Agent Framework code. Reserve GA for hosted services (e.g. "the Foundry service is GA"). For Agent Framework packages, features, and APIs use "released" or "stable" depending on context — these match the feature-lifecycle stages documented in the python-feature-lifecycle skill.

Pull Request Description Guidance

When preparing a PR description:

  • Follow the repository PR template at .github/pull_request_template.md and keep its structure/headings.
  • Describe the net change relative to main (this is implied; do not call it out explicitly as "vs main").
  • Do not add ad-hoc validation sections (for example, "Validation" or "Tests run"); CI/CD and the template checklist cover validation status.

Quick Reference

Run uv run poe from the python/ directory to see available commands. See DEV_SETUP.md for detailed usage.

Project Structure

python/
├── packages/
│   ├── core/                 # agent-framework-core (main package)
│   │   ├── agent_framework/  # Public API exports
│   │   └── tests/
│   ├── foundry/              # agent-framework-foundry
│   ├── anthropic/            # agent-framework-anthropic
│   ├── ollama/               # agent-framework-ollama
│   └── ...                   # Other provider packages
├── samples/                  # Sample code and examples
├── .github/skills/           # Agent skills for Copilot
└── tests/                    # Integration tests

Package Relationships

  • agent-framework-core contains core abstractions and OpenAI/Azure OpenAI built-in
  • Provider packages (foundry, anthropic, etc.) extend core with specific integrations
  • Core uses lazy loading via __getattr__ in provider folders (e.g., agent_framework/azure/)

Package Documentation

Core

  • core - Core abstractions, types, and built-in OpenAI/Azure OpenAI support

LLM Providers

Azure Integrations

Protocols & UI

  • a2a - Agent-to-Agent protocol
  • ag-ui - AG-UI protocol
  • chatkit - OpenAI ChatKit integration
  • devui - Developer UI for testing

Storage & Memory

  • mem0 - Mem0 memory integration
  • redis - Redis storage

Infrastructure

Experimental

  • lab - Experimental features
  • monty - Monty-backed CodeAct integrations (alpha)