diff --git a/Lab-02-building-travel-planner/README.md b/Lab-02-building-travel-planner/README.md index d8d529db..6777eb06 100644 --- a/Lab-02-building-travel-planner/README.md +++ b/Lab-02-building-travel-planner/README.md @@ -68,7 +68,18 @@ cd o2-business-apis/search-api bal run ``` -### 2. Start the AI Agent (BFF) +### 2. Start the Weather MCP Server + +Before starting the AI Agent, you need to set up the Weather MCP server. + +1. Clone the repository: +```bash +git clone https://github.com/xlight05/mcp-openweathermap.git +``` + +2. Follow the setup guide in the repository's README to start the MCP server. + +### 3. Start the AI Agent (BFF) The main agent acts as the Backend-for-Frontend and coordinates with all business APIs: @@ -81,7 +92,7 @@ bal run The agent will be available at: `http://localhost:9090` (default Ballerina AI listener port) -### 3. Start the Frontend +### 4. Start the Frontend Prerequisite: diff --git a/Lab-02-building-travel-planner/ai_backends/activity_analyzer/Ballerina.toml b/Lab-02-building-travel-planner/ai_backends/activity_analyzer/Ballerina.toml index 1adf22c1..9a4405f5 100644 --- a/Lab-02-building-travel-planner/ai_backends/activity_analyzer/Ballerina.toml +++ b/Lab-02-building-travel-planner/ai_backends/activity_analyzer/Ballerina.toml @@ -9,9 +9,9 @@ sticky = true [[tool.openapi]] id = "adminApi" targetModule = "adminApi" -filePath = "/Users/wso2/2025-CMB-AI-tutorial/resources/admin_api_spec.yaml" +filePath = "../../resources/admin_api_spec.yaml" [[tool.openapi]] id = "hotelSearchApi" targetModule = "hotelSearchApi" -filePath = "/Users/wso2/2025-CMB-AI-tutorial/resources/search_api_spec.yaml" +filePath = "../../resources/search_api_spec.yaml" diff --git a/Lab-02-building-travel-planner/ai_backends/agent/Ballerina.toml b/Lab-02-building-travel-planner/ai_backends/agent/Ballerina.toml index 8371270b..30d00ce0 100644 --- a/Lab-02-building-travel-planner/ai_backends/agent/Ballerina.toml +++ b/Lab-02-building-travel-planner/ai_backends/agent/Ballerina.toml @@ -9,9 +9,9 @@ sticky = true [[tool.openapi]] id = "hotelSearchApi" targetModule = "hotelSearchApi" -filePath = "/Users/wso2/asia-con/resources/search_api_spec.yaml" +filePath = "../../resources/search_api_spec.yaml" [[tool.openapi]] id = "bookingApi" targetModule = "bookingApi" -filePath = "/Users/wso2/asia-con/resources/booking_api_spec.yaml" +filePath = "../../resources/booking_api_spec.yaml" diff --git a/Lab-02-building-travel-planner/ai_backends/agent/functions.bal b/Lab-02-building-travel-planner/ai_backends/agent/functions.bal index 169f1dcd..8099faf8 100644 --- a/Lab-02-building-travel-planner/ai_backends/agent/functions.bal +++ b/Lab-02-building-travel-planner/ai_backends/agent/functions.bal @@ -1,7 +1,7 @@ import ballerina/ai; isolated function queryHotelPolicy(string question, string hotelId) returns string|error { - ai:QueryMatch[] aiQuerymatch = check aiVectorknowledgebase.retrieve(question, getHotelFilters(hotelId)); + ai:QueryMatch[] aiQuerymatch = check aiVectorknowledgebase.retrieve(question, -1, getHotelFilters(hotelId)); ai:ChatUserMessage aiChatusermessage = ai:augmentUserQuery(aiQuerymatch, question); ai:ChatAssistantMessage aiChatassistantmessage = check _travelPlannerModel->chat(aiChatusermessage, []); return aiChatassistantmessage.content.ensureType(); diff --git a/Lab-02-building-travel-planner/ai_backends/policy_assist/functions.bal b/Lab-02-building-travel-planner/ai_backends/policy_assist/functions.bal index 4e24681a..95e82926 100644 --- a/Lab-02-building-travel-planner/ai_backends/policy_assist/functions.bal +++ b/Lab-02-building-travel-planner/ai_backends/policy_assist/functions.bal @@ -13,7 +13,7 @@ isolated function getHotelFilters(string hotelId) returns ai:MetadataFilters { }; isolated function queryHotelPolicies(string question, string hotelId) returns string|error { - ai:QueryMatch[] aiQuerymatch = check aiVectorknowledgebase.retrieve(question, getHotelFilters(hotelId)); + ai:QueryMatch[] aiQuerymatch = check aiVectorknowledgebase.retrieve(question, -1, getHotelFilters(hotelId)); ai:ChatUserMessage aiChatusermessage = ai:augmentUserQuery(aiQuerymatch, question); ai:ChatAssistantMessage aiChatassistantmessage = check _policyAgentModel->chat(aiChatusermessage, []); return aiChatassistantmessage.content.ensureType(); diff --git a/Lab-02-building-travel-planner/frontend/.gitignore b/Lab-02-building-travel-planner/frontend/.gitignore index 2b5ef7b8..3f2a4baf 100644 --- a/Lab-02-building-travel-planner/frontend/.gitignore +++ b/Lab-02-building-travel-planner/frontend/.gitignore @@ -1,5 +1,6 @@ # Dependencies node_modules/ + /.pnp .pnp.js npm-debug.log* diff --git a/Lab-02-building-travel-planner/frontend/package-lock.json b/Lab-02-building-travel-planner/frontend/package-lock.json index 4f152492..6d186171 100644 --- a/Lab-02-building-travel-planner/frontend/package-lock.json +++ b/Lab-02-building-travel-planner/frontend/package-lock.json @@ -89,6 +89,7 @@ "resolved": "https://registry.npmjs.org/@asgardeo/react/-/react-0.5.12.tgz", "integrity": "sha512-CEBokSBYq+RcD9dULUfxJrt6UCPgMnZ8Tb3AGHO5uUQ6IKXQImqEtQW8BsKJzPar5kaSiKQi6urpzGVdywP/kg==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@asgardeo/browser": "^0.1.8", "@floating-ui/react": "^0.27.12", @@ -145,6 +146,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -794,6 +796,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1677,6 +1680,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", @@ -3971,6 +3975,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -4408,7 +4413,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -4529,6 +4533,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -4582,6 +4587,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -4951,6 +4957,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5049,6 +5056,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6141,6 +6149,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -7362,8 +7371,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -8183,6 +8191,7 @@ "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -8295,6 +8304,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -11258,6 +11268,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -14534,6 +14545,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -15721,6 +15733,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16129,6 +16142,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -16260,6 +16274,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -16311,6 +16326,7 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -16320,6 +16336,7 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.7.0.tgz", "integrity": "sha512-3FUYSwlvB/5wRJVTL/aavqHmfUKe0+Xm9MllkYgGo9eDwNdkvwlJGjpPxono1kCycLt6AnDTgjmXvK3/B4QGuw==", "license": "MIT", + "peer": true, "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" @@ -16892,6 +16909,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "license": "MIT", + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -17134,6 +17152,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -18879,6 +18898,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { "node": ">=10" }, @@ -19435,6 +19455,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.2.tgz", "integrity": "sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -19506,6 +19527,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "license": "MIT", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -19918,6 +19940,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1",