Skip to content

Add autonomous Teams .NET sample synchronization - #726

Open
Joel Mut (sw-joelmut) wants to merge 5 commits into
mainfrom
southworks/add/automation-teams-samples
Open

Joel Mut (sw-joelmut) wants to merge 5 commits into
mainfrom
southworks/add/automation-teams-samples

Conversation

@sw-joelmut

@sw-joelmut Joel Mut (sw-joelmut) commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Fixes #691

Note

The workflow uses Copilot Auto with the known-working Copilot SDK 1.0.7 and CLI runtime 1.0.83.

Note

Copilot SDK Auto tier routing (balance) requires SDK v1.0.13+ and model: "auto". This sample currently uses a turn-scoped, per-user GitHub OAuth token (GitHubToken), while Auto-tier configuration is not supported with that static-token session setup. Enabling it would require a separate token-provider design that can safely refresh each user’s OAuth credential outside the originating Teams turn. We are intentionally not making that authentication change in this PR.

Description

Add an autonomous workflow that synchronizes selected Microsoft Teams SDK .NET samples with their Agents SDK counterparts.

The workflow creates a frozen migration plan, implements it through one persistent Copilot session, validates the result, and publishes only a verified patch. It limits Copilot write access to the selected sample and keeps repository credentials out of the migration job.

This PR also adds seven migrated Teams samples, reusable migration and manifest skills, deterministic validators, contract tests, and incremental synchronization state.

Changes

GitHub Actions workflow

  • Add a manual workflow with separate plan, migrate, and publish jobs.
  • Add a dropdown to select one sample or all configured samples.
  • Add an option to create draft pull requests for verified changes.
  • Run each selected sample in an independent matrix job.
  • Pin the upstream commit and repository base SHA for each run.
  • Store plans, patches, results, diagnostics, and Copilot transcripts as workflow artifacts.
  • Show useful failure information in GitHub annotations and workflow summaries.
  • Prevent the migration job from receiving repository-write credentials.
  • Apply and verify generated patches only in the publish job.

Autonomous migration

  • Use one persistent Copilot session for planning and implementation.
  • Freeze and hash the migration plan before write access is enabled.
  • Continue incomplete planning responses without waiting for user confirmation.
  • Require a structured Markdown self-audit after implementation.
  • Allow one repair attempt for deterministic validation failures.
  • Restrict edits to the selected sample.
  • Exclude shell and terminal tools from the Copilot session.
  • Use Copilot Auto without selecting a fixed model.
  • Keep SDK 1.0.7 and runtime 1.0.83 for known compatibility.
  • Add a TODO for the future balance auto tier.

Migration and manifest skills

  • Add a Teams SDK to Agents SDK .NET migration skill.
  • Add a Teams app manifest skill with reusable templates and reference material.
  • Define canonical manifest schema and capability validation rules.
  • Verify command titles and command surfaces against handlers, documentation, and manifest JSON.
  • Register the skills in the relevant plugin manifests and marketplace configuration.

Validation and reporting

  • Add source-context and component-digest tracking.
  • Add selected-sample path confinement and patch verification.
  • Validate .NET projects, manifests, README instructions, package policy, and expected capabilities.
  • Add contract tests for messages, attachments, cards, meetings, message extensions, targeted messages, and task modules.
  • Report no-change results explicitly.
  • Preserve detailed Copilot output in diagnostic artifacts while keeping workflow output concise.

Migrated samples

  • Add agent-targeted-messages.
  • Add bot-ai-messages.
  • Add bot-attachments.
  • Add bot-cards.
  • Add bot-meetings.
  • Add bot-message-extensions.
  • Add bot-task-modules.
  • Register the samples in the .NET solution.

Testing

  • Ran npm test --prefix automation/teams-sample-sync.
    • 19 tests passed.
    • The opt-in live Copilot SDK smoke test was skipped.
  • Ran npm run build --prefix automation/teams-sample-sync.
  • Exercised the workflow through manual GitHub Actions runs to validate matrix execution, autonomous continuation, diagnostic artifacts, and failure reporting.

The following image shows the workflow working.
imagen

Comment thread automation/teams-sample-sync/src/report.ts Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved critical and moderate findings remain in validation, manifests, sample behavior, queue handling, and migration guidance.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds an autonomous workflow to synchronize seven Teams SDK .NET samples into Agents SDK samples, with Copilot-driven migration, validation, state tracking, manifests, and contract tests.

