From 275e70acbba949fab9d70df9580af762ea979f72 Mon Sep 17 00:00:00 2001 From: Steven Kanberg Date: Thu, 31 Jul 2025 15:57:14 -0700 Subject: [PATCH 1/6] Adds the console echo agent sample --- samples/compat/console-echo/nodejs/README.md | 47 + .../console-echo/nodejs/package-lock.json | 893 ++++++++++++++++++ .../compat/console-echo/nodejs/package.json | 26 + .../console-echo/nodejs/src/consoleAdapter.ts | 229 +++++ .../console-echo/nodejs/src/dialogAgent.ts | 22 + .../compat/console-echo/nodejs/src/index.ts | 19 + .../compat/console-echo/nodejs/tsconfig.json | 20 + 7 files changed, 1256 insertions(+) create mode 100644 samples/compat/console-echo/nodejs/README.md create mode 100644 samples/compat/console-echo/nodejs/package-lock.json create mode 100644 samples/compat/console-echo/nodejs/package.json create mode 100644 samples/compat/console-echo/nodejs/src/consoleAdapter.ts create mode 100644 samples/compat/console-echo/nodejs/src/dialogAgent.ts create mode 100644 samples/compat/console-echo/nodejs/src/index.ts create mode 100644 samples/compat/console-echo/nodejs/tsconfig.json diff --git a/samples/compat/console-echo/nodejs/README.md b/samples/compat/console-echo/nodejs/README.md new file mode 100644 index 00000000..21c27120 --- /dev/null +++ b/samples/compat/console-echo/nodejs/README.md @@ -0,0 +1,47 @@ +# Console-echo + +This agent has been created with Agents SDK to demonstrate how to implement a simple conversational flow from the console window. + +## Prerequisites + +- [Node.js](https://nodejs.org) version 20 or higher + + ```bash + # determine node version + node --version + ``` + +## Running this sample + +1. Open this folder from your IDE or Terminal of preference +1. Install dependencies + + ```bash + npm install + ``` + +- Start the agent + + ```bash + npm start + ``` + +## Testing the agent + +After running `npm start`, the agent presents a prompt directly in the console window. + +Send messages to the agent by typing them into the console. The agent will echo your message back to you. + +## Adapters + +Adapters such as the `ConsoleAdapter` provide an abstraction for your agent to work with a variety of environments and messaging platforms. + +The adapter is responsible for directing incoming and outgoing communication, authentication, and so on. Adapters for different platforms and messaging technologies differ internally, but achieve the same goal - connecting agents to a stream of messages and events from users. +When your agent receives an activity, the adapter wraps up everything about that activity, creates a context object, passes it to your agent's application logic, and sends responses generated by your agent back to the user's channel. + +In most situations, we don't work with the adapter directly, but it's good to know it's there and what it does. In this example, we're using the +`ConsoleAdapter`, which provides a very simple way to exchange messages - they're sent and received via the console window. Using the ConsoleAdapter is a great way of getting started quickly with Agents. It also allows you to build and test agents that operate on your local machine without any external API calls or client applications. + +## Further reading + +To learn more about building Bots and Agents, see our [Microsoft 365 Agents SDK](https://github.com/microsoft/agents) repo. diff --git a/samples/compat/console-echo/nodejs/package-lock.json b/samples/compat/console-echo/nodejs/package-lock.json new file mode 100644 index 00000000..ff67894c --- /dev/null +++ b/samples/compat/console-echo/nodejs/package-lock.json @@ -0,0 +1,893 @@ +{ + "name": "console-echho-agent", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "console-echho-agent", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@microsoft/agents-activity": "^1.0.0", + "@microsoft/agents-hosting": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^22.13.4", + "esbuild": "^0.25.0", + "typescript": "^5.7.2" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.0.tgz", + "integrity": "sha512-88Djs5vBvGbHQHf5ZZcaoNHo6Y8BKZkt3cw2iuJIQzLEgH4Ox6Tm4hjFhbqOxyYsgIG/eJbFEHpxRIfEEWv5Ow==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.0.tgz", + "integrity": "sha512-o0psW8QWQ58fq3i24Q1K2XfS/jYTxr7O1HRcyUE9bV9NttLU+kYOH82Ixj8DGlMTOWgxm1Sss2QAfKK5UkSPxw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.9.0.tgz", + "integrity": "sha512-lbz/D+C9ixUG3hiZzBLjU79a0+5ZXCorjel3mwXluisKNH0/rOS/ajm8yi4yI9RP5Uc70CAcs9Ipd0051Oh/kA==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.6.4.tgz", + "integrity": "sha512-jMeut9UQugcmq7aPWWlJKhJIse4DQ594zc/JaP6BIxg55XaX3aM/jcPuIQ4ryHnI4QSf03wUspy/uqAvjWKbOg==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.9.0", + "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/@esbuild/win32-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@microsoft/agents-activity": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/agents-activity/-/agents-activity-1.0.0.tgz", + "integrity": "sha512-AQm5NWQ5wWcH0dfvWqTdpAjLX6Fckk2d8mXkG1O8KZCFM67kG0os9G2ONurBZjGFITaIryNfNl6quxnixU6SAQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.7", + "uuid": "^11.1.0", + "zod": "3.25.75" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@microsoft/agents-hosting": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/agents-hosting/-/agents-hosting-1.0.0.tgz", + "integrity": "sha512-7vL9H/jpy8ujJOk7KKSrRC4HKiA0m+GoWoTT9PRHNwmDfIPGU7yAaDLON7NrBOLYZwTDrKg6isMrd6OYigqeSg==", + "license": "MIT", + "dependencies": { + "@azure/core-auth": "^1.10.0", + "@azure/msal-node": "^3.6.0", + "@microsoft/agents-activity": "1.0.0", + "axios": "^1.10.0", + "jsonwebtoken": "^9.0.2", + "jwks-rsa": "^3.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.17.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", + "integrity": "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.0.tgz", + "integrity": "sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==", + "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/agent-base": { + "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" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", + "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.20", + "@types/jsonwebtoken": "^9.0.4", + "debug": "^4.3.4", + "jose": "^4.15.4", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "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/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/zod": { + "version": "3.25.75", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", + "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/samples/compat/console-echo/nodejs/package.json b/samples/compat/console-echo/nodejs/package.json new file mode 100644 index 00000000..9aa7396b --- /dev/null +++ b/samples/compat/console-echo/nodejs/package.json @@ -0,0 +1,26 @@ +{ + "name": "console-echo-agent", + "version": "1.0.0", + "private": true, + "description": "Agents console-echo", + "author": "Microsoft", + "license": "MIT", + "main": "./dist/index.js", + "scripts": { + "prebuild": "npm install", + "build": "tsc --build", + "prestart": "npm run build", + "start": "node ./dist/index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "@microsoft/agents-activity": "^1.0.0", + "@microsoft/agents-hosting": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^22.13.4", + "esbuild": "^0.25.0", + "typescript": "^5.7.2" + }, + "keywords": [] +} diff --git a/samples/compat/console-echo/nodejs/src/consoleAdapter.ts b/samples/compat/console-echo/nodejs/src/consoleAdapter.ts new file mode 100644 index 00000000..7a68118a --- /dev/null +++ b/samples/compat/console-echo/nodejs/src/consoleAdapter.ts @@ -0,0 +1,229 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { BaseAdapter, CloudAdapter, ResourceResponse, TurnContext } from '@microsoft/agents-hosting' +import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity' +import * as readline from 'readline'; + +/** + * Lets a user communicate with a bot from a console window. + * + * @remarks + * The following example shows the typical adapter setup: + * + * ```typescript + * import { ConsoleAdapter } from './consoleAdapter'; + * + * const adapter = new ConsoleAdapter(); + * const closeFn = adapter.listen(async (context) => { + * await context.sendActivity(`Hello World`); + * }); + * ``` + * + * This adapter is intended for local development and testing scenarios. + * It implements the CloudAdapter interface for compatibility with the Agents SDK. + */ +export class ConsoleAdapter extends CloudAdapter { + nextId: number; + reference: ConversationReference; + /** + * Creates a new ConsoleAdapter instance. + * @param [reference] Reference used to customize the address information of activities sent from the adapter. + */ + constructor( reference?: ConversationReference ) { + super(); + this.nextId = 0; + this.reference = { + ...reference, + channelId: 'console', + user: { id: 'user', name: 'User1' }, + agent: { id: 'bot', name: 'Bot' }, + conversation: { id: 'convo1', name: '', isGroup: false }, + serviceUrl: '' + }; + } + + /** + * Begins listening to console input. Returns a function that can be called to stop listening. + * + * @remarks + * When input is received from the console: + * - A 'message' activity is created with the user's input text. + * - A revocable `TurnContext` is created for the activity. + * - The context is routed through any middleware registered with [use()](#use). + * - The bot's logic handler is executed. + * - The middleware promise chain is resolved. + * - The context object is revoked, and future calls to its members will throw a `TypeError`. + * + * ```typescript + * const closeFn = adapter.listen(async (context) => { + * const utterance = context.activity.text.toLowerCase(); + * if (utterance.includes('goodbye')) { + * await context.sendActivity(`Ok... Goodbye`); + * closeFn(); + * } else { + * await context.sendActivity(`Hello World`); + * } + * }); + * ``` + * @param logic Function called each time a message is input by the user. + * @returns Function to stop listening to console input. + */ + listen ( logic: { ( context: TurnContext ): Promise; ( revocableContext: TurnContext ): Promise; } ) { + const rl = this.createInterface( { + input: process.stdin, + output: process.stdout, + terminal: false + } ); + rl.on( 'line', async line => { + // Initialize activity + const activity = Activity.fromObject( { type: ActivityTypes.Message, text: line } ); + activity.applyConversationReference( + this.reference, + true + ); + + // Create context and run middleware pipe + const context = new TurnContext( this as unknown as BaseAdapter, activity ); + await this.runMiddleware( context, logic ).catch( err => { + this.printError( err.toString() ); + } ); + } ); + return () => { + rl.close(); + }; + } + + /** + * Allows the bot to proactively message the user. + * + * @remarks + * The processing steps for this method are similar to [listen()](#listen): + * - A `TurnContext` is created and routed through the adapter's middleware. + * - The provided logic handler is executed. + * The main difference is that since no activity was received from the user, a new activity is created and populated with the provided conversation reference. + * The created activity will have its address-related fields populated, and `context.activity.type` will be set to `message`. + * + * ```typescript + * function delayedNotify(context, message, delay) { + * const reference = TurnContext.getConversationReference(context.activity); + * setTimeout(() => { + * adapter.continueConversation(reference, async (ctx) => { + * await ctx.sendActivity(message); + * }); + * }, delay); + * } + * ``` + * @param reference A `ConversationReference` saved during a previous message from a user. This can be calculated for any incoming activity using `TurnContext.getConversationReference(context.activity)`. + * @param logic A function handler that will be called to perform the bot's logic after the adapter's middleware has been run. + */ + continueConversation ( reference: ConversationReference, logic: ( revocableContext: TurnContext ) => Promise ) { + // Create context and run middleware pipe + const activity = new Activity( ActivityTypes.Message ); + activity.applyConversationReference( + reference, + true + ); + const context = new TurnContext( this as unknown as BaseAdapter, activity ); + return this.runMiddleware( context, logic ).catch( err => { + this.printError( err.toString() ); + } ); + } + + /** + * Sends a set of activities to the console. + * + * @remarks + * This method is called by `TurnContext.sendActivities()` or `TurnContext.sendActivity()` to output activities to the console. + * It ensures outgoing activities have been properly addressed, and prints them appropriately. + * Middleware and addressing are handled by the Agents SDK before this method is called. + * @param _context Context for the current turn of conversation with the user. + * @param activities List of activities to send. + */ + async sendActivities ( _context: TurnContext, activities: Activity[] ) { + /** @type {ResourceResponse[]} */ + const responses = []; + for ( const activity of activities ) { + // Generate a unique id for each activity response + const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`); + responses.push({ id }); + + switch ( activity.type ) { + case 'delay': + await this.sleep( Number(activity.value) ); + break; + case ActivityTypes.Message: + if ( + activity.attachments && + activity.attachments.length > 0 + ) { + const append = + activity.attachments.length === 1 + ? '(1 attachment)' + : `(${ activity.attachments.length } attachments)`; + this.print( `${ activity.text } ${ append }` ); + } else { + this.print( activity.text || '' ); + } + break; + default: + this.print( `[${ activity.type }]` ); + break; + } + } + return responses; + } + + /** + * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.updateActivity()` + * will result an error being returned. + */ + updateActivity ( _context: TurnContext, _activity: Activity ) { + return Promise.reject( new Error( 'ConsoleAdapter.updateActivity(): not supported.' ) ); + } + + /** + * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.deleteActivity()` + * will result an error being returned. + */ + deleteActivity ( _context: TurnContext, _reference: Partial ) { + return Promise.reject( new Error( 'ConsoleAdapter.deleteActivity(): not supported.' ) ); + } + + /** + * Allows for mocking of the console interface in unit tests. + * @param options Console interface options. + */ + createInterface ( options: any ) { + return readline.createInterface( options ); + } + + + /** + * Logs text to the console. + * @param line Text to print. + */ + print ( line: string ) { + console.log( line ); + } + + /** + * Logs an error to the console. + * @param line Error text to print. + */ + printError ( line: string ) { + console.error( line ); + } + + /** + * Puts the current thread to sleep for a specified duration. + * @param milliseconds Duration to sleep in milliseconds. + */ + sleep ( milliseconds: number ) { + return new Promise( resolve => { + setTimeout( resolve, milliseconds ); + } ); + } +} diff --git a/samples/compat/console-echo/nodejs/src/dialogAgent.ts b/samples/compat/console-echo/nodejs/src/dialogAgent.ts new file mode 100644 index 00000000..09f7d903 --- /dev/null +++ b/samples/compat/console-echo/nodejs/src/dialogAgent.ts @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { TurnContext } from '@microsoft/agents-hosting'; + +export class DialogAgent { + async onTurn ( context: TurnContext ) { + // Check to see if this activity is an incoming message. + // (It could theoretically be another type of activity.) + if ( context.activity.type === 'message' && context.activity.text ) { + // Check to see if the user sent a simple "quit" message. + if ( context.activity.text.toLowerCase() === 'quit' ) { + // Send a reply. + context.sendActivity( '> Bye!' ); + process.exit(); + } else { + // Echo the message text back to the user. + return context.sendActivity( `> I heard you say "${ context.activity.text }"` ); + } + } + } +} diff --git a/samples/compat/console-echo/nodejs/src/index.ts b/samples/compat/console-echo/nodejs/src/index.ts new file mode 100644 index 00000000..49219405 --- /dev/null +++ b/samples/compat/console-echo/nodejs/src/index.ts @@ -0,0 +1,19 @@ +import { ConsoleAdapter } from './consoleAdapter'; +import { DialogAgent } from './dialogAgent'; + +// Create the bot adapter, which is responsible for sending and receiving messages. +// We are using the ConsoleAdapter, which enables a bot you can chat with from within your terminal window. +const adapter = new ConsoleAdapter(); + +// Create the bot's main handler. +const myBot = new DialogAgent(); + +// A call to adapter.listen tells the adapter to start listening for incoming messages and events, known as "activities." +// Activities are received as TurnContext objects by the handler function. +adapter.listen( async ( context ) => { + myBot.onTurn( context ); +} ); + +// Emit a startup message with some instructions. +console.log( '> Console EchoBot is online. I will repeat any message you send me!' ); +console.log( '> Say "quit" to end.\n' ); \ No newline at end of file diff --git a/samples/compat/console-echo/nodejs/tsconfig.json b/samples/compat/console-echo/nodejs/tsconfig.json new file mode 100644 index 00000000..5fb9619c --- /dev/null +++ b/samples/compat/console-echo/nodejs/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "incremental": true, + "lib": ["ES2021"], + "target": "es2019", + "module": "commonjs", + "declaration": true, + "sourceMap": true, + "composite": true, + "strict": true, + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "rootDir": "src", + "outDir": "dist", + "tsBuildInfoFile": "dist/.tsbuildinfo" + } +} From df72d354d45fb5609442ed127251c8a1dbbd17c5 Mon Sep 17 00:00:00 2001 From: Steven Kanberg Date: Fri, 1 Aug 2025 10:35:59 -0700 Subject: [PATCH 2/6] Fix console-echo-agent name in package-lock.json and ensured proper async handling in index.ts --- .../compat/console-echo/nodejs/package-lock.json | 4 ++-- .../console-echo/nodejs/src/consoleAdapter.ts | 13 ++++++------- samples/compat/console-echo/nodejs/src/index.ts | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/samples/compat/console-echo/nodejs/package-lock.json b/samples/compat/console-echo/nodejs/package-lock.json index ff67894c..8fb0cfed 100644 --- a/samples/compat/console-echo/nodejs/package-lock.json +++ b/samples/compat/console-echo/nodejs/package-lock.json @@ -1,11 +1,11 @@ { - "name": "console-echho-agent", + "name": "console-echo-agent", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "console-echho-agent", + "name": "console-echo-agent", "version": "1.0.0", "license": "MIT", "dependencies": { diff --git a/samples/compat/console-echo/nodejs/src/consoleAdapter.ts b/samples/compat/console-echo/nodejs/src/consoleAdapter.ts index 7a68118a..b49a9f5a 100644 --- a/samples/compat/console-echo/nodejs/src/consoleAdapter.ts +++ b/samples/compat/console-echo/nodejs/src/consoleAdapter.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. */ -import { BaseAdapter, CloudAdapter, ResourceResponse, TurnContext } from '@microsoft/agents-hosting' -import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity' +import { BaseAdapter, CloudAdapter, ResourceResponse, TurnContext } from '@microsoft/agents-hosting'; +import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity'; import * as readline from 'readline'; /** @@ -89,7 +89,7 @@ export class ConsoleAdapter extends CloudAdapter { const context = new TurnContext( this as unknown as BaseAdapter, activity ); await this.runMiddleware( context, logic ).catch( err => { this.printError( err.toString() ); - } ); + } ); } ); return () => { rl.close(); @@ -147,12 +147,12 @@ export class ConsoleAdapter extends CloudAdapter { const responses = []; for ( const activity of activities ) { // Generate a unique id for each activity response - const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`); - responses.push({ id }); + const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`); + responses.push( { id } ); switch ( activity.type ) { case 'delay': - await this.sleep( Number(activity.value) ); + await this.sleep( Number( activity.value ) ); break; case ActivityTypes.Message: if ( @@ -199,7 +199,6 @@ export class ConsoleAdapter extends CloudAdapter { createInterface ( options: any ) { return readline.createInterface( options ); } - /** * Logs text to the console. diff --git a/samples/compat/console-echo/nodejs/src/index.ts b/samples/compat/console-echo/nodejs/src/index.ts index 49219405..ca70e46a 100644 --- a/samples/compat/console-echo/nodejs/src/index.ts +++ b/samples/compat/console-echo/nodejs/src/index.ts @@ -11,7 +11,7 @@ const myBot = new DialogAgent(); // A call to adapter.listen tells the adapter to start listening for incoming messages and events, known as "activities." // Activities are received as TurnContext objects by the handler function. adapter.listen( async ( context ) => { - myBot.onTurn( context ); + await myBot.onTurn( context ); } ); // Emit a startup message with some instructions. From c070e07a92d763ff100979ae66613a92c1b40dd8 Mon Sep 17 00:00:00 2001 From: Steven Kanberg Date: Fri, 8 Aug 2025 15:28:07 -0700 Subject: [PATCH 3/6] Removed to re-align with new samples folder structure --- samples/compat/console-echo/nodejs/README.md | 47 - .../console-echo/nodejs/package-lock.json | 893 ------------------ .../compat/console-echo/nodejs/package.json | 26 - .../console-echo/nodejs/src/consoleAdapter.ts | 228 ----- .../console-echo/nodejs/src/dialogAgent.ts | 22 - .../compat/console-echo/nodejs/src/index.ts | 19 - .../compat/console-echo/nodejs/tsconfig.json | 20 - 7 files changed, 1255 deletions(-) delete mode 100644 samples/compat/console-echo/nodejs/README.md delete mode 100644 samples/compat/console-echo/nodejs/package-lock.json delete mode 100644 samples/compat/console-echo/nodejs/package.json delete mode 100644 samples/compat/console-echo/nodejs/src/consoleAdapter.ts delete mode 100644 samples/compat/console-echo/nodejs/src/dialogAgent.ts delete mode 100644 samples/compat/console-echo/nodejs/src/index.ts delete mode 100644 samples/compat/console-echo/nodejs/tsconfig.json diff --git a/samples/compat/console-echo/nodejs/README.md b/samples/compat/console-echo/nodejs/README.md deleted file mode 100644 index 21c27120..00000000 --- a/samples/compat/console-echo/nodejs/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Console-echo - -This agent has been created with Agents SDK to demonstrate how to implement a simple conversational flow from the console window. - -## Prerequisites - -- [Node.js](https://nodejs.org) version 20 or higher - - ```bash - # determine node version - node --version - ``` - -## Running this sample - -1. Open this folder from your IDE or Terminal of preference -1. Install dependencies - - ```bash - npm install - ``` - -- Start the agent - - ```bash - npm start - ``` - -## Testing the agent - -After running `npm start`, the agent presents a prompt directly in the console window. - -Send messages to the agent by typing them into the console. The agent will echo your message back to you. - -## Adapters - -Adapters such as the `ConsoleAdapter` provide an abstraction for your agent to work with a variety of environments and messaging platforms. - -The adapter is responsible for directing incoming and outgoing communication, authentication, and so on. Adapters for different platforms and messaging technologies differ internally, but achieve the same goal - connecting agents to a stream of messages and events from users. -When your agent receives an activity, the adapter wraps up everything about that activity, creates a context object, passes it to your agent's application logic, and sends responses generated by your agent back to the user's channel. - -In most situations, we don't work with the adapter directly, but it's good to know it's there and what it does. In this example, we're using the -`ConsoleAdapter`, which provides a very simple way to exchange messages - they're sent and received via the console window. Using the ConsoleAdapter is a great way of getting started quickly with Agents. It also allows you to build and test agents that operate on your local machine without any external API calls or client applications. - -## Further reading - -To learn more about building Bots and Agents, see our [Microsoft 365 Agents SDK](https://github.com/microsoft/agents) repo. diff --git a/samples/compat/console-echo/nodejs/package-lock.json b/samples/compat/console-echo/nodejs/package-lock.json deleted file mode 100644 index 8fb0cfed..00000000 --- a/samples/compat/console-echo/nodejs/package-lock.json +++ /dev/null @@ -1,893 +0,0 @@ -{ - "name": "console-echo-agent", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "console-echo-agent", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@microsoft/agents-activity": "^1.0.0", - "@microsoft/agents-hosting": "^1.0.0" - }, - "devDependencies": { - "@types/node": "^22.13.4", - "esbuild": "^0.25.0", - "typescript": "^5.7.2" - } - }, - "node_modules/@azure/abort-controller": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", - "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@azure/core-auth": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.0.tgz", - "integrity": "sha512-88Djs5vBvGbHQHf5ZZcaoNHo6Y8BKZkt3cw2iuJIQzLEgH4Ox6Tm4hjFhbqOxyYsgIG/eJbFEHpxRIfEEWv5Ow==", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-util": "^1.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@azure/core-util": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.0.tgz", - "integrity": "sha512-o0psW8QWQ58fq3i24Q1K2XfS/jYTxr7O1HRcyUE9bV9NttLU+kYOH82Ixj8DGlMTOWgxm1Sss2QAfKK5UkSPxw==", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@typespec/ts-http-runtime": "^0.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@azure/msal-common": { - "version": "15.9.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.9.0.tgz", - "integrity": "sha512-lbz/D+C9ixUG3hiZzBLjU79a0+5ZXCorjel3mwXluisKNH0/rOS/ajm8yi4yI9RP5Uc70CAcs9Ipd0051Oh/kA==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@azure/msal-node": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.6.4.tgz", - "integrity": "sha512-jMeut9UQugcmq7aPWWlJKhJIse4DQ594zc/JaP6BIxg55XaX3aM/jcPuIQ4ryHnI4QSf03wUspy/uqAvjWKbOg==", - "license": "MIT", - "dependencies": { - "@azure/msal-common": "15.9.0", - "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/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@microsoft/agents-activity": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@microsoft/agents-activity/-/agents-activity-1.0.0.tgz", - "integrity": "sha512-AQm5NWQ5wWcH0dfvWqTdpAjLX6Fckk2d8mXkG1O8KZCFM67kG0os9G2ONurBZjGFITaIryNfNl6quxnixU6SAQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.7", - "uuid": "^11.1.0", - "zod": "3.25.75" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@microsoft/agents-hosting": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@microsoft/agents-hosting/-/agents-hosting-1.0.0.tgz", - "integrity": "sha512-7vL9H/jpy8ujJOk7KKSrRC4HKiA0m+GoWoTT9PRHNwmDfIPGU7yAaDLON7NrBOLYZwTDrKg6isMrd6OYigqeSg==", - "license": "MIT", - "dependencies": { - "@azure/core-auth": "^1.10.0", - "@azure/msal-node": "^3.6.0", - "@microsoft/agents-activity": "1.0.0", - "axios": "^1.10.0", - "jsonwebtoken": "^9.0.2", - "jwks-rsa": "^3.2.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "license": "MIT" - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", - "license": "MIT", - "dependencies": { - "@types/ms": "*", - "@types/node": "*" - } - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.17.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", - "integrity": "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@typespec/ts-http-runtime": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.0.tgz", - "integrity": "sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==", - "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/agent-base": { - "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" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", - "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.8", - "@esbuild/android-arm": "0.25.8", - "@esbuild/android-arm64": "0.25.8", - "@esbuild/android-x64": "0.25.8", - "@esbuild/darwin-arm64": "0.25.8", - "@esbuild/darwin-x64": "0.25.8", - "@esbuild/freebsd-arm64": "0.25.8", - "@esbuild/freebsd-x64": "0.25.8", - "@esbuild/linux-arm": "0.25.8", - "@esbuild/linux-arm64": "0.25.8", - "@esbuild/linux-ia32": "0.25.8", - "@esbuild/linux-loong64": "0.25.8", - "@esbuild/linux-mips64el": "0.25.8", - "@esbuild/linux-ppc64": "0.25.8", - "@esbuild/linux-riscv64": "0.25.8", - "@esbuild/linux-s390x": "0.25.8", - "@esbuild/linux-x64": "0.25.8", - "@esbuild/netbsd-arm64": "0.25.8", - "@esbuild/netbsd-x64": "0.25.8", - "@esbuild/openbsd-arm64": "0.25.8", - "@esbuild/openbsd-x64": "0.25.8", - "@esbuild/openharmony-arm64": "0.25.8", - "@esbuild/sunos-x64": "0.25.8", - "@esbuild/win32-arm64": "0.25.8", - "@esbuild/win32-ia32": "0.25.8", - "@esbuild/win32-x64": "0.25.8" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/form-data/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "license": "MIT", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jwks-rsa": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", - "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", - "license": "MIT", - "dependencies": { - "@types/express": "^4.17.20", - "@types/jsonwebtoken": "^9.0.4", - "debug": "^4.3.4", - "jose": "^4.15.4", - "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "license": "MIT" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", - "license": "MIT" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", - "license": "MIT" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", - "license": "MIT" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "license": "MIT" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "license": "MIT" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-memoizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", - "license": "MIT", - "dependencies": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "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/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/zod": { - "version": "3.25.75", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", - "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/samples/compat/console-echo/nodejs/package.json b/samples/compat/console-echo/nodejs/package.json deleted file mode 100644 index 9aa7396b..00000000 --- a/samples/compat/console-echo/nodejs/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "console-echo-agent", - "version": "1.0.0", - "private": true, - "description": "Agents console-echo", - "author": "Microsoft", - "license": "MIT", - "main": "./dist/index.js", - "scripts": { - "prebuild": "npm install", - "build": "tsc --build", - "prestart": "npm run build", - "start": "node ./dist/index.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "@microsoft/agents-activity": "^1.0.0", - "@microsoft/agents-hosting": "^1.0.0" - }, - "devDependencies": { - "@types/node": "^22.13.4", - "esbuild": "^0.25.0", - "typescript": "^5.7.2" - }, - "keywords": [] -} diff --git a/samples/compat/console-echo/nodejs/src/consoleAdapter.ts b/samples/compat/console-echo/nodejs/src/consoleAdapter.ts deleted file mode 100644 index b49a9f5a..00000000 --- a/samples/compat/console-echo/nodejs/src/consoleAdapter.ts +++ /dev/null @@ -1,228 +0,0 @@ -/** - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - */ - -import { BaseAdapter, CloudAdapter, ResourceResponse, TurnContext } from '@microsoft/agents-hosting'; -import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity'; -import * as readline from 'readline'; - -/** - * Lets a user communicate with a bot from a console window. - * - * @remarks - * The following example shows the typical adapter setup: - * - * ```typescript - * import { ConsoleAdapter } from './consoleAdapter'; - * - * const adapter = new ConsoleAdapter(); - * const closeFn = adapter.listen(async (context) => { - * await context.sendActivity(`Hello World`); - * }); - * ``` - * - * This adapter is intended for local development and testing scenarios. - * It implements the CloudAdapter interface for compatibility with the Agents SDK. - */ -export class ConsoleAdapter extends CloudAdapter { - nextId: number; - reference: ConversationReference; - /** - * Creates a new ConsoleAdapter instance. - * @param [reference] Reference used to customize the address information of activities sent from the adapter. - */ - constructor( reference?: ConversationReference ) { - super(); - this.nextId = 0; - this.reference = { - ...reference, - channelId: 'console', - user: { id: 'user', name: 'User1' }, - agent: { id: 'bot', name: 'Bot' }, - conversation: { id: 'convo1', name: '', isGroup: false }, - serviceUrl: '' - }; - } - - /** - * Begins listening to console input. Returns a function that can be called to stop listening. - * - * @remarks - * When input is received from the console: - * - A 'message' activity is created with the user's input text. - * - A revocable `TurnContext` is created for the activity. - * - The context is routed through any middleware registered with [use()](#use). - * - The bot's logic handler is executed. - * - The middleware promise chain is resolved. - * - The context object is revoked, and future calls to its members will throw a `TypeError`. - * - * ```typescript - * const closeFn = adapter.listen(async (context) => { - * const utterance = context.activity.text.toLowerCase(); - * if (utterance.includes('goodbye')) { - * await context.sendActivity(`Ok... Goodbye`); - * closeFn(); - * } else { - * await context.sendActivity(`Hello World`); - * } - * }); - * ``` - * @param logic Function called each time a message is input by the user. - * @returns Function to stop listening to console input. - */ - listen ( logic: { ( context: TurnContext ): Promise; ( revocableContext: TurnContext ): Promise; } ) { - const rl = this.createInterface( { - input: process.stdin, - output: process.stdout, - terminal: false - } ); - rl.on( 'line', async line => { - // Initialize activity - const activity = Activity.fromObject( { type: ActivityTypes.Message, text: line } ); - activity.applyConversationReference( - this.reference, - true - ); - - // Create context and run middleware pipe - const context = new TurnContext( this as unknown as BaseAdapter, activity ); - await this.runMiddleware( context, logic ).catch( err => { - this.printError( err.toString() ); - } ); - } ); - return () => { - rl.close(); - }; - } - - /** - * Allows the bot to proactively message the user. - * - * @remarks - * The processing steps for this method are similar to [listen()](#listen): - * - A `TurnContext` is created and routed through the adapter's middleware. - * - The provided logic handler is executed. - * The main difference is that since no activity was received from the user, a new activity is created and populated with the provided conversation reference. - * The created activity will have its address-related fields populated, and `context.activity.type` will be set to `message`. - * - * ```typescript - * function delayedNotify(context, message, delay) { - * const reference = TurnContext.getConversationReference(context.activity); - * setTimeout(() => { - * adapter.continueConversation(reference, async (ctx) => { - * await ctx.sendActivity(message); - * }); - * }, delay); - * } - * ``` - * @param reference A `ConversationReference` saved during a previous message from a user. This can be calculated for any incoming activity using `TurnContext.getConversationReference(context.activity)`. - * @param logic A function handler that will be called to perform the bot's logic after the adapter's middleware has been run. - */ - continueConversation ( reference: ConversationReference, logic: ( revocableContext: TurnContext ) => Promise ) { - // Create context and run middleware pipe - const activity = new Activity( ActivityTypes.Message ); - activity.applyConversationReference( - reference, - true - ); - const context = new TurnContext( this as unknown as BaseAdapter, activity ); - return this.runMiddleware( context, logic ).catch( err => { - this.printError( err.toString() ); - } ); - } - - /** - * Sends a set of activities to the console. - * - * @remarks - * This method is called by `TurnContext.sendActivities()` or `TurnContext.sendActivity()` to output activities to the console. - * It ensures outgoing activities have been properly addressed, and prints them appropriately. - * Middleware and addressing are handled by the Agents SDK before this method is called. - * @param _context Context for the current turn of conversation with the user. - * @param activities List of activities to send. - */ - async sendActivities ( _context: TurnContext, activities: Activity[] ) { - /** @type {ResourceResponse[]} */ - const responses = []; - for ( const activity of activities ) { - // Generate a unique id for each activity response - const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`); - responses.push( { id } ); - - switch ( activity.type ) { - case 'delay': - await this.sleep( Number( activity.value ) ); - break; - case ActivityTypes.Message: - if ( - activity.attachments && - activity.attachments.length > 0 - ) { - const append = - activity.attachments.length === 1 - ? '(1 attachment)' - : `(${ activity.attachments.length } attachments)`; - this.print( `${ activity.text } ${ append }` ); - } else { - this.print( activity.text || '' ); - } - break; - default: - this.print( `[${ activity.type }]` ); - break; - } - } - return responses; - } - - /** - * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.updateActivity()` - * will result an error being returned. - */ - updateActivity ( _context: TurnContext, _activity: Activity ) { - return Promise.reject( new Error( 'ConsoleAdapter.updateActivity(): not supported.' ) ); - } - - /** - * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.deleteActivity()` - * will result an error being returned. - */ - deleteActivity ( _context: TurnContext, _reference: Partial ) { - return Promise.reject( new Error( 'ConsoleAdapter.deleteActivity(): not supported.' ) ); - } - - /** - * Allows for mocking of the console interface in unit tests. - * @param options Console interface options. - */ - createInterface ( options: any ) { - return readline.createInterface( options ); - } - - /** - * Logs text to the console. - * @param line Text to print. - */ - print ( line: string ) { - console.log( line ); - } - - /** - * Logs an error to the console. - * @param line Error text to print. - */ - printError ( line: string ) { - console.error( line ); - } - - /** - * Puts the current thread to sleep for a specified duration. - * @param milliseconds Duration to sleep in milliseconds. - */ - sleep ( milliseconds: number ) { - return new Promise( resolve => { - setTimeout( resolve, milliseconds ); - } ); - } -} diff --git a/samples/compat/console-echo/nodejs/src/dialogAgent.ts b/samples/compat/console-echo/nodejs/src/dialogAgent.ts deleted file mode 100644 index 09f7d903..00000000 --- a/samples/compat/console-echo/nodejs/src/dialogAgent.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { TurnContext } from '@microsoft/agents-hosting'; - -export class DialogAgent { - async onTurn ( context: TurnContext ) { - // Check to see if this activity is an incoming message. - // (It could theoretically be another type of activity.) - if ( context.activity.type === 'message' && context.activity.text ) { - // Check to see if the user sent a simple "quit" message. - if ( context.activity.text.toLowerCase() === 'quit' ) { - // Send a reply. - context.sendActivity( '> Bye!' ); - process.exit(); - } else { - // Echo the message text back to the user. - return context.sendActivity( `> I heard you say "${ context.activity.text }"` ); - } - } - } -} diff --git a/samples/compat/console-echo/nodejs/src/index.ts b/samples/compat/console-echo/nodejs/src/index.ts deleted file mode 100644 index ca70e46a..00000000 --- a/samples/compat/console-echo/nodejs/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ConsoleAdapter } from './consoleAdapter'; -import { DialogAgent } from './dialogAgent'; - -// Create the bot adapter, which is responsible for sending and receiving messages. -// We are using the ConsoleAdapter, which enables a bot you can chat with from within your terminal window. -const adapter = new ConsoleAdapter(); - -// Create the bot's main handler. -const myBot = new DialogAgent(); - -// A call to adapter.listen tells the adapter to start listening for incoming messages and events, known as "activities." -// Activities are received as TurnContext objects by the handler function. -adapter.listen( async ( context ) => { - await myBot.onTurn( context ); -} ); - -// Emit a startup message with some instructions. -console.log( '> Console EchoBot is online. I will repeat any message you send me!' ); -console.log( '> Say "quit" to end.\n' ); \ No newline at end of file diff --git a/samples/compat/console-echo/nodejs/tsconfig.json b/samples/compat/console-echo/nodejs/tsconfig.json deleted file mode 100644 index 5fb9619c..00000000 --- a/samples/compat/console-echo/nodejs/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "incremental": true, - "lib": ["ES2021"], - "target": "es2019", - "module": "commonjs", - "declaration": true, - "sourceMap": true, - "composite": true, - "strict": true, - "moduleResolution": "node", - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "rootDir": "src", - "outDir": "dist", - "tsBuildInfoFile": "dist/.tsbuildinfo" - } -} From 9d41d0e956aefec2c0a6090362c07ebd7794074c Mon Sep 17 00:00:00 2001 From: Steven Kanberg Date: Fri, 8 Aug 2025 15:34:15 -0700 Subject: [PATCH 4/6] Adds the console echo agent sample --- samples/nodejs/console-echo/README.md | 47 + samples/nodejs/console-echo/package-lock.json | 893 ++++++++++++++++++ samples/nodejs/console-echo/package.json | 26 + .../nodejs/console-echo/src/consoleAdapter.ts | 228 +++++ .../nodejs/console-echo/src/dialogAgent.ts | 22 + samples/nodejs/console-echo/src/index.ts | 19 + samples/nodejs/console-echo/tsconfig.json | 20 + 7 files changed, 1255 insertions(+) create mode 100644 samples/nodejs/console-echo/README.md create mode 100644 samples/nodejs/console-echo/package-lock.json create mode 100644 samples/nodejs/console-echo/package.json create mode 100644 samples/nodejs/console-echo/src/consoleAdapter.ts create mode 100644 samples/nodejs/console-echo/src/dialogAgent.ts create mode 100644 samples/nodejs/console-echo/src/index.ts create mode 100644 samples/nodejs/console-echo/tsconfig.json diff --git a/samples/nodejs/console-echo/README.md b/samples/nodejs/console-echo/README.md new file mode 100644 index 00000000..21c27120 --- /dev/null +++ b/samples/nodejs/console-echo/README.md @@ -0,0 +1,47 @@ +# Console-echo + +This agent has been created with Agents SDK to demonstrate how to implement a simple conversational flow from the console window. + +## Prerequisites + +- [Node.js](https://nodejs.org) version 20 or higher + + ```bash + # determine node version + node --version + ``` + +## Running this sample + +1. Open this folder from your IDE or Terminal of preference +1. Install dependencies + + ```bash + npm install + ``` + +- Start the agent + + ```bash + npm start + ``` + +## Testing the agent + +After running `npm start`, the agent presents a prompt directly in the console window. + +Send messages to the agent by typing them into the console. The agent will echo your message back to you. + +## Adapters + +Adapters such as the `ConsoleAdapter` provide an abstraction for your agent to work with a variety of environments and messaging platforms. + +The adapter is responsible for directing incoming and outgoing communication, authentication, and so on. Adapters for different platforms and messaging technologies differ internally, but achieve the same goal - connecting agents to a stream of messages and events from users. +When your agent receives an activity, the adapter wraps up everything about that activity, creates a context object, passes it to your agent's application logic, and sends responses generated by your agent back to the user's channel. + +In most situations, we don't work with the adapter directly, but it's good to know it's there and what it does. In this example, we're using the +`ConsoleAdapter`, which provides a very simple way to exchange messages - they're sent and received via the console window. Using the ConsoleAdapter is a great way of getting started quickly with Agents. It also allows you to build and test agents that operate on your local machine without any external API calls or client applications. + +## Further reading + +To learn more about building Bots and Agents, see our [Microsoft 365 Agents SDK](https://github.com/microsoft/agents) repo. diff --git a/samples/nodejs/console-echo/package-lock.json b/samples/nodejs/console-echo/package-lock.json new file mode 100644 index 00000000..8fb0cfed --- /dev/null +++ b/samples/nodejs/console-echo/package-lock.json @@ -0,0 +1,893 @@ +{ + "name": "console-echo-agent", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "console-echo-agent", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@microsoft/agents-activity": "^1.0.0", + "@microsoft/agents-hosting": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^22.13.4", + "esbuild": "^0.25.0", + "typescript": "^5.7.2" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.0.tgz", + "integrity": "sha512-88Djs5vBvGbHQHf5ZZcaoNHo6Y8BKZkt3cw2iuJIQzLEgH4Ox6Tm4hjFhbqOxyYsgIG/eJbFEHpxRIfEEWv5Ow==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.0.tgz", + "integrity": "sha512-o0psW8QWQ58fq3i24Q1K2XfS/jYTxr7O1HRcyUE9bV9NttLU+kYOH82Ixj8DGlMTOWgxm1Sss2QAfKK5UkSPxw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.9.0.tgz", + "integrity": "sha512-lbz/D+C9ixUG3hiZzBLjU79a0+5ZXCorjel3mwXluisKNH0/rOS/ajm8yi4yI9RP5Uc70CAcs9Ipd0051Oh/kA==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.6.4.tgz", + "integrity": "sha512-jMeut9UQugcmq7aPWWlJKhJIse4DQ594zc/JaP6BIxg55XaX3aM/jcPuIQ4ryHnI4QSf03wUspy/uqAvjWKbOg==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.9.0", + "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/@esbuild/win32-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@microsoft/agents-activity": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/agents-activity/-/agents-activity-1.0.0.tgz", + "integrity": "sha512-AQm5NWQ5wWcH0dfvWqTdpAjLX6Fckk2d8mXkG1O8KZCFM67kG0os9G2ONurBZjGFITaIryNfNl6quxnixU6SAQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.7", + "uuid": "^11.1.0", + "zod": "3.25.75" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@microsoft/agents-hosting": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/agents-hosting/-/agents-hosting-1.0.0.tgz", + "integrity": "sha512-7vL9H/jpy8ujJOk7KKSrRC4HKiA0m+GoWoTT9PRHNwmDfIPGU7yAaDLON7NrBOLYZwTDrKg6isMrd6OYigqeSg==", + "license": "MIT", + "dependencies": { + "@azure/core-auth": "^1.10.0", + "@azure/msal-node": "^3.6.0", + "@microsoft/agents-activity": "1.0.0", + "axios": "^1.10.0", + "jsonwebtoken": "^9.0.2", + "jwks-rsa": "^3.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.17.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", + "integrity": "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.0.tgz", + "integrity": "sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==", + "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/agent-base": { + "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" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", + "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.20", + "@types/jsonwebtoken": "^9.0.4", + "debug": "^4.3.4", + "jose": "^4.15.4", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "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/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/zod": { + "version": "3.25.75", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", + "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/samples/nodejs/console-echo/package.json b/samples/nodejs/console-echo/package.json new file mode 100644 index 00000000..9aa7396b --- /dev/null +++ b/samples/nodejs/console-echo/package.json @@ -0,0 +1,26 @@ +{ + "name": "console-echo-agent", + "version": "1.0.0", + "private": true, + "description": "Agents console-echo", + "author": "Microsoft", + "license": "MIT", + "main": "./dist/index.js", + "scripts": { + "prebuild": "npm install", + "build": "tsc --build", + "prestart": "npm run build", + "start": "node ./dist/index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "@microsoft/agents-activity": "^1.0.0", + "@microsoft/agents-hosting": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^22.13.4", + "esbuild": "^0.25.0", + "typescript": "^5.7.2" + }, + "keywords": [] +} diff --git a/samples/nodejs/console-echo/src/consoleAdapter.ts b/samples/nodejs/console-echo/src/consoleAdapter.ts new file mode 100644 index 00000000..b49a9f5a --- /dev/null +++ b/samples/nodejs/console-echo/src/consoleAdapter.ts @@ -0,0 +1,228 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { BaseAdapter, CloudAdapter, ResourceResponse, TurnContext } from '@microsoft/agents-hosting'; +import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity'; +import * as readline from 'readline'; + +/** + * Lets a user communicate with a bot from a console window. + * + * @remarks + * The following example shows the typical adapter setup: + * + * ```typescript + * import { ConsoleAdapter } from './consoleAdapter'; + * + * const adapter = new ConsoleAdapter(); + * const closeFn = adapter.listen(async (context) => { + * await context.sendActivity(`Hello World`); + * }); + * ``` + * + * This adapter is intended for local development and testing scenarios. + * It implements the CloudAdapter interface for compatibility with the Agents SDK. + */ +export class ConsoleAdapter extends CloudAdapter { + nextId: number; + reference: ConversationReference; + /** + * Creates a new ConsoleAdapter instance. + * @param [reference] Reference used to customize the address information of activities sent from the adapter. + */ + constructor( reference?: ConversationReference ) { + super(); + this.nextId = 0; + this.reference = { + ...reference, + channelId: 'console', + user: { id: 'user', name: 'User1' }, + agent: { id: 'bot', name: 'Bot' }, + conversation: { id: 'convo1', name: '', isGroup: false }, + serviceUrl: '' + }; + } + + /** + * Begins listening to console input. Returns a function that can be called to stop listening. + * + * @remarks + * When input is received from the console: + * - A 'message' activity is created with the user's input text. + * - A revocable `TurnContext` is created for the activity. + * - The context is routed through any middleware registered with [use()](#use). + * - The bot's logic handler is executed. + * - The middleware promise chain is resolved. + * - The context object is revoked, and future calls to its members will throw a `TypeError`. + * + * ```typescript + * const closeFn = adapter.listen(async (context) => { + * const utterance = context.activity.text.toLowerCase(); + * if (utterance.includes('goodbye')) { + * await context.sendActivity(`Ok... Goodbye`); + * closeFn(); + * } else { + * await context.sendActivity(`Hello World`); + * } + * }); + * ``` + * @param logic Function called each time a message is input by the user. + * @returns Function to stop listening to console input. + */ + listen ( logic: { ( context: TurnContext ): Promise; ( revocableContext: TurnContext ): Promise; } ) { + const rl = this.createInterface( { + input: process.stdin, + output: process.stdout, + terminal: false + } ); + rl.on( 'line', async line => { + // Initialize activity + const activity = Activity.fromObject( { type: ActivityTypes.Message, text: line } ); + activity.applyConversationReference( + this.reference, + true + ); + + // Create context and run middleware pipe + const context = new TurnContext( this as unknown as BaseAdapter, activity ); + await this.runMiddleware( context, logic ).catch( err => { + this.printError( err.toString() ); + } ); + } ); + return () => { + rl.close(); + }; + } + + /** + * Allows the bot to proactively message the user. + * + * @remarks + * The processing steps for this method are similar to [listen()](#listen): + * - A `TurnContext` is created and routed through the adapter's middleware. + * - The provided logic handler is executed. + * The main difference is that since no activity was received from the user, a new activity is created and populated with the provided conversation reference. + * The created activity will have its address-related fields populated, and `context.activity.type` will be set to `message`. + * + * ```typescript + * function delayedNotify(context, message, delay) { + * const reference = TurnContext.getConversationReference(context.activity); + * setTimeout(() => { + * adapter.continueConversation(reference, async (ctx) => { + * await ctx.sendActivity(message); + * }); + * }, delay); + * } + * ``` + * @param reference A `ConversationReference` saved during a previous message from a user. This can be calculated for any incoming activity using `TurnContext.getConversationReference(context.activity)`. + * @param logic A function handler that will be called to perform the bot's logic after the adapter's middleware has been run. + */ + continueConversation ( reference: ConversationReference, logic: ( revocableContext: TurnContext ) => Promise ) { + // Create context and run middleware pipe + const activity = new Activity( ActivityTypes.Message ); + activity.applyConversationReference( + reference, + true + ); + const context = new TurnContext( this as unknown as BaseAdapter, activity ); + return this.runMiddleware( context, logic ).catch( err => { + this.printError( err.toString() ); + } ); + } + + /** + * Sends a set of activities to the console. + * + * @remarks + * This method is called by `TurnContext.sendActivities()` or `TurnContext.sendActivity()` to output activities to the console. + * It ensures outgoing activities have been properly addressed, and prints them appropriately. + * Middleware and addressing are handled by the Agents SDK before this method is called. + * @param _context Context for the current turn of conversation with the user. + * @param activities List of activities to send. + */ + async sendActivities ( _context: TurnContext, activities: Activity[] ) { + /** @type {ResourceResponse[]} */ + const responses = []; + for ( const activity of activities ) { + // Generate a unique id for each activity response + const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`); + responses.push( { id } ); + + switch ( activity.type ) { + case 'delay': + await this.sleep( Number( activity.value ) ); + break; + case ActivityTypes.Message: + if ( + activity.attachments && + activity.attachments.length > 0 + ) { + const append = + activity.attachments.length === 1 + ? '(1 attachment)' + : `(${ activity.attachments.length } attachments)`; + this.print( `${ activity.text } ${ append }` ); + } else { + this.print( activity.text || '' ); + } + break; + default: + this.print( `[${ activity.type }]` ); + break; + } + } + return responses; + } + + /** + * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.updateActivity()` + * will result an error being returned. + */ + updateActivity ( _context: TurnContext, _activity: Activity ) { + return Promise.reject( new Error( 'ConsoleAdapter.updateActivity(): not supported.' ) ); + } + + /** + * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.deleteActivity()` + * will result an error being returned. + */ + deleteActivity ( _context: TurnContext, _reference: Partial ) { + return Promise.reject( new Error( 'ConsoleAdapter.deleteActivity(): not supported.' ) ); + } + + /** + * Allows for mocking of the console interface in unit tests. + * @param options Console interface options. + */ + createInterface ( options: any ) { + return readline.createInterface( options ); + } + + /** + * Logs text to the console. + * @param line Text to print. + */ + print ( line: string ) { + console.log( line ); + } + + /** + * Logs an error to the console. + * @param line Error text to print. + */ + printError ( line: string ) { + console.error( line ); + } + + /** + * Puts the current thread to sleep for a specified duration. + * @param milliseconds Duration to sleep in milliseconds. + */ + sleep ( milliseconds: number ) { + return new Promise( resolve => { + setTimeout( resolve, milliseconds ); + } ); + } +} diff --git a/samples/nodejs/console-echo/src/dialogAgent.ts b/samples/nodejs/console-echo/src/dialogAgent.ts new file mode 100644 index 00000000..09f7d903 --- /dev/null +++ b/samples/nodejs/console-echo/src/dialogAgent.ts @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { TurnContext } from '@microsoft/agents-hosting'; + +export class DialogAgent { + async onTurn ( context: TurnContext ) { + // Check to see if this activity is an incoming message. + // (It could theoretically be another type of activity.) + if ( context.activity.type === 'message' && context.activity.text ) { + // Check to see if the user sent a simple "quit" message. + if ( context.activity.text.toLowerCase() === 'quit' ) { + // Send a reply. + context.sendActivity( '> Bye!' ); + process.exit(); + } else { + // Echo the message text back to the user. + return context.sendActivity( `> I heard you say "${ context.activity.text }"` ); + } + } + } +} diff --git a/samples/nodejs/console-echo/src/index.ts b/samples/nodejs/console-echo/src/index.ts new file mode 100644 index 00000000..ca70e46a --- /dev/null +++ b/samples/nodejs/console-echo/src/index.ts @@ -0,0 +1,19 @@ +import { ConsoleAdapter } from './consoleAdapter'; +import { DialogAgent } from './dialogAgent'; + +// Create the bot adapter, which is responsible for sending and receiving messages. +// We are using the ConsoleAdapter, which enables a bot you can chat with from within your terminal window. +const adapter = new ConsoleAdapter(); + +// Create the bot's main handler. +const myBot = new DialogAgent(); + +// A call to adapter.listen tells the adapter to start listening for incoming messages and events, known as "activities." +// Activities are received as TurnContext objects by the handler function. +adapter.listen( async ( context ) => { + await myBot.onTurn( context ); +} ); + +// Emit a startup message with some instructions. +console.log( '> Console EchoBot is online. I will repeat any message you send me!' ); +console.log( '> Say "quit" to end.\n' ); \ No newline at end of file diff --git a/samples/nodejs/console-echo/tsconfig.json b/samples/nodejs/console-echo/tsconfig.json new file mode 100644 index 00000000..5fb9619c --- /dev/null +++ b/samples/nodejs/console-echo/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "incremental": true, + "lib": ["ES2021"], + "target": "es2019", + "module": "commonjs", + "declaration": true, + "sourceMap": true, + "composite": true, + "strict": true, + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "rootDir": "src", + "outDir": "dist", + "tsBuildInfoFile": "dist/.tsbuildinfo" + } +} From b5cbb86007b02f1e8f60384ca8b6629014697824 Mon Sep 17 00:00:00 2001 From: Rido Date: Mon, 18 Aug 2025 09:27:28 +0000 Subject: [PATCH 5/6] simplify console adapter --- samples/nodejs/console-echo/package-lock.json | 1 - samples/nodejs/console-echo/package.json | 1 - .../nodejs/console-echo/src/consoleAdapter.ts | 129 ++++++------------ .../nodejs/console-echo/src/dialogAgent.ts | 32 ++--- samples/nodejs/console-echo/src/index.ts | 22 ++- 5 files changed, 70 insertions(+), 115 deletions(-) diff --git a/samples/nodejs/console-echo/package-lock.json b/samples/nodejs/console-echo/package-lock.json index 8fb0cfed..46a55250 100644 --- a/samples/nodejs/console-echo/package-lock.json +++ b/samples/nodejs/console-echo/package-lock.json @@ -9,7 +9,6 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@microsoft/agents-activity": "^1.0.0", "@microsoft/agents-hosting": "^1.0.0" }, "devDependencies": { diff --git a/samples/nodejs/console-echo/package.json b/samples/nodejs/console-echo/package.json index 9aa7396b..a9735a7e 100644 --- a/samples/nodejs/console-echo/package.json +++ b/samples/nodejs/console-echo/package.json @@ -14,7 +14,6 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@microsoft/agents-activity": "^1.0.0", "@microsoft/agents-hosting": "^1.0.0" }, "devDependencies": { diff --git a/samples/nodejs/console-echo/src/consoleAdapter.ts b/samples/nodejs/console-echo/src/consoleAdapter.ts index b49a9f5a..b683a34e 100644 --- a/samples/nodejs/console-echo/src/consoleAdapter.ts +++ b/samples/nodejs/console-echo/src/consoleAdapter.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. */ -import { BaseAdapter, CloudAdapter, ResourceResponse, TurnContext } from '@microsoft/agents-hosting'; -import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity'; -import * as readline from 'readline'; +import { BaseAdapter, CloudAdapter, TurnContext } from '@microsoft/agents-hosting' +import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity' +import * as readline from 'readline' /** * Lets a user communicate with a bot from a console window. @@ -26,15 +26,15 @@ import * as readline from 'readline'; * It implements the CloudAdapter interface for compatibility with the Agents SDK. */ export class ConsoleAdapter extends CloudAdapter { - nextId: number; - reference: ConversationReference; + nextId: number + reference: ConversationReference /** * Creates a new ConsoleAdapter instance. * @param [reference] Reference used to customize the address information of activities sent from the adapter. */ - constructor( reference?: ConversationReference ) { - super(); - this.nextId = 0; + constructor (reference?: ConversationReference) { + super() + this.nextId = 0 this.reference = { ...reference, channelId: 'console', @@ -42,7 +42,7 @@ export class ConsoleAdapter extends CloudAdapter { agent: { id: 'bot', name: 'Bot' }, conversation: { id: 'convo1', name: '', isGroup: false }, serviceUrl: '' - }; + } } /** @@ -71,29 +71,29 @@ export class ConsoleAdapter extends CloudAdapter { * @param logic Function called each time a message is input by the user. * @returns Function to stop listening to console input. */ - listen ( logic: { ( context: TurnContext ): Promise; ( revocableContext: TurnContext ): Promise; } ) { - const rl = this.createInterface( { + listen (logic: { (context: TurnContext): Promise; (revocableContext: TurnContext): Promise; }) { + const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false - } ); - rl.on( 'line', async line => { + }) + rl.on('line', async line => { // Initialize activity - const activity = Activity.fromObject( { type: ActivityTypes.Message, text: line } ); + const activity = Activity.fromObject({ type: ActivityTypes.Message, text: line }) activity.applyConversationReference( this.reference, true - ); + ) // Create context and run middleware pipe - const context = new TurnContext( this as unknown as BaseAdapter, activity ); - await this.runMiddleware( context, logic ).catch( err => { - this.printError( err.toString() ); - } ); - } ); + const context = new TurnContext(this as unknown as BaseAdapter, activity) + await this.runMiddleware(context, logic).catch(err => { + this.printError(err.toString()) + }) + }) return () => { - rl.close(); - }; + rl.close() + } } /** @@ -119,17 +119,17 @@ export class ConsoleAdapter extends CloudAdapter { * @param reference A `ConversationReference` saved during a previous message from a user. This can be calculated for any incoming activity using `TurnContext.getConversationReference(context.activity)`. * @param logic A function handler that will be called to perform the bot's logic after the adapter's middleware has been run. */ - continueConversation ( reference: ConversationReference, logic: ( revocableContext: TurnContext ) => Promise ) { + continueConversation (reference: ConversationReference, logic: (revocableContext: TurnContext) => Promise) { // Create context and run middleware pipe - const activity = new Activity( ActivityTypes.Message ); + const activity = new Activity(ActivityTypes.Message) activity.applyConversationReference( reference, true - ); - const context = new TurnContext( this as unknown as BaseAdapter, activity ); - return this.runMiddleware( context, logic ).catch( err => { - this.printError( err.toString() ); - } ); + ) + const context = new TurnContext(this as unknown as BaseAdapter, activity) + return this.runMiddleware(context, logic).catch(err => { + this.printError(err.toString()) + }) } /** @@ -142,87 +142,46 @@ export class ConsoleAdapter extends CloudAdapter { * @param _context Context for the current turn of conversation with the user. * @param activities List of activities to send. */ - async sendActivities ( _context: TurnContext, activities: Activity[] ) { - /** @type {ResourceResponse[]} */ - const responses = []; - for ( const activity of activities ) { + async sendActivities (_context: TurnContext, activities: Activity[]) { + const responses = [] + for (const activity of activities) { // Generate a unique id for each activity response - const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`); - responses.push( { id } ); - - switch ( activity.type ) { - case 'delay': - await this.sleep( Number( activity.value ) ); - break; - case ActivityTypes.Message: - if ( - activity.attachments && - activity.attachments.length > 0 - ) { - const append = - activity.attachments.length === 1 - ? '(1 attachment)' - : `(${ activity.attachments.length } attachments)`; - this.print( `${ activity.text } ${ append }` ); - } else { - this.print( activity.text || '' ); - } - break; - default: - this.print( `[${ activity.type }]` ); - break; - } + const id = (activity.id || `console-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`) + responses.push({ id }) + this.print(activity.text || '') } - return responses; + return responses } /** * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.updateActivity()` * will result an error being returned. */ - updateActivity ( _context: TurnContext, _activity: Activity ) { - return Promise.reject( new Error( 'ConsoleAdapter.updateActivity(): not supported.' ) ); + updateActivity (_context: TurnContext, _activity: Activity) { + return Promise.reject(new Error('ConsoleAdapter.updateActivity(): not supported.')) } /** * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.deleteActivity()` * will result an error being returned. */ - deleteActivity ( _context: TurnContext, _reference: Partial ) { - return Promise.reject( new Error( 'ConsoleAdapter.deleteActivity(): not supported.' ) ); - } - - /** - * Allows for mocking of the console interface in unit tests. - * @param options Console interface options. - */ - createInterface ( options: any ) { - return readline.createInterface( options ); + deleteActivity (_context: TurnContext, _reference: Partial) { + return Promise.reject(new Error('ConsoleAdapter.deleteActivity(): not supported.')) } /** * Logs text to the console. * @param line Text to print. */ - print ( line: string ) { - console.log( line ); + print (line: string) { + console.log(line) } /** * Logs an error to the console. * @param line Error text to print. */ - printError ( line: string ) { - console.error( line ); - } - - /** - * Puts the current thread to sleep for a specified duration. - * @param milliseconds Duration to sleep in milliseconds. - */ - sleep ( milliseconds: number ) { - return new Promise( resolve => { - setTimeout( resolve, milliseconds ); - } ); + printError (line: string) { + console.error(line) } } diff --git a/samples/nodejs/console-echo/src/dialogAgent.ts b/samples/nodejs/console-echo/src/dialogAgent.ts index 09f7d903..583f2ee0 100644 --- a/samples/nodejs/console-echo/src/dialogAgent.ts +++ b/samples/nodejs/console-echo/src/dialogAgent.ts @@ -1,22 +1,22 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { TurnContext } from '@microsoft/agents-hosting'; +import { ActivityTypes } from '@microsoft/agents-activity' +import { TurnContext, AgentApplication, TurnState } from '@microsoft/agents-hosting' -export class DialogAgent { - async onTurn ( context: TurnContext ) { - // Check to see if this activity is an incoming message. - // (It could theoretically be another type of activity.) - if ( context.activity.type === 'message' && context.activity.text ) { - // Check to see if the user sent a simple "quit" message. - if ( context.activity.text.toLowerCase() === 'quit' ) { - // Send a reply. - context.sendActivity( '> Bye!' ); - process.exit(); - } else { - // Echo the message text back to the user. - return context.sendActivity( `> I heard you say "${ context.activity.text }"` ); - } - } +export class DialogAgent extends AgentApplication { + constructor () { + super() + this.onMessage('quit', this._quit) + this.onActivity(ActivityTypes.Message, this._echo) + } + + private async _quit (context: TurnContext, state: TurnState): Promise { + await context.sendActivity('> Bye!') + process.exit() + } + + private async _echo (context: TurnContext, state: TurnState): Promise { + await context.sendActivity(`> I heard you say "${context.activity.text}"`) } } diff --git a/samples/nodejs/console-echo/src/index.ts b/samples/nodejs/console-echo/src/index.ts index ca70e46a..ce28e034 100644 --- a/samples/nodejs/console-echo/src/index.ts +++ b/samples/nodejs/console-echo/src/index.ts @@ -1,19 +1,17 @@ -import { ConsoleAdapter } from './consoleAdapter'; -import { DialogAgent } from './dialogAgent'; +import { ConsoleAdapter } from './consoleAdapter' +import { DialogAgent } from './dialogAgent' -// Create the bot adapter, which is responsible for sending and receiving messages. -// We are using the ConsoleAdapter, which enables a bot you can chat with from within your terminal window. -const adapter = new ConsoleAdapter(); +// Create the adapter, which is responsible for sending and receiving messages. +// We are using the ConsoleAdapter, which enables an agent you can chat with from within your terminal window. +const adapter = new ConsoleAdapter() -// Create the bot's main handler. -const myBot = new DialogAgent(); +// Create the agent's main handler. +const myAgent = new DialogAgent() // A call to adapter.listen tells the adapter to start listening for incoming messages and events, known as "activities." // Activities are received as TurnContext objects by the handler function. -adapter.listen( async ( context ) => { - await myBot.onTurn( context ); -} ); +adapter.listen(context => myAgent.run(context)) // Emit a startup message with some instructions. -console.log( '> Console EchoBot is online. I will repeat any message you send me!' ); -console.log( '> Say "quit" to end.\n' ); \ No newline at end of file +console.log('> Console EchoBot is online. I will repeat any message you send me!') +console.log('> Say "quit" to end.\n') From 904bdcdf124a46cfc692044ea1abdab7bd197e02 Mon Sep 17 00:00:00 2001 From: Steven Kanberg Date: Mon, 18 Aug 2025 15:16:22 -0700 Subject: [PATCH 6/6] Refactor README and ConsoleAdapter comments for clarity and conciseness --- samples/nodejs/console-echo/README.md | 2 +- .../nodejs/console-echo/src/consoleAdapter.ts | 102 +----------------- 2 files changed, 4 insertions(+), 100 deletions(-) diff --git a/samples/nodejs/console-echo/README.md b/samples/nodejs/console-echo/README.md index 21c27120..4c3f1cde 100644 --- a/samples/nodejs/console-echo/README.md +++ b/samples/nodejs/console-echo/README.md @@ -44,4 +44,4 @@ In most situations, we don't work with the adapter directly, but it's good to kn ## Further reading -To learn more about building Bots and Agents, see our [Microsoft 365 Agents SDK](https://github.com/microsoft/agents) repo. +To learn more about building agents, see our [Microsoft 365 Agents SDK](https://github.com/microsoft/agents) repo. diff --git a/samples/nodejs/console-echo/src/consoleAdapter.ts b/samples/nodejs/console-echo/src/consoleAdapter.ts index b683a34e..c25b2b88 100644 --- a/samples/nodejs/console-echo/src/consoleAdapter.ts +++ b/samples/nodejs/console-echo/src/consoleAdapter.ts @@ -7,31 +7,10 @@ import { BaseAdapter, CloudAdapter, TurnContext } from '@microsoft/agents-hostin import { ActivityTypes, Activity, ConversationReference } from '@microsoft/agents-activity' import * as readline from 'readline' -/** - * Lets a user communicate with a bot from a console window. - * - * @remarks - * The following example shows the typical adapter setup: - * - * ```typescript - * import { ConsoleAdapter } from './consoleAdapter'; - * - * const adapter = new ConsoleAdapter(); - * const closeFn = adapter.listen(async (context) => { - * await context.sendActivity(`Hello World`); - * }); - * ``` - * - * This adapter is intended for local development and testing scenarios. - * It implements the CloudAdapter interface for compatibility with the Agents SDK. - */ + // Implements the CloudAdapter interface. export class ConsoleAdapter extends CloudAdapter { nextId: number reference: ConversationReference - /** - * Creates a new ConsoleAdapter instance. - * @param [reference] Reference used to customize the address information of activities sent from the adapter. - */ constructor (reference?: ConversationReference) { super() this.nextId = 0 @@ -45,38 +24,13 @@ export class ConsoleAdapter extends CloudAdapter { } } - /** - * Begins listening to console input. Returns a function that can be called to stop listening. - * - * @remarks - * When input is received from the console: - * - A 'message' activity is created with the user's input text. - * - A revocable `TurnContext` is created for the activity. - * - The context is routed through any middleware registered with [use()](#use). - * - The bot's logic handler is executed. - * - The middleware promise chain is resolved. - * - The context object is revoked, and future calls to its members will throw a `TypeError`. - * - * ```typescript - * const closeFn = adapter.listen(async (context) => { - * const utterance = context.activity.text.toLowerCase(); - * if (utterance.includes('goodbye')) { - * await context.sendActivity(`Ok... Goodbye`); - * closeFn(); - * } else { - * await context.sendActivity(`Hello World`); - * } - * }); - * ``` - * @param logic Function called each time a message is input by the user. - * @returns Function to stop listening to console input. - */ + // Listens for incoming messages from the console. listen (logic: { (context: TurnContext): Promise; (revocableContext: TurnContext): Promise; }) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false - }) + } ) rl.on('line', async line => { // Initialize activity const activity = Activity.fromObject({ type: ActivityTypes.Message, text: line }) @@ -96,31 +50,7 @@ export class ConsoleAdapter extends CloudAdapter { } } - /** - * Allows the bot to proactively message the user. - * - * @remarks - * The processing steps for this method are similar to [listen()](#listen): - * - A `TurnContext` is created and routed through the adapter's middleware. - * - The provided logic handler is executed. - * The main difference is that since no activity was received from the user, a new activity is created and populated with the provided conversation reference. - * The created activity will have its address-related fields populated, and `context.activity.type` will be set to `message`. - * - * ```typescript - * function delayedNotify(context, message, delay) { - * const reference = TurnContext.getConversationReference(context.activity); - * setTimeout(() => { - * adapter.continueConversation(reference, async (ctx) => { - * await ctx.sendActivity(message); - * }); - * }, delay); - * } - * ``` - * @param reference A `ConversationReference` saved during a previous message from a user. This can be calculated for any incoming activity using `TurnContext.getConversationReference(context.activity)`. - * @param logic A function handler that will be called to perform the bot's logic after the adapter's middleware has been run. - */ continueConversation (reference: ConversationReference, logic: (revocableContext: TurnContext) => Promise) { - // Create context and run middleware pipe const activity = new Activity(ActivityTypes.Message) activity.applyConversationReference( reference, @@ -132,16 +62,6 @@ export class ConsoleAdapter extends CloudAdapter { }) } - /** - * Sends a set of activities to the console. - * - * @remarks - * This method is called by `TurnContext.sendActivities()` or `TurnContext.sendActivity()` to output activities to the console. - * It ensures outgoing activities have been properly addressed, and prints them appropriately. - * Middleware and addressing are handled by the Agents SDK before this method is called. - * @param _context Context for the current turn of conversation with the user. - * @param activities List of activities to send. - */ async sendActivities (_context: TurnContext, activities: Activity[]) { const responses = [] for (const activity of activities) { @@ -153,34 +73,18 @@ export class ConsoleAdapter extends CloudAdapter { return responses } - /** - * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.updateActivity()` - * will result an error being returned. - */ updateActivity (_context: TurnContext, _activity: Activity) { return Promise.reject(new Error('ConsoleAdapter.updateActivity(): not supported.')) } - /** - * Not supported for the ConsoleAdapter. Calling this method or `TurnContext.deleteActivity()` - * will result an error being returned. - */ deleteActivity (_context: TurnContext, _reference: Partial) { return Promise.reject(new Error('ConsoleAdapter.deleteActivity(): not supported.')) } - /** - * Logs text to the console. - * @param line Text to print. - */ print (line: string) { console.log(line) } - /** - * Logs an error to the console. - * @param line Error text to print. - */ printError (line: string) { console.error(line) }