diff --git a/samples/da-RubberDuck/.gitignore b/samples/da-RubberDuck/.gitignore new file mode 100644 index 000000000..e56779951 --- /dev/null +++ b/samples/da-RubberDuck/.gitignore @@ -0,0 +1,13 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appPackage/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store diff --git a/samples/da-RubberDuck/README.md b/samples/da-RubberDuck/README.md new file mode 100644 index 000000000..295bae83d --- /dev/null +++ b/samples/da-RubberDuck/README.md @@ -0,0 +1,68 @@ +# Rubber Duck Debugging Assistant 🐤 + +![Rubber Duck](assets/da-RubberDuck-screenshot.png) + +## Summary + +Meet your new debugging companion! This declarative agent acts as a "rubber duck" - inspired by the classic programming practice where developers explain their code problems out loud to uncover issues and clarify their thinking. Instead of talking to an actual rubber duck on your desk, you can now interact with an AI-powered debugging assistant that listens patiently and asks thoughtful questions to guide you toward solutions. + +![Rubber Duck in use](assets/da-RubberDuck.gif) + +### What is Rubber Duck Debugging? + +Rubber duck debugging is a method where programmers explain their code line-by-line to an inanimate object (traditionally a rubber duck) to identify bugs and logical errors. By verbalizing the problem, developers often discover the solution themselves. This agent brings that concept to virtual life with intelligent, guided questioning. + +### Version history + +| Version | Date | Comments | +| --- | --- | --- | +| 1.0 | 16/04/2026 | Initial release | + +## Prerequisites + +* Microsoft 365 tenant with Microsoft 365 Copilot +* [Node.js](https://nodejs.org/), supported versions: 18, 20, 22 +* A [Microsoft 365 account for development](https://docs.microsoft.com/microsoftteams/platform/toolkit/accounts) +* [VSCode](https://code.visualstudio.com/) +* [Microsoft 365 Agents Toolkit Visual Studio Code Extension](https://aka.ms/teams-toolkit) version 5.0.0 and higher or [Microsoft 365 Agents Toolkit CLI](https://aka.ms/teamsfx-toolkit-cli) +* [Microsoft 365 Copilot license](https://learn.microsoft.com/microsoft-365-copilot/extensibility/prerequisites#prerequisites) + +## Minimal path to awesome + +1. First, select the Teams Toolkit icon on the left in the VS Code toolbar. +2. In the Account section, sign in with your [Microsoft 365 account](https://docs.microsoft.com/microsoftteams/platform/toolkit/accounts) if you haven't already. Ensure that both "Custom App Upload Enabled" and "Copilot Access Enabled" have green checkmarks +3. Create and provision the Teams app by clicking `Provision` in "Lifecycle" section. +4. Select the "Run and Debug" icon in the left sidebar, and then select `Preview in Copilot (Edge)` or `Preview in Copilot (Chrome)` from the launch configuration dropdown. +5. Once the Copilot app is loaded in the browser, click on the "…" menu and select "Copilot agents". You will see your declarative agent on the right rail. Clicking on it will change the experience to showcase the logo and name of the declarative agent. +6. Ask a question to your declarative agent and it should respond based on the instructions provided. + +## Contributors + +* [Guido Zambarda](https://github.com/guidozam) + +## Features + +This sample illustrates the following concepts: + +Using this sample you can extend Microsoft 365 Copilot with an agent that: + +* **Facilitates rubber duck debugging** - Provides a patient virtual companion for explaining code problems +* **Asks guided questions** - Instead of giving direct answers, asks thoughtful questions to guide you toward solutions +* **Encourages systematic thinking** - Helps break down complex problems into manageable parts +* **Creates a judgment-free environment** - Allows developers to think through problems without feeling rushed or judged + +## Help + +We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues. + +You can try looking at [issues related to this sample](https://github.com/pnp/copilot-pro-dev-samples/issues?q=label%3A%22sample%3A%20da-RubberDuck%22) to see if anybody else is having the same issues. + +If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/copilot-pro-dev-samples/issues/new). + +Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/copilot-pro-dev-samples/issues/new). + +## Disclaimer + +**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +![](https://m365-visitor-stats.azurewebsites.net/copilot-pro-dev-samples/samples/da-RubberDuck) diff --git a/samples/da-RubberDuck/appPackage/color.png b/samples/da-RubberDuck/appPackage/color.png new file mode 100644 index 000000000..47543f2de Binary files /dev/null and b/samples/da-RubberDuck/appPackage/color.png differ diff --git a/samples/da-RubberDuck/appPackage/declarativeAgent.json b/samples/da-RubberDuck/appPackage/declarativeAgent.json new file mode 100644 index 000000000..f60c52ba7 --- /dev/null +++ b/samples/da-RubberDuck/appPackage/declarativeAgent.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.6/schema.json", + "version": "v1.6", + "name": "Rubber duck${{APP_NAME_SUFFIX}}", + "description": "Sample declarative agent that acts as a rubber duck to help developers.", + "instructions": "$[file('instruction.txt')]" +} \ No newline at end of file diff --git a/samples/da-RubberDuck/appPackage/instruction.txt b/samples/da-RubberDuck/appPackage/instruction.txt new file mode 100644 index 000000000..60e6632fa --- /dev/null +++ b/samples/da-RubberDuck/appPackage/instruction.txt @@ -0,0 +1,83 @@ +You are a “Rubber Duck Debugging Assistant,” inspired by the classic practice where developers explain their code out loud to uncover issues and clarify thinking. + +## Mandatory Output Rule + +* Every single response MUST begin with the duck emoji: 🐤 +* The emoji must be the very first character in your response (no spaces or text before it). +* This rule is strict and applies to ALL replies without exception. + +## Core Behavior + +* Act as a patient, attentive listener. +* Encourage the developer to explain their problem step-by-step. +* Ask thoughtful, open-ended questions that guide reflection. +* Help break down complex problems into smaller parts. +* Only provide direct suggestions or solutions when the user explicitly asks or is clearly stuck. + +## Interaction Style + +* Be calm, curious, and non-judgmental. +* Never assume the developer is wrong; instead, explore their reasoning. +* Use prompts like: + + * “Can you walk me through what this part of the code is doing?” + * “What do you expect to happen here?” + * “What actually happens instead?” + * “Where do you think things might be going off track?” +* Reflect back what the developer says to confirm understanding. + +## Guidance Strategy + +1. Clarification First + + * Ask the developer to describe the problem in their own words. + * Identify inputs, outputs, and expected behavior. + +2. Step-by-Step Exploration + + * Guide them through the code flow. + * Encourage them to trace execution mentally or with examples. + +3. Hypothesis Building + + * Help them form possible explanations for the issue. + * Ask what evidence supports or contradicts each hypothesis. + +4. Narrowing Down + + * Suggest isolating components or testing smaller parts. + * Encourage debugging techniques (logs, breakpoints, minimal examples). + +5. Gentle Nudging + + * If they are stuck, provide hints—not full solutions. + * Escalate gradually from hints → partial suggestions → full explanation (only if needed). + +## Constraints + +* Do NOT immediately provide the final answer unless explicitly requested. +* Avoid overwhelming the user with too many questions at once. +* Keep responses concise but thoughtful. +* Prefer guiding questions over explanations. + +## Optional Behaviors + +* If the developer seems frustrated, acknowledge it briefly and refocus: + + * “This kind of issue can be tricky—let’s break it down together.” +* If they skip steps, gently bring them back: + + * “Before we jump ahead, can we look at what this function returns?” + +## Example Tone + +Developer: “My function isn’t returning the right value.” +You: “🐤 Can you show me the function and tell me what you expect it to return versus what it actually returns?” + +## End Goal + +Help the developer: + +* Understand their own code better +* Discover bugs or gaps in logic independently +* Build stronger problem-solving skills diff --git a/samples/da-RubberDuck/appPackage/manifest.json b/samples/da-RubberDuck/appPackage/manifest.json new file mode 100644 index 000000000..8748e229b --- /dev/null +++ b/samples/da-RubberDuck/appPackage/manifest.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.25/MicrosoftTeams.schema.json", + "manifestVersion": "1.25", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "GuidoZam", + "websiteUrl": "https://iamguidozam.blog", + "privacyUrl": "https://iamguidozam.blog/privacy", + "termsOfUseUrl": "https://iamguidozam.blog/term-of-use" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Rubber duck${{APP_NAME_SUFFIX}}", + "full": "Rubber duck: your personal coding assistant" + }, + "description": { + "short": "Rubber duck is your personal coding assistant that helps developers.", + "full": "Rubber duck is your personal coding assistant that helps you debug and understand your code by explaining it in simple terms." + }, + "accentColor": "#FFFFFF", + "supportsChannelFeatures": "tier1", + "composeExtensions": [], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "copilotAgents": { + "declarativeAgents": [ + { + "id": "declarativeAgent", + "file": "declarativeAgent.json" + } + ] + }, + "validDomains": [] +} \ No newline at end of file diff --git a/samples/da-RubberDuck/appPackage/outline.png b/samples/da-RubberDuck/appPackage/outline.png new file mode 100644 index 000000000..6ff8a9233 Binary files /dev/null and b/samples/da-RubberDuck/appPackage/outline.png differ diff --git a/samples/da-RubberDuck/assets/da-RubberDuck-screenshot.png b/samples/da-RubberDuck/assets/da-RubberDuck-screenshot.png new file mode 100644 index 000000000..3a0c2f602 Binary files /dev/null and b/samples/da-RubberDuck/assets/da-RubberDuck-screenshot.png differ diff --git a/samples/da-RubberDuck/assets/da-RubberDuck.gif b/samples/da-RubberDuck/assets/da-RubberDuck.gif new file mode 100644 index 000000000..766eabd00 Binary files /dev/null and b/samples/da-RubberDuck/assets/da-RubberDuck.gif differ diff --git a/samples/da-RubberDuck/assets/sample.json b/samples/da-RubberDuck/assets/sample.json new file mode 100644 index 000000000..7a437d1c6 --- /dev/null +++ b/samples/da-RubberDuck/assets/sample.json @@ -0,0 +1,69 @@ +[ + { + "name": "pnp-copilot-pro-dev-da-RubberDuck", + "source": "pnp", + "title": "Rubber Duck Debugging Assistant", + "shortDescription": "AI-powered debugging companion for rubber duck debugging methodology", + "url": "https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/da-RubberDuck", + "downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/da-RubberDuck", + "longDescription": [ + "This declarative agent acts as a rubber duck debugging assistant, inspired by the classic programming practice where developers explain their code problems out loud to uncover issues and clarify their thinking. Instead of talking to an actual rubber duck, you can interact with an AI-powered debugging assistant that listens patiently and asks thoughtful questions to guide you toward solutions." + ], + "creationDateTime": "2026-04-16", + "updateDateTime": "2026-04-16", + "products": [ + "Microsoft 365 Copilot" + ], + "metadata": [ + { + "key": "PLATFORM", + "value": "Microsoft 365 Agents Toolkit" + }, + { + "key": "LANGUAGE", + "value": "N/A" + }, + { + "key": "API-PLUGIN", + "value": "No" + }, + { + "key": "GRAPH-CONNECTOR", + "value": "No" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://github.com/pnp/copilot-pro-dev-samples/raw/main/samples/da-RubberDuck/assets/da-RubberDuck-screenshot.png", + "alt": "Rubber Duck Debugging Assistant in action" + }, + { + "type": "image", + "order": 101, + "url": "https://github.com/pnp/copilot-pro-dev-samples/raw/main/samples/da-RubberDuck/assets/da-RubberDuck.gif", + "alt": "Rubber Duck Debugging Assistant conversation flow" + } + ], + "authors": [ + { + "gitHubAccount": "guidozam", + "pictureUrl": "https://github.com/guidozam.png", + "name": "Guido Zambarda" + } + ], + "references": [ + { + "name": "Microsoft 365 Copilot extensibility", + "description": "Learn more about what Microsoft 365 Copilot and how you can extend it.", + "url": "https://learn.microsoft.com/microsoft-365-copilot/extensibility/" + }, + { + "name": "Rubber Duck Debugging", + "description": "Learn more about the rubber duck debugging methodology.", + "url": "https://en.wikipedia.org/wiki/Rubber_duck_debugging" + } + ] + } +] \ No newline at end of file diff --git a/samples/da-RubberDuck/env/.env.dev.sample b/samples/da-RubberDuck/env/.env.dev.sample new file mode 100644 index 000000000..b528d3f13 --- /dev/null +++ b/samples/da-RubberDuck/env/.env.dev.sample @@ -0,0 +1,9 @@ + +# This file includes environment variables that will be committed to git by default. + +# Built-in environment variables +TEAMSFX_ENV=dev +APP_NAME_SUFFIX=" dev" +AGENT_SCOPE=shared +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= \ No newline at end of file diff --git a/samples/da-RubberDuck/m365agents.yml b/samples/da-RubberDuck/m365agents.yml new file mode 100644 index 000000000..978a2deb2 --- /dev/null +++ b/samples/da-RubberDuck/m365agents.yml @@ -0,0 +1,72 @@ +# yaml-language-server: $schema=https://aka.ms/m365-agents-toolkits/v1.11/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.11 + +environmentFolderPath: ./env + +# Triggered when 'teamsapp provision' is executed +provision: + # Creates an app + - uses: teamsApp/create + with: + # app name + name: Rubber duck${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Build app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputFolder: ./appPackage/build + # Update the app manifest to an existing app in Developer Portal. + # Will use the app id in manifest file to determine which app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Extend your app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + scope: ${{AGENT_SCOPE}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID + shareLink: SHARE_LINK + +# Triggered when 'teamsapp publish' is executed +publish: + # Build app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputFolder: ./appPackage/build + # Apply the app manifest to an existing app in + # Developer Portal. + # Will use the app id in manifest file to determine which app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Publish the app to + # Teams Admin Center (https://admin.teams.microsoft.com/policies/manage-apps) + # for review and approval + - uses: teamsApp/publishAppPackage + with: + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + publishedAppId: TEAMS_APP_PUBLISHED_APP_ID +projectId: 19e37db5-9021-415c-9718-1e0ac119326a