Changes:

  • Added bounded plan, migrate, and publish workflow jobs.
  • Added migration and manifest skills, validators, reporting, and tests.
  • Added seven migrated samples and solution registrations.

Additional findings remain in migration guidance, validation, and sample implementations, including critical and moderate issues.

File summaries
File Summary
samples/dotnet/teams/bot-task-modules/README.md Documents task-module usage. Nit (2 votes): prerequisite should reference .NET 10. Moderate (1 vote): remove or implement undocumented permissions.
samples/dotnet/teams/bot-task-modules/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/bot-task-modules/Program.cs Configures the Agents host.
samples/dotnet/teams/bot-task-modules/pages/CustomForm/index.html Provides the custom task-module form.
samples/dotnet/teams/bot-task-modules/BotTaskModules.csproj Defines project dependencies.
samples/dotnet/teams/bot-task-modules/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/bot-task-modules/appsettings.json Adds runtime configuration.
samples/dotnet/teams/bot-task-modules/appManifest/manifest.json Adds the Teams app manifest. Moderate (1 vote): align permission declarations with the README and behavior.
samples/dotnet/teams/bot-message-extensions/README.md Documents message-extension usage. Nit (2 votes): prerequisite should reference .NET 10.
samples/dotnet/teams/bot-message-extensions/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/bot-message-extensions/Program.cs Configures the Agents host.
samples/dotnet/teams/bot-message-extensions/BotMessageExtensionsAgent.cs Implements search and link-unfurling handlers.
samples/dotnet/teams/bot-message-extensions/BotMessageExtensions.csproj Defines project dependencies.
samples/dotnet/teams/bot-message-extensions/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/bot-message-extensions/appsettings.json Adds runtime configuration.
samples/dotnet/teams/bot-message-extensions/appPackage/manifest.json Adds the messaging-extension manifest. Moderate (1 vote): narrow the link-handler domain and use the approved 1.22 schema baseline.
samples/dotnet/teams/bot-meetings/README.md Documents meeting events and Graph setup. Nit (2 votes): prerequisite should reference .NET 10.
samples/dotnet/teams/bot-meetings/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/bot-meetings/Program.cs Configures the Agents host.
samples/dotnet/teams/bot-meetings/BotMeetings.csproj Defines project dependencies.
samples/dotnet/teams/bot-meetings/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/bot-meetings/appsettings.json Adds bot and Graph configuration.
samples/dotnet/teams/bot-meetings/appManifest/manifest.json Adds the Teams app manifest. Moderate (1 vote): include the documented personal scope.
samples/dotnet/teams/bot-cards/README.md Documents card behaviors. Nit (2 votes): prerequisite should reference .NET 10.
samples/dotnet/teams/bot-cards/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/bot-cards/Program.cs Configures the Agents host.
samples/dotnet/teams/bot-cards/Cards/Cards.cs Builds adaptive cards.
samples/dotnet/teams/bot-cards/BotCardsAgent.cs Implements card routes.
samples/dotnet/teams/bot-cards/BotCards.csproj Defines project dependencies.
samples/dotnet/teams/bot-cards/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/bot-cards/appsettings.json Adds runtime configuration.
samples/dotnet/teams/bot-cards/appManifest/manifest.json Adds the Teams app manifest.
samples/dotnet/teams/bot-attachments/Services/PendingUploadStore.cs Stores pending uploads. Moderate (1 vote): serialize capacity check and insertion.
samples/dotnet/teams/bot-attachments/Services/FileUploadQueue.cs Processes background uploads.
samples/dotnet/teams/bot-attachments/README.md Documents the file-consent flow. Nit (2 votes): prerequisite should reference .NET 10.
samples/dotnet/teams/bot-attachments/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/bot-attachments/Program.cs Configures services and host.
samples/dotnet/teams/bot-attachments/Models/FileDownloadInfo.cs Models download metadata.
samples/dotnet/teams/bot-attachments/BotAttachments.csproj Defines project dependencies.
samples/dotnet/teams/bot-attachments/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/bot-attachments/appsettings.json Adds runtime configuration.
samples/dotnet/teams/bot-attachments/appManifest/manifest.json Adds the Teams app manifest.
samples/dotnet/teams/bot-ai-messages/README.md Documents AI message features. Nit (2 votes): prerequisite should reference .NET 10.
samples/dotnet/teams/bot-ai-messages/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/bot-ai-messages/Program.cs Configures the Agents host.
samples/dotnet/teams/bot-ai-messages/BotAiMessagesAgent.cs Implements AI message routes.
samples/dotnet/teams/bot-ai-messages/BotAiMessages.csproj Defines project dependencies.
samples/dotnet/teams/bot-ai-messages/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/bot-ai-messages/appsettings.json Adds runtime configuration.
samples/dotnet/teams/bot-ai-messages/appManifest/manifest.json Adds the Teams app manifest.
samples/dotnet/teams/agent-targeted-messages/ReminderService.cs Schedules proactive reminders.
samples/dotnet/teams/agent-targeted-messages/README.md Documents targeted messaging. Nit (2 votes): prerequisite should reference .NET 10.
samples/dotnet/teams/agent-targeted-messages/Properties/launchSettings.json Adds local launch profile.
samples/dotnet/teams/agent-targeted-messages/Program.cs Configures services and host.
samples/dotnet/teams/agent-targeted-messages/assets/sample.json Adds sample catalog metadata.
samples/dotnet/teams/agent-targeted-messages/appsettings.json Adds runtime configuration.
samples/dotnet/teams/agent-targeted-messages/appManifest/manifest.json Adds the targeted-message manifest. Critical (2 votes): split command entries so trigger surfaces match the README.
samples/dotnet/teams/agent-targeted-messages/AgentTargetedMessages.csproj Defines project dependencies.
samples/dotnet/Samples.sln Registers migrated projects and contract tests.
package.json Pins the root lint dependency.
automation/teams-sample-sync/tsconfig.json Configures TypeScript checking.
automation/teams-sample-sync/tsconfig.build.json Configures TypeScript builds.
automation/teams-sample-sync/tests/unit/workflow-config.test.ts Tests workflow configuration.
automation/teams-sample-sync/tests/unit/validation-path.test.ts Tests validation behavior.
automation/teams-sample-sync/tests/unit/report.test.ts Tests reporting output.
automation/teams-sample-sync/tests/unit/agent-runner.test.ts Tests Copilot session controls.
automation/teams-sample-sync/tests/integration/sdk-smoke.test.ts Adds opt-in SDK smoke coverage.
automation/teams-sample-sync/tests/contracts/TeamsSampleSync.ContractTests.csproj Defines the contract-test project.
automation/teams-sample-sync/tests/contracts/TeamsSampleContracts.cs Tests card and AI contracts.
automation/teams-sample-sync/tests/contracts/TaskModuleContracts.cs Tests task modules.
automation/teams-sample-sync/tests/contracts/TargetedMessageContracts.cs Tests targeted messages.
automation/teams-sample-sync/tests/contracts/MessageExtensionContracts.cs Tests message extensions.
automation/teams-sample-sync/tests/contracts/MeetingContracts.cs Tests meeting behavior.
automation/teams-sample-sync/tests/contracts/AttachmentContracts.cs Tests file-consent behavior.
automation/teams-sample-sync/src/types.ts Defines synchronization contracts.
automation/teams-sample-sync/src/sync-session.ts Implements frozen-plan sessions.
automation/teams-sample-sync/src/state.ts Manages verified state.
automation/teams-sample-sync/src/report.ts Generates workflow reports.
automation/teams-sample-sync/src/plan.ts Creates migration plans.
automation/teams-sample-sync/src/guard.ts Enforces repository confinement.
automation/teams-sample-sync/src/git.ts Provides Git and digest utilities.
automation/teams-sample-sync/src/context.ts Creates immutable source context.
automation/teams-sample-sync/src/config.ts Loads synchronization policy.
automation/teams-sample-sync/src/agent-tools.ts Defines trusted validation tools.
automation/teams-sample-sync/src/agent-runner.ts Runs Copilot sessions.
automation/teams-sample-sync/skills/sync-teams-dotnet-samples-to-agents-sdk/SKILL.md Adds synchronization guidance.
automation/teams-sample-sync/README.md Documents local workflow usage.
automation/teams-sample-sync/prompts/agent-prompt.md Defines the Copilot migration protocol.
automation/teams-sample-sync/package.json Defines automation dependencies and scripts.
automation/teams-sample-sync/config/targets.yml Configures selected samples.
automation/teams-sample-sync/config/ownership.yml Defines protected paths.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/source-detection.md Documents capability detection.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/schema-validation.md Documents manifest validation.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/message-extensions.md Documents message extensions.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/meetings.md Documents meeting manifests.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/cards-and-dialogs.md Documents cards and dialogs.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/capability-ledger.md Defines capability evidence rules.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/bots.md Documents bot capabilities.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/references/authentication-and-permissions.md Documents permissions and domains.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/assets/manifest-evidence.template.md Adds the evidence template.
agent-plugins/agents-sdk-common/skills/teams-app-manifest/assets/base-manifest.template.json Adds the manifest template.
agent-plugins/agents-sdk-common/plugin.json Updates the common plugin version.
agent-plugins/agents-for-net/plugin.json Updates the .NET plugin version.
.gitignore Ignores synchronization artifacts.
.github/workflows/sync-teams-dotnet-samples.yml Adds the synchronization workflow.
.claude-plugin/marketplace.json Updates marketplace versions.
Review details

