diff --git a/.config/samples-config-v3.json b/.config/samples-config-v3.json index 6134b2fa..25590821 100644 --- a/.config/samples-config-v3.json +++ b/.config/samples-config-v3.json @@ -912,55 +912,8 @@ ], "time": "5 mins to run", "configuration": "Manual configurations required", - "thumbnailPath": "assets/coffee-agent-thumbnail.png", - "gifPath": "assets/coffee-agent-thumbnail.png", - "suggested": false - }, - { - "id": "collaborator-agent", - "shortId": "collaborator-agent", - "onboardDate": "2025-10-31", - "title": "Collaborator Agent", - "shortDescription": "Collaboration agent with advanced conversation analysis and task management capabilities.", - "fullDescription": "This sample is built with the Microsoft Teams SDK, and showcases how to create an intelligent collaboration assistant that can analyze conversations, manage action items, and search through chat history using natural language processing and time-based queries.", - "types": [ - "Custom Engine Agent" - ], - "tags": [ - "TS", - "Custom Engine Agent", - "Conversation Analysis", - "Task Management", - "Microsoft Teams SDK" - ], - "time": "10 mins to run", - "configuration": "Manual configurations required", - "thumbnailPath": "assets/collaborator-agent-thumbnail.png", - "gifPath": "assets/collaborator-agent-thumbnail.png", - "suggested": false - }, - { - "id": "data-analyst-agent-v2", - "shortId": "data-analyst-v2", - "onboardDate": "2025-10-31", - "title": "Data Analyst Agent v2", - "shortDescription": "Natural language interface for data exploration and visualization.", - "fullDescription": "This sample demonstrates how to build an AI-powered data analyst agent using Microsoft Teams SDK that can be integrated into Microsoft Teams. It helps users explore and visualize data through natural language conversations and Adaptive Cards charts.", - "types": [ - "Custom Engine Agent" - ], - "tags": [ - "TS", - "Custom Engine Agent", - "Data Visualization", - "Adaptive Cards", - "LLM SQL", - "Microsoft Teams SDK" - ], - "time": "10 mins to run", - "configuration": "Manual configurations required", - "thumbnailPath": "assets/demo.gif", - "gifPath": "assets/demo.gif", + "thumbnailPath": "assets/coffee-agent-sample-response.png", + "gifPath": "assets/coffee-agent-sample-response.png", "suggested": false } ] diff --git a/coffee-agent/.gitignore b/coffee-agent/.gitignore index 516cb5ca..78acc715 100644 --- a/coffee-agent/.gitignore +++ b/coffee-agent/.gitignore @@ -3,4 +3,5 @@ node_modules/ .env appPackage/build .localConfigs -.localConfigs.playground \ No newline at end of file +.localConfigs.playground +dist \ No newline at end of file diff --git a/coffee-agent/.webappignore b/coffee-agent/.webappignore new file mode 100644 index 00000000..2a59f587 --- /dev/null +++ b/coffee-agent/.webappignore @@ -0,0 +1,28 @@ +.webappignore +.fx +.deployment +.localConfigs.playground +.localConfigs +.notification.localstore.json +.notification.playgroundstore.json +.vscode +*.js.map +*.ts.map +*.ts +.git* +.tsbuildinfo +CHANGELOG.md +readme.md +local.settings.json +test +tsconfig.json +.DS_Store +m365agents.yml +m365agents.*.yml +/env/ +/node_modules/.bin +/node_modules/ts-node +/node_modules/typescript +/appPackage/ +/infra/ +/devTools/ \ No newline at end of file diff --git a/coffee-agent/README.md b/coffee-agent/README.md index b583bac9..c9330d4d 100644 --- a/coffee-agent/README.md +++ b/coffee-agent/README.md @@ -4,7 +4,7 @@ Originally from our Build 2025 Lab, this sample is built with the [Microsoft Tea This Coffee Agent helps teams coordinate their daily coffee orders by randomly selecting coffee shops and orderers, managing team coffee orders, and maintaining information about available coffee shops and their offerings. It's perfect for teams that want to streamline their coffee coordination process while having fun with their daily caffeine routine. -![Coffee Agent Demo](assets/coffee-agent-thumbnail.png) +![Coffee Agent Demo](assets/coffee-agent-sample-response.png) ## This sample illustrates - Use Microsoft 365 Agents Toolkit to create an AI-powered Teams bot diff --git a/coffee-agent/appPackage/color.png b/coffee-agent/appPackage/color.png index 16d6a811..a5909009 100644 Binary files a/coffee-agent/appPackage/color.png and b/coffee-agent/appPackage/color.png differ diff --git a/coffee-agent/assets/coffee-agent-sample-response.png b/coffee-agent/assets/coffee-agent-sample-response.png new file mode 100644 index 00000000..53e371ab Binary files /dev/null and b/coffee-agent/assets/coffee-agent-sample-response.png differ diff --git a/coffee-agent/infra/azure.bicep b/coffee-agent/infra/azure.bicep index 434d22d7..f80f392a 100644 --- a/coffee-agent/infra/azure.bicep +++ b/coffee-agent/infra/azure.bicep @@ -61,13 +61,17 @@ resource webApp 'Microsoft.Web/sites@2021-02-01' = { value: '1' } { - name: 'clientId' + name: 'CLIENT_ID' value: identity.properties.clientId } { - name: 'tenantId' + name: 'TENANT_ID' value: identity.properties.tenantId } + { + name: 'BOT_TYPE' + value: 'UserAssignedMsi' + } { name: 'AZURE_OPENAI_API_KEY' value: azureOpenAIKey diff --git a/coffee-agent/package-lock.json b/coffee-agent/package-lock.json index 23316b9a..648f2375 100644 --- a/coffee-agent/package-lock.json +++ b/coffee-agent/package-lock.json @@ -9,14 +9,14 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@microsoft/teams.ai": "^2.0.0-preview.3", - "@microsoft/teams.api": "^2.0.0-preview.3", - "@microsoft/teams.apps": "^2.0.0-preview.3", - "@microsoft/teams.cards": "^2.0.0-preview.3", - "@microsoft/teams.common": "^2.0.0-preview.3", - "@microsoft/teams.dev": "^2.0.0-preview.3", - "@microsoft/teams.graph": "^2.0.0-preview.3", - "@microsoft/teams.openai": "^2.0.0-preview.3" + "@azure/identity": "^4.13.0", + "@microsoft/teams.ai": "^2.0.0", + "@microsoft/teams.api": "^2.0.0", + "@microsoft/teams.apps": "^2.0.0", + "@microsoft/teams.cards": "^2.0.0", + "@microsoft/teams.common": "^2.0.0", + "@microsoft/teams.graph": "^2.0.0", + "@microsoft/teams.openai": "^2.0.0" }, "devDependencies": { "@types/node": "^22.5.4", @@ -59,73 +59,158 @@ } }, "node_modules/@azure/core-auth": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz", - "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-util": "^1.11.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.1.tgz", - "integrity": "sha512-zHeoI3NCs53lLBbWNzQycjnYKsA1CVKlnzSNuSFcUDwBp8HHVObePxrM7HaX+Ha5Ks639H7chNC9HOaIhNS03w==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.2.tgz", + "integrity": "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-auth": "^1.8.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.11.0", - "@azure/logger": "^1.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-tracing": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", - "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", "license": "MIT", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-util": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz", - "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.0.tgz", + "integrity": "sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.5.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/logger": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz", - "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", "license": "MIT", "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.26.1.tgz", + "integrity": "sha512-GGCIsZXxyNm5QcQZ4maA9q+9UWmM+/87G+ybvPkrE32el1URSa9WYt0t67ks3/P0gspZX9RoEqyLqJ/X/JDnBQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.13.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.13.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.13.1.tgz", + "integrity": "sha512-vQYQcG4J43UWgo1lj7LcmdsGUKWYo28RfEvDQAEMmQIMjSFufvb+pS0FJ3KXmrPmnWlt1vHDl3oip6mIDUQ4uA==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.1.tgz", + "integrity": "sha512-HszfqoC+i2C9+BRDQfuNUGp15Re7menIhCEbFCQ49D3KaqEDrgZIgQ8zSct4T59jWeUIL9N/Dwiv4o2VueTdqQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.13.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/@azure/openai": { @@ -629,21 +714,21 @@ } }, "node_modules/@microsoft/teams.ai": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.ai/-/teams.ai-2.0.0-preview.3.tgz", - "integrity": "sha512-sXzzqyDgbnpo18CthRQTOoMBu8N49y45xsl4hC0UINrpFtpAVtoKUePC08aceWSjMsscldYIqx6l6LNpJG+CzA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.ai/-/teams.ai-2.0.2.tgz", + "integrity": "sha512-Qrz8R+6M1w1o4P14G/CiTk/CFA0P0SpTDqsmK5FPd0qu4jDTi8EG+2z7nzsl55+fdAL+idr3J9Diit7Bler0qA==", "license": "MIT", "engines": { "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.common": "2.0.0-preview.3" + "@microsoft/teams.common": "2.0.2" } }, "node_modules/@microsoft/teams.api": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.api/-/teams.api-2.0.0-preview.3.tgz", - "integrity": "sha512-Keua01qEgd0q5+PjwFGdMYWzgpU42xAXgh/nzHi/Xa4w27Dqpt7UGBmAHE7z+N0a9wbeBF+ae8Vqsn0cAUz40g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.api/-/teams.api-2.0.2.tgz", + "integrity": "sha512-TAczlRa02N8VoSkl/XyAdMY82B4MnBwk6XZzmAy7tJWZAudrfNRWJ4qDra9XtJ/eoGF1kKgzGBPTBT8cmH8nzw==", "license": "MIT", "dependencies": { "jwt-decode": "^4.0.0", @@ -653,17 +738,17 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.cards": "2.0.0-preview.3", - "@microsoft/teams.common": "2.0.0-preview.3" + "@microsoft/teams.cards": "2.0.2", + "@microsoft/teams.common": "2.0.2" } }, "node_modules/@microsoft/teams.apps": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.apps/-/teams.apps-2.0.0-preview.3.tgz", - "integrity": "sha512-SHIIGkhWhRDRf0hhk8d9+blkVhRpyvg+WcQdvOxXVUihm3CYqAxvKf7b3fNk/knm3p1bSXTTycqaKnMAekl3+g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.apps/-/teams.apps-2.0.2.tgz", + "integrity": "sha512-IDr7mNJQhOFPAWKaSFMFRhscMapV+b9T+Kq9zfyUdSzPyDG9ayubikC+3na4SRCrRuVqkceUP9VV5c6ZMTagQw==", "license": "MIT", "dependencies": { - "axios": "^1.8.2", + "axios": "^1.12.0", "cors": "^2.8.5", "express": "^4.21.0", "jsonwebtoken": "^9.0.2", @@ -674,62 +759,39 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.api": "2.0.0-preview.3", - "@microsoft/teams.common": "2.0.0-preview.3", - "@microsoft/teams.graph": "2.0.0-preview.3" + "@microsoft/teams.api": "2.0.2", + "@microsoft/teams.common": "2.0.2", + "@microsoft/teams.graph": "2.0.2" } }, "node_modules/@microsoft/teams.cards": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.cards/-/teams.cards-2.0.0-preview.3.tgz", - "integrity": "sha512-d/7dmadkuOZjzx2xmewr2JjrcL6j3Fn/J5bDSDq4muqGfY8a1wpmbRuNnH8UTFs0gfXAoTiIAyZrjhIeZMK5vw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.cards/-/teams.cards-2.0.2.tgz", + "integrity": "sha512-E/QLeeb3owS3oyRKFw7Pvcoo2qrnAI6+kv0/t4Ed0XM9jyKi+bc1ro/JhwxtgiLyodNoThQVu8f/7TYihvRI4w==", "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/@microsoft/teams.common": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.common/-/teams.common-2.0.0-preview.3.tgz", - "integrity": "sha512-+Jboc007CzwwJvqWa52j5Ouplllm0wH01jKKt2v09ZEF4M9SPmPvnM/yWBjpHygZ3tTYO+O2RGzQSSyXt9Uexw==", - "license": "MIT", - "dependencies": { - "axios": "^1.8.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@microsoft/teams.dev": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.dev/-/teams.dev-2.0.0-preview.3.tgz", - "integrity": "sha512-c3MTqwSntkYqBTqfb2+Ux/zCzAQrnqTQhGSXdmPdtHE84WZZ5b5iUhe+B2dZDotq1W7pdgUnRMSFs6Rnt9jJ6g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.common/-/teams.common-2.0.2.tgz", + "integrity": "sha512-IFQJ7KOADspZL2sIWR+n7LnS3prYulB7IXmn62YcxDLsuq9UZsGxLERM3CeagiCh8Thb5OxERxyCwzhuS9Fx6w==", "license": "MIT", "dependencies": { - "axios": "^1.8.2", - "express": "^4.21.0", - "jsonwebtoken": "^9.0.2", - "uuid": "^11.0.5", - "ws": "^8.18.1" + "axios": "^1.12.0" }, "engines": { "node": ">=20" - }, - "peerDependencies": { - "@microsoft/teams.api": "2.0.0-preview.3", - "@microsoft/teams.apps": "2.0.0-preview.3", - "@microsoft/teams.cards": "2.0.0-preview.3", - "@microsoft/teams.common": "2.0.0-preview.3", - "@microsoft/teams.graph": "2.0.0-preview.3" } }, "node_modules/@microsoft/teams.graph": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.graph/-/teams.graph-2.0.0-preview.3.tgz", - "integrity": "sha512-V95MkcXSFf3a+IbOP9RvyDTiHIEELAXMR2Vzgs0G/3j+7XadwfFEjME3DVWWEcO3wj2pghoAMn4kpmXcWDFNaA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.graph/-/teams.graph-2.0.2.tgz", + "integrity": "sha512-JbmdnMPKmayTtamiDY24IgLwzrJvZPN0FBYA3DsMdlDgJrPAWRx+JXdBn39offGcVIoQed6SYlsay6EiTE9Hig==", "license": "MIT", "dependencies": { - "@microsoft/teams.common": "2.0.0-preview.3", + "@microsoft/teams.common": "2.0.2", "qs": "^6.13.0" }, "engines": { @@ -737,9 +799,9 @@ } }, "node_modules/@microsoft/teams.openai": { - "version": "2.0.0-preview.3", - "resolved": "https://registry.npmjs.org/@microsoft/teams.openai/-/teams.openai-2.0.0-preview.3.tgz", - "integrity": "sha512-y9tT3Ol0PIGbhJ3vunXfEkX8HfYW3EI+HgUxxibcFh5cbZRVT9PsR/oW8KFWWuxb8ldjOjkrdckUkowo4r7//g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.openai/-/teams.openai-2.0.2.tgz", + "integrity": "sha512-e2yp+fcFnmfWisxvMe9yuyUlAPC7/xQq5669QDpSQQtuUU8Lr105s4ZP62TcYH2qfC74iE8WcfSSJFzJNfU4mg==", "license": "MIT", "dependencies": { "@azure/openai": "^2.0.0" @@ -748,8 +810,8 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.ai": "2.0.0-preview.3", - "@microsoft/teams.common": "2.0.0-preview.3", + "@microsoft/teams.ai": "2.0.2", + "@microsoft/teams.common": "2.0.2", "openai": "^4.55.0" } }, @@ -1164,6 +1226,20 @@ "@types/send": "*" } }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -1214,9 +1290,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", "engines": { "node": ">= 14" @@ -1387,6 +1463,21 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bundle-require": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", @@ -1595,6 +1686,46 @@ "ms": "2.0.0" } }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2185,9 +2316,9 @@ } }, "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2221,9 +2352,9 @@ } }, "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2295,6 +2426,21 @@ "node": ">=8" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2325,6 +2471,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2334,6 +2498,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2830,6 +3009,24 @@ "node": ">= 0.8" } }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openai": { "version": "4.95.1", "resolved": "https://registry.npmjs.org/openai/-/openai-4.95.1.tgz", @@ -3152,6 +3349,18 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3911,18 +4120,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -4074,6 +4271,8 @@ "version": "8.18.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -4090,6 +4289,21 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/coffee-agent/package.json b/coffee-agent/package.json index 27163b03..d2259495 100644 --- a/coffee-agent/package.json +++ b/coffee-agent/package.json @@ -12,21 +12,21 @@ "scripts": { "clean": "npx rimraf ./dist", "build": "npx tsup", - "start": "node .", + "start": "node ./dist/index.js", "dev": "npx nodemon -w \"./src/**\" -e ts --exec \"node -r ts-node/register -r dotenv/config ./src/index.ts\"", "dev:teamsfx": "env-cmd --silent -f .localConfigs npm run dev", "dev:teamsfx:playground": "env-cmd --silent -f .localConfigs.playground npm run dev", "dev:teamsfx:launch-playground": "env-cmd --silent -f env/.env.playground teamsapptester start" }, "dependencies": { - "@microsoft/teams.ai": "^2.0.0-preview.3", - "@microsoft/teams.api": "^2.0.0-preview.3", - "@microsoft/teams.apps": "^2.0.0-preview.3", - "@microsoft/teams.cards": "^2.0.0-preview.3", - "@microsoft/teams.common": "^2.0.0-preview.3", - "@microsoft/teams.dev": "^2.0.0-preview.3", - "@microsoft/teams.graph": "^2.0.0-preview.3", - "@microsoft/teams.openai": "^2.0.0-preview.3" + "@azure/identity": "^4.13.0", + "@microsoft/teams.ai": "^2.0.0", + "@microsoft/teams.api": "^2.0.0", + "@microsoft/teams.apps": "^2.0.0", + "@microsoft/teams.cards": "^2.0.0", + "@microsoft/teams.common": "^2.0.0", + "@microsoft/teams.graph": "^2.0.0", + "@microsoft/teams.openai": "^2.0.0" }, "devDependencies": { "@types/node": "^22.5.4", diff --git a/coffee-agent/src/index.ts b/coffee-agent/src/index.ts index e534efd3..d9d34a5b 100644 --- a/coffee-agent/src/index.ts +++ b/coffee-agent/src/index.ts @@ -1,17 +1,41 @@ -import { App } from '@microsoft/teams.apps'; +import { ManagedIdentityCredential } from '@azure/identity'; import { ChatPrompt } from '@microsoft/teams.ai'; -import { AzureOpenAIChatModelOptions, OpenAIChatModel } from '@microsoft/teams.openai'; +import { InvokeResponse, TaskModuleResponse, TokenCredentials } from '@microsoft/teams.api'; +import { App } from '@microsoft/teams.apps'; import { ConsoleLogger, LocalStorage } from '@microsoft/teams.common'; -import { InvokeResponse, TaskModuleResponse } from '@microsoft/teams.api'; -import { CoffeeShop, Member, StorageState } from './interfaces'; +import { AzureOpenAIChatModelOptions, OpenAIChatModel } from '@microsoft/teams.openai'; import { generateOrderCard, generateOrderDialogCard, generateSubmittedOrderCard } from './cards'; +import { CoffeeShop, Member, StorageState } from './interfaces'; import { addCoffeeShopSchema } from './schema'; import { initialCafes, initialOrder } from './storage'; const storage = new LocalStorage(); storage.set('local', { coffeeShops: initialCafes, currOrder: initialOrder } as StorageState); +const createTokenFactory = () => { + return async (scope: string | string[], tenantId?: string): Promise => { + const managedIdentityCredential = new ManagedIdentityCredential({ + clientId: process.env.CLIENT_ID + }); + const scopes = Array.isArray(scope) ? scope : [scope]; + const tokenResponse = await managedIdentityCredential.getToken(scopes, { + tenantId: tenantId + }); + + return tokenResponse.token; + }; +}; + +// Configure authentication using TokenCredentials +const tokenCredentials: TokenCredentials = { + clientId: process.env.CLIENT_ID || '', + token: createTokenFactory() +}; + +const credentialOptions = process.env.BOT_TYPE === "UserAssignedMsi" ? { ...tokenCredentials } : undefined; + const app = new App({ + ...credentialOptions, logger: new ConsoleLogger('@samples/coffee', { level: 'debug' }) }); @@ -117,5 +141,8 @@ const prompt = new ChatPrompt( }); (async () => { - await app.start(+(process.env.PORT || 3978)); + await app.start(process.env.PORT || process.env.port || 3978); + console.log(`\nAgent started, app listening to`, process.env.PORT || process.env.port || 3978); })(); + +export default app; diff --git a/coffee-agent/tsup.config.js b/coffee-agent/tsup.config.js index 32277a72..f1bc6df4 100644 --- a/coffee-agent/tsup.config.js +++ b/coffee-agent/tsup.config.js @@ -2,10 +2,10 @@ module.exports = { dts: true, minify: false, - bundle: false, + bundle: true, sourcemap: true, treeshake: true, - splitting: true, + splitting: false, clean: true, outDir: 'dist', entry: ['src/index.ts'], diff --git a/coffee-agent/web.config b/coffee-agent/web.config new file mode 100644 index 00000000..9a7f2fa9 --- /dev/null +++ b/coffee-agent/web.config @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collaborator-agent/.gitignore b/collaborator-agent/.gitignore index 6e621e85..6b468b8a 100644 --- a/collaborator-agent/.gitignore +++ b/collaborator-agent/.gitignore @@ -11,3 +11,4 @@ src/storage/conversations.db .localConfigs .localConfigs.playground +dist diff --git a/collaborator-agent/.webappignore b/collaborator-agent/.webappignore new file mode 100644 index 00000000..2a59f587 --- /dev/null +++ b/collaborator-agent/.webappignore @@ -0,0 +1,28 @@ +.webappignore +.fx +.deployment +.localConfigs.playground +.localConfigs +.notification.localstore.json +.notification.playgroundstore.json +.vscode +*.js.map +*.ts.map +*.ts +.git* +.tsbuildinfo +CHANGELOG.md +readme.md +local.settings.json +test +tsconfig.json +.DS_Store +m365agents.yml +m365agents.*.yml +/env/ +/node_modules/.bin +/node_modules/ts-node +/node_modules/typescript +/appPackage/ +/infra/ +/devTools/ \ No newline at end of file diff --git a/collaborator-agent/appPackage/color.png b/collaborator-agent/appPackage/color.png index 1bd6aa4d..9707a244 100644 Binary files a/collaborator-agent/appPackage/color.png and b/collaborator-agent/appPackage/color.png differ diff --git a/collaborator-agent/infra/azure.bicep b/collaborator-agent/infra/azure.bicep index 434d22d7..f80f392a 100644 --- a/collaborator-agent/infra/azure.bicep +++ b/collaborator-agent/infra/azure.bicep @@ -61,13 +61,17 @@ resource webApp 'Microsoft.Web/sites@2021-02-01' = { value: '1' } { - name: 'clientId' + name: 'CLIENT_ID' value: identity.properties.clientId } { - name: 'tenantId' + name: 'TENANT_ID' value: identity.properties.tenantId } + { + name: 'BOT_TYPE' + value: 'UserAssignedMsi' + } { name: 'AZURE_OPENAI_API_KEY' value: azureOpenAIKey diff --git a/collaborator-agent/package-lock.json b/collaborator-agent/package-lock.json index 41cebf23..d3c80c5a 100644 --- a/collaborator-agent/package-lock.json +++ b/collaborator-agent/package-lock.json @@ -9,14 +9,14 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@microsoft/teams.ai": "^2.0.0-preview.5", - "@microsoft/teams.api": "^2.0.0-preview.5", - "@microsoft/teams.apps": "^2.0.0-preview.5", - "@microsoft/teams.cards": "^2.0.0-preview.5", - "@microsoft/teams.common": "^2.0.0-preview.5", - "@microsoft/teams.dev": "^2.0.0-preview.5", - "@microsoft/teams.graph": "^2.0.0-preview.5", - "@microsoft/teams.openai": "^2.0.0-preview.5", + "@azure/identity": "^4.13.0", + "@microsoft/teams.ai": "^2.0.0", + "@microsoft/teams.api": "^2.0.0", + "@microsoft/teams.apps": "^2.0.0", + "@microsoft/teams.cards": "^2.0.0", + "@microsoft/teams.common": "^2.0.0", + "@microsoft/teams.graph": "^2.0.0", + "@microsoft/teams.openai": "^2.0.0", "@types/better-sqlite3": "^7.6.12", "better-sqlite3": "^11.9.0", "chrono-node": "^2.7.0", @@ -27,7 +27,7 @@ "@types/node": "^22.5.4", "@types/ws": "^8.18.1", "dotenv": "^16.4.5", - "env-cmd": "*", + "env-cmd": "latest", "nodemon": "^3.1.4", "rimraf": "^6.0.1", "ts-morph": "^26.0.0", @@ -66,74 +66,200 @@ } }, "node_modules/@azure/core-auth": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz", - "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-util": "^1.11.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.21.0.tgz", - "integrity": "sha512-a4MBwe/5WKbq9MIxikzgxLBbruC5qlkFYlBdI7Ev50Y7ib5Vo/Jvt5jnJo7NaWeJ908LCHL0S1Us4UMf1VoTfg==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.2.tgz", + "integrity": "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-auth": "^1.8.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.11.0", - "@azure/logger": "^1.0.0", - "@typespec/ts-http-runtime": "^0.2.3", + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/core-tracing": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", - "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", "license": "MIT", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-util": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.12.0.tgz", - "integrity": "sha512-13IyjTQgABPARvG90+N2dXpC+hwp466XCdQXPCRlbWHgd3SJd5Q1VvaBGv6k1BIa4MQm6hAF1UBU1m8QUxV8sQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@typespec/ts-http-runtime": "^0.2.2", + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.0.tgz", + "integrity": "sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.5.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/logger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.2.0.tgz", - "integrity": "sha512-0hKEzLhpw+ZTAfNJyRrn6s+V0nDWzXk9OjBr2TiGIu0OfMr5s2V4FpKLTAK3Ca5r5OKLbf4hkOGDPyiRjie/jA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", "license": "MIT", "dependencies": { - "@typespec/ts-http-runtime": "^0.2.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/logger/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.26.1.tgz", + "integrity": "sha512-GGCIsZXxyNm5QcQZ4maA9q+9UWmM+/87G+ybvPkrE32el1URSa9WYt0t67ks3/P0gspZX9RoEqyLqJ/X/JDnBQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.13.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.13.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.13.1.tgz", + "integrity": "sha512-vQYQcG4J43UWgo1lj7LcmdsGUKWYo28RfEvDQAEMmQIMjSFufvb+pS0FJ3KXmrPmnWlt1vHDl3oip6mIDUQ4uA==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.1.tgz", + "integrity": "sha512-HszfqoC+i2C9+BRDQfuNUGp15Re7menIhCEbFCQ49D3KaqEDrgZIgQ8zSct4T59jWeUIL9N/Dwiv4o2VueTdqQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.13.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/@azure/openai": { @@ -716,21 +842,21 @@ } }, "node_modules/@microsoft/teams.ai": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.ai/-/teams.ai-2.0.0-preview.6.tgz", - "integrity": "sha512-vJgHcRMHsksxIb0epdynnYrkcxeFkM/tybe35sjrtrtQ1RdOc4lVbR9yFwJj5j3qMCx/4veQWYr2MUHehl9ofA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.ai/-/teams.ai-2.0.2.tgz", + "integrity": "sha512-Qrz8R+6M1w1o4P14G/CiTk/CFA0P0SpTDqsmK5FPd0qu4jDTi8EG+2z7nzsl55+fdAL+idr3J9Diit7Bler0qA==", "license": "MIT", "engines": { "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.common": "2.0.0-preview.6" + "@microsoft/teams.common": "2.0.2" } }, "node_modules/@microsoft/teams.api": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.api/-/teams.api-2.0.0-preview.6.tgz", - "integrity": "sha512-/SPo8GJXI3GOzI/3UUCY1JIsrLTb1KCI0iqGc5Ii3EazzZYw7JbDj+1KO9qiBwCaQ2hG0HcD26vZa63buI7JWA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.api/-/teams.api-2.0.2.tgz", + "integrity": "sha512-TAczlRa02N8VoSkl/XyAdMY82B4MnBwk6XZzmAy7tJWZAudrfNRWJ4qDra9XtJ/eoGF1kKgzGBPTBT8cmH8nzw==", "license": "MIT", "dependencies": { "jwt-decode": "^4.0.0", @@ -740,17 +866,17 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.cards": "2.0.0-preview.6", - "@microsoft/teams.common": "2.0.0-preview.6" + "@microsoft/teams.cards": "2.0.2", + "@microsoft/teams.common": "2.0.2" } }, "node_modules/@microsoft/teams.apps": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.apps/-/teams.apps-2.0.0-preview.6.tgz", - "integrity": "sha512-b6rtcOqJjxu7NADQJ0kFBG+3rCLc/fmz3e4spB9en599f/iv1gIMFMWp+vDfKehxsWgYJLALU1R4t+ZbNhf1Uw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.apps/-/teams.apps-2.0.2.tgz", + "integrity": "sha512-IDr7mNJQhOFPAWKaSFMFRhscMapV+b9T+Kq9zfyUdSzPyDG9ayubikC+3na4SRCrRuVqkceUP9VV5c6ZMTagQw==", "license": "MIT", "dependencies": { - "axios": "^1.8.2", + "axios": "^1.12.0", "cors": "^2.8.5", "express": "^4.21.0", "jsonwebtoken": "^9.0.2", @@ -761,62 +887,39 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.api": "2.0.0-preview.6", - "@microsoft/teams.common": "2.0.0-preview.6", - "@microsoft/teams.graph": "2.0.0-preview.6" + "@microsoft/teams.api": "2.0.2", + "@microsoft/teams.common": "2.0.2", + "@microsoft/teams.graph": "2.0.2" } }, "node_modules/@microsoft/teams.cards": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.cards/-/teams.cards-2.0.0-preview.6.tgz", - "integrity": "sha512-AnXXpTeb7iR8Frbk241wFEU2ORgGAW3Ueczxp5DBYUm6CfR29//fZAzm8ZfP5x2mAIoSbyMjS6MXfq4akU8w2w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.cards/-/teams.cards-2.0.2.tgz", + "integrity": "sha512-E/QLeeb3owS3oyRKFw7Pvcoo2qrnAI6+kv0/t4Ed0XM9jyKi+bc1ro/JhwxtgiLyodNoThQVu8f/7TYihvRI4w==", "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/@microsoft/teams.common": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.common/-/teams.common-2.0.0-preview.6.tgz", - "integrity": "sha512-0dAG9HrjxscYKYhzn+o7uHA3Sql7kpc/gl5NH/YEGMTbaC9esNN94JTBdoG3W99rJT1vIVxExmPa5f4y4qRxFA==", - "license": "MIT", - "dependencies": { - "axios": "^1.8.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@microsoft/teams.dev": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.dev/-/teams.dev-2.0.0-preview.6.tgz", - "integrity": "sha512-pxmalPoI944bRdav7yF200AYXUJ3lx0gQdt8Ne6R45BtWMQnITzeN/WXXxVD1FkiSR71QHKysbplUp2GeTgHAw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.common/-/teams.common-2.0.2.tgz", + "integrity": "sha512-IFQJ7KOADspZL2sIWR+n7LnS3prYulB7IXmn62YcxDLsuq9UZsGxLERM3CeagiCh8Thb5OxERxyCwzhuS9Fx6w==", "license": "MIT", "dependencies": { - "axios": "^1.8.2", - "express": "^4.21.0", - "jsonwebtoken": "^9.0.2", - "uuid": "^11.0.5", - "ws": "^8.18.1" + "axios": "^1.12.0" }, "engines": { "node": ">=20" - }, - "peerDependencies": { - "@microsoft/teams.api": "2.0.0-preview.6", - "@microsoft/teams.apps": "2.0.0-preview.6", - "@microsoft/teams.cards": "2.0.0-preview.6", - "@microsoft/teams.common": "2.0.0-preview.6", - "@microsoft/teams.graph": "2.0.0-preview.6" } }, "node_modules/@microsoft/teams.graph": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.graph/-/teams.graph-2.0.0-preview.6.tgz", - "integrity": "sha512-AZJQlVC+JwGvLsHK3BPyGSf/uOFkpJxepLxmnwyjNUJuO36PpjhrDz3aTaWiE5nGrIQ8oksnUNJx2aECu9gJfQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.graph/-/teams.graph-2.0.2.tgz", + "integrity": "sha512-JbmdnMPKmayTtamiDY24IgLwzrJvZPN0FBYA3DsMdlDgJrPAWRx+JXdBn39offGcVIoQed6SYlsay6EiTE9Hig==", "license": "MIT", "dependencies": { - "@microsoft/teams.common": "2.0.0-preview.6", + "@microsoft/teams.common": "2.0.2", "qs": "^6.13.0" }, "engines": { @@ -824,9 +927,9 @@ } }, "node_modules/@microsoft/teams.openai": { - "version": "2.0.0-preview.6", - "resolved": "https://registry.npmjs.org/@microsoft/teams.openai/-/teams.openai-2.0.0-preview.6.tgz", - "integrity": "sha512-9O9G6yTfFgWqKhiAB7q31W89hHIIJJ99QbY712rJ2j5QXOBulZlCTa07OkgSs5Aa5NHiBpXJWUp9d/5eddq7tA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.openai/-/teams.openai-2.0.2.tgz", + "integrity": "sha512-e2yp+fcFnmfWisxvMe9yuyUlAPC7/xQq5669QDpSQQtuUU8Lr105s4ZP62TcYH2qfC74iE8WcfSSJFzJNfU4mg==", "license": "MIT", "dependencies": { "@azure/openai": "^2.0.0" @@ -835,8 +938,8 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.ai": "2.0.0-preview.6", - "@microsoft/teams.common": "2.0.0-preview.6", + "@microsoft/teams.ai": "2.0.2", + "@microsoft/teams.common": "2.0.2", "openai": "^4.55.0" } }, @@ -1722,6 +1825,21 @@ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bundle-require": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", @@ -2084,6 +2202,46 @@ "node": ">=4.0.0" } }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3053,6 +3211,21 @@ "node": ">=8" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3086,6 +3259,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3108,6 +3299,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3798,6 +4004,24 @@ "fn.name": "1.x.x" } }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openai": { "version": "4.104.0", "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", @@ -4265,6 +4489,18 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5302,19 +5538,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -5520,6 +5743,8 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -5536,6 +5761,21 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/collaborator-agent/package.json b/collaborator-agent/package.json index c9d6b91c..6f5a20d5 100644 --- a/collaborator-agent/package.json +++ b/collaborator-agent/package.json @@ -12,7 +12,7 @@ "scripts": { "clean": "npx rimraf ./dist", "build": "npx tsup", - "start": "node .", + "start": "node ./dist/index.js", "dev": "npx nodemon -w \"./src/**\" -e ts --exec \"node -r ts-node/register -r dotenv/config ./src/index.ts\"", "dev:teamsfx": "npx cross-env NODE_OPTIONS='--inspect=9239' env-cmd --silent -f .localConfigs npm run dev", "dev:teamsfx:playground": "npx cross-env NODE_OPTIONS='--inspect=9239' env-cmd --silent -f .localConfigs.playground npm run dev", @@ -20,14 +20,14 @@ "generate-mock": "npx ts-node src/mock/processMessageContent.ts" }, "dependencies": { - "@microsoft/teams.ai": "^2.0.0-preview.5", - "@microsoft/teams.api": "^2.0.0-preview.5", - "@microsoft/teams.apps": "^2.0.0-preview.5", - "@microsoft/teams.cards": "^2.0.0-preview.5", - "@microsoft/teams.common": "^2.0.0-preview.5", - "@microsoft/teams.dev": "^2.0.0-preview.5", - "@microsoft/teams.graph": "^2.0.0-preview.5", - "@microsoft/teams.openai": "^2.0.0-preview.5", + "@azure/identity": "^4.13.0", + "@microsoft/teams.ai": "^2.0.0", + "@microsoft/teams.api": "^2.0.0", + "@microsoft/teams.apps": "^2.0.0", + "@microsoft/teams.cards": "^2.0.0", + "@microsoft/teams.common": "^2.0.0", + "@microsoft/teams.graph": "^2.0.0", + "@microsoft/teams.openai": "^2.0.0", "@types/better-sqlite3": "^7.6.12", "better-sqlite3": "^11.9.0", "node-html-markdown": "^1.3.0", diff --git a/collaborator-agent/src/index.ts b/collaborator-agent/src/index.ts index 47a377e1..1facbb23 100644 --- a/collaborator-agent/src/index.ts +++ b/collaborator-agent/src/index.ts @@ -1,14 +1,39 @@ +import { ManagedIdentityCredential } from '@azure/identity'; +import { TokenCredentials } from '@microsoft/teams.api'; import { App } from '@microsoft/teams.apps'; +import { ConsoleLogger } from '@microsoft/teams.common'; import { ManagerPrompt } from './agent/manager'; -import { validateEnvironment, logModelConfigs } from './utils/config'; -import { finalizePromptResponse, createMessageRecords } from './utils/utils'; -import { createMessageContext } from './utils/messageContext'; import { SqliteKVStore } from './storage/storage'; -import { ConsoleLogger } from '@microsoft/teams.common'; +import { logModelConfigs, validateEnvironment } from './utils/config'; +import { createMessageContext } from './utils/messageContext'; +import { createMessageRecords, finalizePromptResponse } from './utils/utils'; const logger = new ConsoleLogger('collaborator', { level: 'debug' }); +const createTokenFactory = () => { + return async (scope: string | string[], tenantId?: string): Promise => { + const managedIdentityCredential = new ManagedIdentityCredential({ + clientId: process.env.CLIENT_ID + }); + const scopes = Array.isArray(scope) ? scope : [scope]; + const tokenResponse = await managedIdentityCredential.getToken(scopes, { + tenantId: tenantId + }); + + return tokenResponse.token; + }; +}; + +// Configure authentication using TokenCredentials +const tokenCredentials: TokenCredentials = { + clientId: process.env.CLIENT_ID || '', + token: createTokenFactory() +}; + +const credentialOptions = process.env.BOT_TYPE === "UserAssignedMsi" ? { ...tokenCredentials } : undefined; + const app = new App({ + ...credentialOptions, logger }); @@ -72,7 +97,6 @@ app.on('install.add', async ({ send }) => { }); (async ( ) => { - const port = +(process.env.PORT || 3978); try { validateEnvironment(logger); logModelConfigs(logger); @@ -81,7 +105,8 @@ app.on('install.add', async ({ send }) => { process.exit(1); } - await app.start(port); - - logger.debug(`🚀 Collab Agent started on port ${port}`); + await app.start(process.env.PORT || process.env.port || 3978); + logger.debug(`🚀 Collab Agent started on port ${process.env.PORT || process.env.port || 3978}`); })(); + +export default app; diff --git a/collaborator-agent/tsup.config.js b/collaborator-agent/tsup.config.js index 32277a72..f1bc6df4 100644 --- a/collaborator-agent/tsup.config.js +++ b/collaborator-agent/tsup.config.js @@ -2,10 +2,10 @@ module.exports = { dts: true, minify: false, - bundle: false, + bundle: true, sourcemap: true, treeshake: true, - splitting: true, + splitting: false, clean: true, outDir: 'dist', entry: ['src/index.ts'], diff --git a/collaborator-agent/web.config b/collaborator-agent/web.config new file mode 100644 index 00000000..9a7f2fa9 --- /dev/null +++ b/collaborator-agent/web.config @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data-analyst-agent-v2/.gitignore b/data-analyst-agent-v2/.gitignore index adc8850c..bde5a8ed 100644 --- a/data-analyst-agent-v2/.gitignore +++ b/data-analyst-agent-v2/.gitignore @@ -10,3 +10,4 @@ evals/logs/ .localConfigs .localConfigs.playground +dist diff --git a/data-analyst-agent-v2/.webappignore b/data-analyst-agent-v2/.webappignore new file mode 100644 index 00000000..2a59f587 --- /dev/null +++ b/data-analyst-agent-v2/.webappignore @@ -0,0 +1,28 @@ +.webappignore +.fx +.deployment +.localConfigs.playground +.localConfigs +.notification.localstore.json +.notification.playgroundstore.json +.vscode +*.js.map +*.ts.map +*.ts +.git* +.tsbuildinfo +CHANGELOG.md +readme.md +local.settings.json +test +tsconfig.json +.DS_Store +m365agents.yml +m365agents.*.yml +/env/ +/node_modules/.bin +/node_modules/ts-node +/node_modules/typescript +/appPackage/ +/infra/ +/devTools/ \ No newline at end of file diff --git a/data-analyst-agent-v2/infra/azure.bicep b/data-analyst-agent-v2/infra/azure.bicep index 434d22d7..f80f392a 100644 --- a/data-analyst-agent-v2/infra/azure.bicep +++ b/data-analyst-agent-v2/infra/azure.bicep @@ -61,13 +61,17 @@ resource webApp 'Microsoft.Web/sites@2021-02-01' = { value: '1' } { - name: 'clientId' + name: 'CLIENT_ID' value: identity.properties.clientId } { - name: 'tenantId' + name: 'TENANT_ID' value: identity.properties.tenantId } + { + name: 'BOT_TYPE' + value: 'UserAssignedMsi' + } { name: 'AZURE_OPENAI_API_KEY' value: azureOpenAIKey diff --git a/data-analyst-agent-v2/package-lock.json b/data-analyst-agent-v2/package-lock.json index 05c049db..0012ba46 100644 --- a/data-analyst-agent-v2/package-lock.json +++ b/data-analyst-agent-v2/package-lock.json @@ -9,14 +9,14 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@microsoft/teams.ai": "^2.0.0-preview.9", - "@microsoft/teams.api": "^2.0.0-preview.9", - "@microsoft/teams.apps": "^2.0.0-preview.9", - "@microsoft/teams.cards": "^2.0.0-preview.9", - "@microsoft/teams.common": "^2.0.0-preview.9", - "@microsoft/teams.dev": "^2.0.0-preview.9", - "@microsoft/teams.graph": "^2.0.0-preview.9", - "@microsoft/teams.openai": "^2.0.0-preview.9", + "@azure/identity": "^4.13.0", + "@microsoft/teams.ai": "^2.0.0", + "@microsoft/teams.api": "^2.0.0", + "@microsoft/teams.apps": "^2.0.0", + "@microsoft/teams.cards": "^2.0.0", + "@microsoft/teams.common": "^2.0.0", + "@microsoft/teams.graph": "^2.0.0", + "@microsoft/teams.openai": "^2.0.0", "better-sqlite3": "^11.10.0", "chalk": "^5.3.0", "dotenv": "^16.4.5", @@ -25,7 +25,7 @@ "devDependencies": { "@types/better-sqlite3": "^7.6.13", "@types/node": "^22.5.4", - "env-cmd": "*", + "env-cmd": "latest", "nodemon": "^3.1.4", "rimraf": "^6.0.1", "ts-node": "^10.9.2", @@ -63,74 +63,200 @@ } }, "node_modules/@azure/core-auth": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz", - "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-util": "^1.11.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.20.0.tgz", - "integrity": "sha512-ASoP8uqZBS3H/8N8at/XwFr6vYrRP3syTK0EUjDXQy0Y1/AUS+QeIRThKmTNJO2RggvBBxaXDPM7YoIwDGeA0g==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.2.tgz", + "integrity": "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-auth": "^1.8.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.11.0", - "@azure/logger": "^1.0.0", - "@typespec/ts-http-runtime": "^0.2.2", + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/core-tracing": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", - "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", "license": "MIT", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-util": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.12.0.tgz", - "integrity": "sha512-13IyjTQgABPARvG90+N2dXpC+hwp466XCdQXPCRlbWHgd3SJd5Q1VvaBGv6k1BIa4MQm6hAF1UBU1m8QUxV8sQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@typespec/ts-http-runtime": "^0.2.2", + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.0.tgz", + "integrity": "sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.5.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@azure/logger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.2.0.tgz", - "integrity": "sha512-0hKEzLhpw+ZTAfNJyRrn6s+V0nDWzXk9OjBr2TiGIu0OfMr5s2V4FpKLTAK3Ca5r5OKLbf4hkOGDPyiRjie/jA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", "license": "MIT", "dependencies": { - "@typespec/ts-http-runtime": "^0.2.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@azure/logger/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", + "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.26.1.tgz", + "integrity": "sha512-GGCIsZXxyNm5QcQZ4maA9q+9UWmM+/87G+ybvPkrE32el1URSa9WYt0t67ks3/P0gspZX9RoEqyLqJ/X/JDnBQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.13.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.13.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.13.1.tgz", + "integrity": "sha512-vQYQcG4J43UWgo1lj7LcmdsGUKWYo28RfEvDQAEMmQIMjSFufvb+pS0FJ3KXmrPmnWlt1vHDl3oip6mIDUQ4uA==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.1.tgz", + "integrity": "sha512-HszfqoC+i2C9+BRDQfuNUGp15Re7menIhCEbFCQ49D3KaqEDrgZIgQ8zSct4T59jWeUIL9N/Dwiv4o2VueTdqQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.13.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/@azure/openai": { @@ -667,21 +793,21 @@ } }, "node_modules/@microsoft/teams.ai": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.ai/-/teams.ai-2.0.0-preview.9.tgz", - "integrity": "sha512-ODmHpzUBMOsbZLiufdGPFWG0mi+x/qy9QF2E+HI0qMKqJInPUxIS0ueniSBUTSJarH+S8ZesNkG5nnyAtscItA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.ai/-/teams.ai-2.0.2.tgz", + "integrity": "sha512-Qrz8R+6M1w1o4P14G/CiTk/CFA0P0SpTDqsmK5FPd0qu4jDTi8EG+2z7nzsl55+fdAL+idr3J9Diit7Bler0qA==", "license": "MIT", "engines": { "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.common": "2.0.0-preview.9" + "@microsoft/teams.common": "2.0.2" } }, "node_modules/@microsoft/teams.api": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.api/-/teams.api-2.0.0-preview.9.tgz", - "integrity": "sha512-eSLy+mDYY1/XsLKagwaN8D0XS8JLNlSumYxjEvJ4FKcuvxBK415zQRAh4m9bW0r6KQJINt4IfN8fgOLI0WHp5g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.api/-/teams.api-2.0.2.tgz", + "integrity": "sha512-TAczlRa02N8VoSkl/XyAdMY82B4MnBwk6XZzmAy7tJWZAudrfNRWJ4qDra9XtJ/eoGF1kKgzGBPTBT8cmH8nzw==", "license": "MIT", "dependencies": { "jwt-decode": "^4.0.0", @@ -691,17 +817,17 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.cards": "2.0.0-preview.9", - "@microsoft/teams.common": "2.0.0-preview.9" + "@microsoft/teams.cards": "2.0.2", + "@microsoft/teams.common": "2.0.2" } }, "node_modules/@microsoft/teams.apps": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.apps/-/teams.apps-2.0.0-preview.9.tgz", - "integrity": "sha512-PQgMMiDmKkaBUp9zfYVEFeZNz+BC1W+07Ki6CH53jqZPcqzY3OwwSn+vZ7rcBQfwiThBUWhRf96WhQbd0qPl6A==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.apps/-/teams.apps-2.0.2.tgz", + "integrity": "sha512-IDr7mNJQhOFPAWKaSFMFRhscMapV+b9T+Kq9zfyUdSzPyDG9ayubikC+3na4SRCrRuVqkceUP9VV5c6ZMTagQw==", "license": "MIT", "dependencies": { - "axios": "^1.8.2", + "axios": "^1.12.0", "cors": "^2.8.5", "express": "^4.21.0", "jsonwebtoken": "^9.0.2", @@ -712,62 +838,39 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.api": "2.0.0-preview.9", - "@microsoft/teams.common": "2.0.0-preview.9", - "@microsoft/teams.graph": "2.0.0-preview.9" + "@microsoft/teams.api": "2.0.2", + "@microsoft/teams.common": "2.0.2", + "@microsoft/teams.graph": "2.0.2" } }, "node_modules/@microsoft/teams.cards": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.cards/-/teams.cards-2.0.0-preview.9.tgz", - "integrity": "sha512-5feD0SEpxS6KgdgDPaiMoxTH87iqWwacDs/UgYHixIjdmpLS/6rtBeji7czQlcOwUNqKddThpjl4n6wR9N3K2w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.cards/-/teams.cards-2.0.2.tgz", + "integrity": "sha512-E/QLeeb3owS3oyRKFw7Pvcoo2qrnAI6+kv0/t4Ed0XM9jyKi+bc1ro/JhwxtgiLyodNoThQVu8f/7TYihvRI4w==", "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/@microsoft/teams.common": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.common/-/teams.common-2.0.0-preview.9.tgz", - "integrity": "sha512-/CGQ7WTJ74EgIcEzPQkhI/7MAi/c07GBBpbIK4S/YFmriIy2P00W24MmYpHsxhSnruEG6cInn8MaWV5cOH8ERg==", - "license": "MIT", - "dependencies": { - "axios": "^1.8.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@microsoft/teams.dev": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.dev/-/teams.dev-2.0.0-preview.9.tgz", - "integrity": "sha512-bjEl4NjxvreuRxlM7b5ClKFlLaX6zQ1Jix2r/gPO5MDKUWAn2bqf8eBKX8rziZvPradm4SxqYa+60WOObikNLg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.common/-/teams.common-2.0.2.tgz", + "integrity": "sha512-IFQJ7KOADspZL2sIWR+n7LnS3prYulB7IXmn62YcxDLsuq9UZsGxLERM3CeagiCh8Thb5OxERxyCwzhuS9Fx6w==", "license": "MIT", "dependencies": { - "axios": "^1.8.2", - "express": "^4.21.0", - "jsonwebtoken": "^9.0.2", - "uuid": "^11.0.5", - "ws": "^8.18.1" + "axios": "^1.12.0" }, "engines": { "node": ">=20" - }, - "peerDependencies": { - "@microsoft/teams.api": "2.0.0-preview.9", - "@microsoft/teams.apps": "2.0.0-preview.9", - "@microsoft/teams.cards": "2.0.0-preview.9", - "@microsoft/teams.common": "2.0.0-preview.9", - "@microsoft/teams.graph": "2.0.0-preview.9" } }, "node_modules/@microsoft/teams.graph": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.graph/-/teams.graph-2.0.0-preview.9.tgz", - "integrity": "sha512-UWxrkPmsaFswJegf2c5OmtCC5PnosEQ1D7wFttBnZcV03pTfNTFHDaV2kGGY4+bOit7Vcz7yFaS4yXV7/gc+JQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.graph/-/teams.graph-2.0.2.tgz", + "integrity": "sha512-JbmdnMPKmayTtamiDY24IgLwzrJvZPN0FBYA3DsMdlDgJrPAWRx+JXdBn39offGcVIoQed6SYlsay6EiTE9Hig==", "license": "MIT", "dependencies": { - "@microsoft/teams.common": "2.0.0-preview.9", + "@microsoft/teams.common": "2.0.2", "qs": "^6.13.0" }, "engines": { @@ -775,9 +878,9 @@ } }, "node_modules/@microsoft/teams.openai": { - "version": "2.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@microsoft/teams.openai/-/teams.openai-2.0.0-preview.9.tgz", - "integrity": "sha512-CgT9GKJvphMUk3Wk8KCUddsFV+O/GcdF5GCcas/CtT4Hl49TwGz6lLcpjeH4Es+4pn8gz8h5qhZlsdOCgpDvFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/teams.openai/-/teams.openai-2.0.2.tgz", + "integrity": "sha512-e2yp+fcFnmfWisxvMe9yuyUlAPC7/xQq5669QDpSQQtuUU8Lr105s4ZP62TcYH2qfC74iE8WcfSSJFzJNfU4mg==", "license": "MIT", "dependencies": { "@azure/openai": "^2.0.0" @@ -786,8 +889,8 @@ "node": ">=20" }, "peerDependencies": { - "@microsoft/teams.ai": "2.0.0-preview.9", - "@microsoft/teams.common": "2.0.0-preview.9", + "@microsoft/teams.ai": "2.0.2", + "@microsoft/teams.common": "2.0.2", "openai": "^4.55.0" } }, @@ -1406,13 +1509,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -1580,6 +1683,21 @@ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bundle-require": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", @@ -1857,6 +1975,46 @@ "node": ">=4.0.0" } }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2684,6 +2842,21 @@ "node": ">=8" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2717,6 +2890,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2727,6 +2918,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3359,6 +3565,24 @@ "wrappy": "1" } }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openai": { "version": "4.104.0", "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", @@ -3787,6 +4011,18 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4721,19 +4957,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -4904,6 +5127,8 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -4920,6 +5145,21 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/data-analyst-agent-v2/package.json b/data-analyst-agent-v2/package.json index 4246262e..5c0345e7 100644 --- a/data-analyst-agent-v2/package.json +++ b/data-analyst-agent-v2/package.json @@ -12,7 +12,7 @@ "scripts": { "clean": "npx rimraf ./dist", "build": "npx tsup", - "start": "node .", + "start": "node ./dist/index.js", "dev": "npx nodemon -w \"./src/**\" -e ts --exec \"node -r ts-node/register -r dotenv/config ./src/index.ts\"", "dev:teamsfx": "env-cmd --silent -f .localConfigs npm run dev", "dev:teamsfx:playground": "env-cmd --silent -f .localConfigs.playground npm run dev", @@ -23,14 +23,14 @@ "eval:ac:one": "ts-node -r dotenv/config evals/skills/adaptive-card-generation.ts --run-one" }, "dependencies": { - "@microsoft/teams.ai": "^2.0.0-preview.9", - "@microsoft/teams.api": "^2.0.0-preview.9", - "@microsoft/teams.apps": "^2.0.0-preview.9", - "@microsoft/teams.cards": "^2.0.0-preview.9", - "@microsoft/teams.common": "^2.0.0-preview.9", - "@microsoft/teams.dev": "^2.0.0-preview.9", - "@microsoft/teams.graph": "^2.0.0-preview.9", - "@microsoft/teams.openai": "^2.0.0-preview.9", + "@azure/identity": "^4.13.0", + "@microsoft/teams.ai": "^2.0.0", + "@microsoft/teams.api": "^2.0.0", + "@microsoft/teams.apps": "^2.0.0", + "@microsoft/teams.cards": "^2.0.0", + "@microsoft/teams.common": "^2.0.0", + "@microsoft/teams.graph": "^2.0.0", + "@microsoft/teams.openai": "^2.0.0", "better-sqlite3": "^11.10.0", "chalk": "^5.3.0", "dotenv": "^16.4.5", diff --git a/data-analyst-agent-v2/src/index.ts b/data-analyst-agent-v2/src/index.ts index bf91aa50..726a2ca5 100644 --- a/data-analyst-agent-v2/src/index.ts +++ b/data-analyst-agent-v2/src/index.ts @@ -1,12 +1,36 @@ +import { ManagedIdentityCredential } from '@azure/identity'; +import { Message } from '@microsoft/teams.ai'; +import { MessageActivity, TokenCredentials } from '@microsoft/teams.api'; import { App } from '@microsoft/teams.apps'; import { ConsoleLogger } from '@microsoft/teams.common'; import { createDataAnalystPrompt } from './prompt'; -import { MessageActivity } from '@microsoft/teams.api'; -import { Message } from '@microsoft/teams.ai'; const conversationHistoryById = new Map(); +const createTokenFactory = () => { + return async (scope: string | string[], tenantId?: string): Promise => { + const managedIdentityCredential = new ManagedIdentityCredential({ + clientId: process.env.CLIENT_ID + }); + const scopes = Array.isArray(scope) ? scope : [scope]; + const tokenResponse = await managedIdentityCredential.getToken(scopes, { + tenantId: tenantId + }); + + return tokenResponse.token; + }; +}; + +// Configure authentication using TokenCredentials +const tokenCredentials: TokenCredentials = { + clientId: process.env.CLIENT_ID || '', + token: createTokenFactory() +}; + +const credentialOptions = process.env.BOT_TYPE === "UserAssignedMsi" ? { ...tokenCredentials } : undefined; + const app = new App({ + ...credentialOptions, logger: new ConsoleLogger('adventureworks-data-analyst', { level: 'debug' }) }); @@ -55,5 +79,8 @@ app.on('message', async ({ send, activity, stream }) => { }); (async () => { - await app.start(+(process.env.PORT || 3978)); -})(); \ No newline at end of file + await app.start(process.env.PORT || process.env.port || 3978); + console.log(`\nAgent started, app listening to`, process.env.PORT || process.env.port || 3978); +})(); + +export default app; diff --git a/data-analyst-agent-v2/tsup.config.js b/data-analyst-agent-v2/tsup.config.js index 32277a72..f1bc6df4 100644 --- a/data-analyst-agent-v2/tsup.config.js +++ b/data-analyst-agent-v2/tsup.config.js @@ -2,10 +2,10 @@ module.exports = { dts: true, minify: false, - bundle: false, + bundle: true, sourcemap: true, treeshake: true, - splitting: true, + splitting: false, clean: true, outDir: 'dist', entry: ['src/index.ts'], diff --git a/data-analyst-agent-v2/web.config b/data-analyst-agent-v2/web.config new file mode 100644 index 00000000..9a7f2fa9 --- /dev/null +++ b/data-analyst-agent-v2/web.config @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/travel-agent/M365Agent/infra/azure.bicep b/travel-agent/M365Agent/infra/azure.bicep index ad4da3ce..73b27353 100644 --- a/travel-agent/M365Agent/infra/azure.bicep +++ b/travel-agent/M365Agent/infra/azure.bicep @@ -14,7 +14,7 @@ param webAppSKU string param botDisplayName string param environment string -param botDomain string +param botDomain string = '' param deployAppService bool = environment != 'local' // For OAuth connection of bot service, created outside of Bicep @@ -114,6 +114,7 @@ module azureBotRegistration './botRegistration/azurebot.bicep' = { } // The output will be persisted in .env.{envName}. Visit https://aka.ms/teamsfx-actions/arm-deploy for more details. +output BOT_AZURE_APP_SERVICE_RESOURCE_ID string = deployAppService ? webApp.id : '' output BOT_DOMAIN string = deployAppService ? webApp.properties.defaultHostName : botDomain output BOT_ID string = deployAppService ? identity.properties.clientId :aadAppClientId output BOT_TENANT_ID string = identity.properties.tenantId diff --git a/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep b/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep index 800228fe..7b07bf95 100644 --- a/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep +++ b/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep @@ -29,7 +29,7 @@ resource botService 'Microsoft.BotService/botServices@2021-03-01' = { msaAppId: deployAppService ? identityClientId : botConnectionClientId msaAppMSIResourceId: deployAppService ? identityResourceId : '' msaAppTenantId: identityTenantId - msaAppType: deployAppService ? 'ManagedIdentity' : 'SingleTenant' + msaAppType: deployAppService ? 'UserAssignedMSI' : 'SingleTenant' } sku: { name: botServiceSku diff --git a/travel-agent/README.md b/travel-agent/README.md index 1fb13bd8..6819d18d 100644 --- a/travel-agent/README.md +++ b/travel-agent/README.md @@ -4,7 +4,7 @@ This sample demonstrates how to build an intelligent travel agent using the Micr The Travel Agent leverages Azure OpenAI and the Microsoft 365 Retrieval API to access company travel documents and policies stored in SharePoint or OneDrive for Business, providing contextual and policy-compliant travel recommendations directly within Microsoft Teams. -![Sample response from agent](../assets/sampleResponse.png) +![Sample response from agent](./assets/sampleResponse.png) ## This sample illustrates diff --git a/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs b/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs index d5901f34..cb953610 100644 --- a/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs +++ b/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs @@ -1,4 +1,5 @@ using Microsoft.Agents.AI; +using Microsoft.Agents.Builder; using Microsoft.Agents.Builder.App; using Microsoft.Extensions.AI; using System.Text.Json.Nodes; @@ -22,7 +23,7 @@ You have access to all user information. When a customer asks a question about travel policies in domains mentioned, use the Retrieval Plugin to search the documents and find relevant information, and summarize result with referenced document to user. - When a customer asks a question about booking hotel/flight, first use the Retrieval Plugin to search the documents and find relevant information. + When a customer asks a question about booking hotel/flight, first use the RetrievalPlugin to search the documents and find relevant information. Then, summarize the relevant information into a set of rules of related policies and the referenced documents. After that, use DataPlugin to call the external flight/hotel API to get data. Leave location/destination parameter empty string is user does not specify. Ask for user input if date parameter is missing. Finally, combine the rules from documents and the data from external API to answer the user's question. @@ -42,7 +43,9 @@ Each choice should followed by justification of related policies. Make sure just /// Initializes a new instance of the class. /// /// An instance of for interacting with an LLM. - public TravelAgent(IChatClient chatClient, AgentApplication app) + /// The agent application instance. + /// The turn context for the current conversation. + public TravelAgent(IChatClient chatClient, AgentApplication app, ITurnContext turnContext) { var tools = new List(); @@ -55,7 +58,7 @@ public TravelAgent(IChatClient chatClient, AgentApplication app) var dataPlugin = new DataPlugin(); tools.Add(AIFunctionFactory.Create(dataPlugin.GetHotelFlightDataAsync)); - var retrievalPlugin = new RetrievalPlugin(app); + var retrievalPlugin = new RetrievalPlugin(app, turnContext); tools.Add(AIFunctionFactory.Create(retrievalPlugin.BuildRetrievalAsync)); _agent = chatClient.CreateAIAgent(instructions: AgentInstructions, tools: tools); diff --git a/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs b/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs index d4c4898b..b38eddbc 100644 --- a/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs +++ b/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs @@ -5,13 +5,12 @@ using Microsoft.Kiota.Abstractions.Authentication; using Microsoft.Kiota.Http.HttpClientLibrary; using Microsoft.Agents.M365Copilot.Beta.Models; +using Microsoft.Agents.Builder; namespace TravelAgent.Bot.Plugins { - public class RetrievalPlugin(AgentApplication app) + public class RetrievalPlugin(AgentApplication app, ITurnContext turnContext) { - AgentApplication _app = app; - /// /// Retrieve travel policies about expenses use graph API. /// @@ -20,9 +19,7 @@ public class RetrievalPlugin(AgentApplication app) [Description("This function talks to Microsoft 365 Copilot Retrieval API and gets travel policies about expenses and reimbursements, flight booking, ground transportation, hotel accommodations which are nicely formatted. It accepts user query as input and send out a chunk of relevant text and a link to the file in the results.")] public async Task BuildRetrievalAsync(string userquery) { -#pragma warning disable CS0618 // Type or member is obsolete - string accessToken = _app.UserAuthorization.GetTurnToken("graph"); -#pragma warning restore CS0618 // Type or member is obsolete + string accessToken = await app.UserAuthorization.GetTurnTokenAsync(turnContext, "graph"); var tokenProvider = new StaticTokenProvider(accessToken); var authProvider = new BaseBearerTokenAuthenticationProvider(tokenProvider); var requestAdapter = new HttpClientRequestAdapter(authProvider); diff --git a/travel-agent/TravelAgent/Bot/TravelAgentBot.cs b/travel-agent/TravelAgent/Bot/TravelAgentBot.cs index 92a8de44..4ba171cb 100644 --- a/travel-agent/TravelAgent/Bot/TravelAgentBot.cs +++ b/travel-agent/TravelAgent/Bot/TravelAgentBot.cs @@ -19,7 +19,7 @@ public TravelAgentBot(AgentApplicationOptions options, IChatClient chatClient) : _chatClient = chatClient ?? throw new ArgumentNullException(nameof(chatClient)); OnConversationUpdate(ConversationUpdateEvents.MembersAdded, WelcomeMessageAsync); - OnActivity(ActivityTypes.Message, MessageActivityAsync, rank: RouteRank.Last); + OnActivity(ActivityTypes.Message, MessageActivityAsync, rank: RouteRank.Last, autoSignInHandlers: ["graph"]); } protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken) @@ -35,7 +35,7 @@ protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState t await turnContext.StreamingResponse.QueueInformativeUpdateAsync("Working on a response for you"); IList chatHistory = turnState.GetValue("conversation.chatHistory", () => new List()); - _travelAgent = new Agents.TravelAgent(_chatClient, this); + _travelAgent = new Agents.TravelAgent(_chatClient, this, turnContext); // Invoke the TravelAgent to process the message TravelAgentResponse travelResponse = await _travelAgent.InvokeAgentAsync(turnContext.Activity.Text, chatHistory); diff --git a/travel-agent/TravelAgent/appsettings.Development.json b/travel-agent/TravelAgent/appsettings.Development.json index 9f36b72a..7ad78877 100644 --- a/travel-agent/TravelAgent/appsettings.Development.json +++ b/travel-agent/TravelAgent/appsettings.Development.json @@ -5,7 +5,7 @@ "NormalizeMentions": false, "UserAuthorization": { "Default": "graph", - "AutoSignIn": true, + "AutoSignIn": false, "Handlers": { "graph": { "Settings": { diff --git a/travel-agent/TravelAgent/appsettings.json b/travel-agent/TravelAgent/appsettings.json index 21a066f5..5942be7f 100644 --- a/travel-agent/TravelAgent/appsettings.json +++ b/travel-agent/TravelAgent/appsettings.json @@ -5,7 +5,7 @@ "NormalizeMentions": false, "UserAuthorization": { "Default": "graph", - "AutoSignIn": true, + "AutoSignIn": false, "Handlers": { "graph": { "Settings": {