Files not reviewed (1)

  • automation/teams-sample-sync/package-lock.json: Generated file

Suppressed comments (10)

agent-plugins/agents-for-net/skills/teams-sdk-to-agents-sdk-dotnet-migration/SKILL.md:79

  • The migration skill also requires net8.0, but this synchronization policy validates net10.0 and all seven migrated projects target it. An autonomous migration following this instruction will produce a candidate that fails the deterministic project check; make the framework rule use the configured policy.
**TargetFramework:** the Agents SDK targets `net8.0`. Set `<TargetFramework>net8.0</TargetFramework>`
(Teams SDK samples often target `net10.0`). Set `<ImplicitUsings>disable</ImplicitUsings>` and add
explicit `using` directives (matches Agents SDK sample convention).

agent-plugins/agents-for-net/skills/teams-sdk-to-agents-sdk-dotnet-migration/SKILL.md:38

  • This newly added migration skill tells the agent to emit Agents SDK 1.7.*, while the synchronization policy and every migrated project require 1.8.*. That contradiction can make the agent generate projects the validator rejects; align the skill with the configured 1.8.* policy.
- **Use the latest release Agents SDK packages** The
  base packages (`Microsoft.Agents.Hosting.AspNetCore`, `Microsoft.Agents.Authentication.Msal`, `Microsoft.Agents.Extensions.MSTeams`, and the
  transitive `Microsoft.Agents.Core` / `Builder` / `Connector` / `Storage`) are on the **`1.7.x`** line —
  use the repository's current shared version convention, currently `1.7.*` but use the latest non-beta version.

samples/dotnet/teams/agent-targeted-messages/AgentTargetedMessagesAgent.cs:520

  • The else at line 523 binds only to this hour check, so valid seconds and minutes units fall through to return null. This rejects the documented 30 seconds/minute reminders; use an else if chain or a separate unsupported-unit check so all three unit groups produce a multiplier.
    samples/dotnet/teams/bot-attachments/BotAttachmentsAgent.cs:129
  • When the bounded upload queue is full, the file has already been removed from the incoming turn but its bytes remain in PendingUploadStore; no later path removes them. Repeated queue-full responses can therefore consume the 32-entry pending capacity for 10 minutes without any upload or user notification. Remove the pending item when TryQueue fails (and report the rejection to the user).
    samples/dotnet/teams/bot-attachments/Services/PendingUploadStore.cs:22
  • The capacity check and insert are separate operations, so concurrent attachment requests can all observe a count below 32 and then exceed the configured capacity. Serialize the check-and-add (or reserve a slot atomically) before storing the bytes.
    samples/dotnet/teams/bot-meetings/appManifest/manifest.json:9
  • The README's meeting manifest example includes personal, but this committed manifest only declares team and groupChat. Users following the documented personal/team/group-chat setup cannot install this bot for personal scope; keep the manifest scopes aligned with the documented behavior.
    samples/dotnet/teams/bot-message-extensions/appPackage/manifest.json:67
  • The link handler accepts every *.wikipedia.org subdomain, while the sample generates links only to en.wikipedia.org. This unnecessarily broadens link-unfurling coverage and conflicts with the manifest guidance to use controlled, narrowly scoped domains; use the exact host unless other subdomains are intentionally supported.
    samples/dotnet/teams/bot-message-extensions/appPackage/manifest.json:3
  • The new manifest skill establishes 1.22 as the repository baseline for new Teams agent samples, and all other manifests in this PR use it. This sample instead pins 1.19; use the approved baseline unless a documented capability requires the older schema.
    samples/dotnet/teams/bot-task-modules/README.md:63
  • The setup instructions require identity and messageTeamMembers, but this manifest does not declare them and the sample only replies to the current task-module conversation; those permissions are not needed for this behavior. Users following the README will grant unnecessary permissions and still receive a package that does not contain them. Remove the two permissions from the instructions or add a concrete feature that requires them and declare them in the manifest.
    samples/dotnet/teams/bot-task-modules/appManifest/manifest.json:9
  • The README instructs users that this app needs the root identity and messageTeamMembers permissions, but the package manifest declares neither. An uploaded package therefore does not carry the permissions required by its own setup instructions; add the declarations or remove the requirement after confirming the behavior does not need them.
  • Files reviewed: 122/149 changed files
  • Comments generated: 10
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread automation/teams-sample-sync/src/validate.ts
Comment thread samples/dotnet/teams/bot-meetings/BotMeetingsAgent.cs
Comment thread samples/dotnet/teams/agent-targeted-messages/README.md Outdated
Comment thread samples/dotnet/teams/bot-ai-messages/README.md Outdated
Comment thread samples/dotnet/teams/bot-attachments/README.md Outdated
Comment thread samples/dotnet/teams/bot-cards/README.md Outdated
Comment thread samples/dotnet/teams/bot-meetings/README.md Outdated
Comment thread samples/dotnet/teams/bot-message-extensions/README.md Outdated
Comment thread samples/dotnet/teams/bot-task-modules/README.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The synchronization boundary can be bypassed by executed candidate code, and several manifest and reliability defects remain.

Get a fresh assessment by requesting another Copilot review.

Review details

Files not reviewed (1)

  • automation/teams-sample-sync/package-lock.json: Generated file

Suppressed comments (5)

Previously missed (5) — in code that hasn't changed since the last review.

automation/teams-sample-sync/src/plan.ts:87

  • The weekly inventory reports every unconfigured upstream directory as a new candidate, so bot-quickstart will be surfaced on every periodic run even though it is explicitly excluded from periodic migration. Apply the default skip list before constructing newSampleCandidates and cover that exclusion in the planner tests.
    automation/teams-sample-sync/src/sync-session.ts:60
  • When the deadline expires during options.validate(), only the Copilot session is aborted. The spawned build/test process remains in activeProcesses until its own timeout, so the advertised per-sample deadline can be exceeded by up to another ten minutes. Invoke the existing validation-process cancellation path when this timer fires.
    samples/dotnet/teams/agent-targeted-messages/ReminderService.cs:78
  • The reminder is removed before delivery, and the exception path only logs. Any transient proactive-send failure therefore permanently loses the reminder while the user still expects it to fire. Keep the item until delivery succeeds, or requeue it with a bounded retry/backoff policy on transient failures.
    samples/dotnet/teams/agent-targeted-messages/appManifest/manifest.json:59
  • The sample does not retrieve or use Teams member profile fields such as UPN, email, or Entra object ID; it only routes with opaque account IDs. Declaring identity therefore requests a root Teams permission that this implementation does not need. Remove it and retain only the separately justified member-messaging permission.
    samples/dotnet/teams/bot-attachments/Services/FileUploadQueue.cs:74
  • A zero-byte attachment reaches this path with Length == 0, making the range end -1; ContentRangeHeaderValue rejects that value before the PUT, so empty files can never be uploaded. Handle zero-length content explicitly (for example, use the service's supported empty-file upload shape or reject it before consent with a clear response).
  • Files reviewed: 122/149 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread automation/teams-sample-sync/src/validate.ts
Comment thread samples/dotnet/teams/bot-meetings/appManifest/manifest.json

This branch has not been deployed

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

Labels

Build Automation Samples Changes to Samples

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automate migration of Teams SDK samples to Agents

3 participants