S01Nour
commited on
Commit
·
ef945f2
1
Parent(s):
e020e83
feat: Add MessageList component for chat display with specialized UI and update package dependencies.
Browse files- package-lock.json +85 -156
- package.json +2 -2
- src/app/components/chat/MessageList.tsx +193 -226
package-lock.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
| 18 |
"react-dom": "^19.1.0",
|
| 19 |
"react-markdown": "^9.0.1",
|
| 20 |
"react-router-dom": "^7.10.1",
|
| 21 |
-
"react-scripts": "5.0.1",
|
| 22 |
"recharts": "^3.5.1",
|
| 23 |
"web-vitals": "^2.1.4"
|
| 24 |
},
|
|
@@ -77,6 +77,7 @@
|
|
| 77 |
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
| 78 |
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
| 79 |
"license": "MIT",
|
|
|
|
| 80 |
"dependencies": {
|
| 81 |
"@babel/code-frame": "^7.27.1",
|
| 82 |
"@babel/generator": "^7.28.5",
|
|
@@ -726,6 +727,7 @@
|
|
| 726 |
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz",
|
| 727 |
"integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==",
|
| 728 |
"license": "MIT",
|
|
|
|
| 729 |
"dependencies": {
|
| 730 |
"@babel/helper-plugin-utils": "^7.27.1"
|
| 731 |
},
|
|
@@ -1609,6 +1611,7 @@
|
|
| 1609 |
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz",
|
| 1610 |
"integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==",
|
| 1611 |
"license": "MIT",
|
|
|
|
| 1612 |
"dependencies": {
|
| 1613 |
"@babel/helper-annotate-as-pure": "^7.27.1",
|
| 1614 |
"@babel/helper-module-imports": "^7.27.1",
|
|
@@ -3386,6 +3389,7 @@
|
|
| 3386 |
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
| 3387 |
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
| 3388 |
"license": "MIT",
|
|
|
|
| 3389 |
"dependencies": {
|
| 3390 |
"@babel/code-frame": "^7.10.4",
|
| 3391 |
"@babel/runtime": "^7.12.5",
|
|
@@ -3863,6 +3867,7 @@
|
|
| 3863 |
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
| 3864 |
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
| 3865 |
"license": "MIT",
|
|
|
|
| 3866 |
"dependencies": {
|
| 3867 |
"csstype": "^3.2.2"
|
| 3868 |
}
|
|
@@ -3873,6 +3878,7 @@
|
|
| 3873 |
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
|
| 3874 |
"devOptional": true,
|
| 3875 |
"license": "MIT",
|
|
|
|
| 3876 |
"peerDependencies": {
|
| 3877 |
"@types/react": "^19.2.0"
|
| 3878 |
}
|
|
@@ -3999,6 +4005,7 @@
|
|
| 3999 |
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
|
| 4000 |
"integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
|
| 4001 |
"license": "MIT",
|
|
|
|
| 4002 |
"dependencies": {
|
| 4003 |
"@eslint-community/regexpp": "^4.4.0",
|
| 4004 |
"@typescript-eslint/scope-manager": "5.62.0",
|
|
@@ -4052,6 +4059,7 @@
|
|
| 4052 |
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
|
| 4053 |
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
|
| 4054 |
"license": "BSD-2-Clause",
|
|
|
|
| 4055 |
"dependencies": {
|
| 4056 |
"@typescript-eslint/scope-manager": "5.62.0",
|
| 4057 |
"@typescript-eslint/types": "5.62.0",
|
|
@@ -4421,6 +4429,7 @@
|
|
| 4421 |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
| 4422 |
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
| 4423 |
"license": "MIT",
|
|
|
|
| 4424 |
"bin": {
|
| 4425 |
"acorn": "bin/acorn"
|
| 4426 |
},
|
|
@@ -4519,6 +4528,7 @@
|
|
| 4519 |
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
| 4520 |
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
| 4521 |
"license": "MIT",
|
|
|
|
| 4522 |
"dependencies": {
|
| 4523 |
"fast-deep-equal": "^3.1.1",
|
| 4524 |
"fast-json-stable-stringify": "^2.0.0",
|
|
@@ -5436,6 +5446,7 @@
|
|
| 5436 |
}
|
| 5437 |
],
|
| 5438 |
"license": "MIT",
|
|
|
|
| 5439 |
"dependencies": {
|
| 5440 |
"baseline-browser-mapping": "^2.9.0",
|
| 5441 |
"caniuse-lite": "^1.0.30001759",
|
|
@@ -7228,9 +7239,9 @@
|
|
| 7228 |
}
|
| 7229 |
},
|
| 7230 |
"node_modules/enhanced-resolve": {
|
| 7231 |
-
"version": "5.18.
|
| 7232 |
-
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.
|
| 7233 |
-
"integrity": "sha512-
|
| 7234 |
"license": "MIT",
|
| 7235 |
"dependencies": {
|
| 7236 |
"graceful-fs": "^4.2.4",
|
|
@@ -7268,9 +7279,9 @@
|
|
| 7268 |
}
|
| 7269 |
},
|
| 7270 |
"node_modules/es-abstract": {
|
| 7271 |
-
"version": "1.24.
|
| 7272 |
-
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.
|
| 7273 |
-
"integrity": "sha512-
|
| 7274 |
"license": "MIT",
|
| 7275 |
"dependencies": {
|
| 7276 |
"array-buffer-byte-length": "^1.0.2",
|
|
@@ -7360,26 +7371,26 @@
|
|
| 7360 |
}
|
| 7361 |
},
|
| 7362 |
"node_modules/es-iterator-helpers": {
|
| 7363 |
-
"version": "1.2.
|
| 7364 |
-
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.
|
| 7365 |
-
"integrity": "sha512-
|
| 7366 |
"license": "MIT",
|
| 7367 |
"dependencies": {
|
| 7368 |
"call-bind": "^1.0.8",
|
| 7369 |
-
"call-bound": "^1.0.
|
| 7370 |
"define-properties": "^1.2.1",
|
| 7371 |
-
"es-abstract": "^1.
|
| 7372 |
"es-errors": "^1.3.0",
|
| 7373 |
-
"es-set-tostringtag": "^2.0
|
| 7374 |
"function-bind": "^1.1.2",
|
| 7375 |
-
"get-intrinsic": "^1.
|
| 7376 |
"globalthis": "^1.0.4",
|
| 7377 |
"gopd": "^1.2.0",
|
| 7378 |
"has-property-descriptors": "^1.0.2",
|
| 7379 |
"has-proto": "^1.2.0",
|
| 7380 |
"has-symbols": "^1.1.0",
|
| 7381 |
"internal-slot": "^1.1.0",
|
| 7382 |
-
"iterator.prototype": "^1.1.
|
| 7383 |
"safe-array-concat": "^1.1.3"
|
| 7384 |
},
|
| 7385 |
"engines": {
|
|
@@ -7387,9 +7398,9 @@
|
|
| 7387 |
}
|
| 7388 |
},
|
| 7389 |
"node_modules/es-module-lexer": {
|
| 7390 |
-
"version": "
|
| 7391 |
-
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-
|
| 7392 |
-
"integrity": "sha512-
|
| 7393 |
"license": "MIT"
|
| 7394 |
},
|
| 7395 |
"node_modules/es-object-atoms": {
|
|
@@ -7522,6 +7533,7 @@
|
|
| 7522 |
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
| 7523 |
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
| 7524 |
"license": "MIT",
|
|
|
|
| 7525 |
"dependencies": {
|
| 7526 |
"@eslint-community/eslint-utils": "^4.2.0",
|
| 7527 |
"@eslint-community/regexpp": "^4.6.1",
|
|
@@ -10393,6 +10405,7 @@
|
|
| 10393 |
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
|
| 10394 |
"integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==",
|
| 10395 |
"license": "MIT",
|
|
|
|
| 10396 |
"dependencies": {
|
| 10397 |
"@jest/core": "^27.5.1",
|
| 10398 |
"import-local": "^3.0.2",
|
|
@@ -11278,6 +11291,7 @@
|
|
| 11278 |
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
| 11279 |
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
| 11280 |
"license": "MIT",
|
|
|
|
| 11281 |
"bin": {
|
| 11282 |
"jiti": "bin/jiti.js"
|
| 11283 |
}
|
|
@@ -12782,21 +12796,21 @@
|
|
| 12782 |
}
|
| 12783 |
},
|
| 12784 |
"node_modules/object.getownpropertydescriptors": {
|
| 12785 |
-
"version": "2.1.
|
| 12786 |
-
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.
|
| 12787 |
-
"integrity": "sha512-
|
| 12788 |
"license": "MIT",
|
| 12789 |
"dependencies": {
|
| 12790 |
-
"array.prototype.reduce": "^1.0.
|
| 12791 |
-
"call-bind": "^1.0.
|
| 12792 |
"define-properties": "^1.2.1",
|
| 12793 |
-
"es-abstract": "^1.
|
| 12794 |
-
"es-object-atoms": "^1.
|
| 12795 |
-
"gopd": "^1.0
|
| 12796 |
-
"safe-array-concat": "^1.1.
|
| 12797 |
},
|
| 12798 |
"engines": {
|
| 12799 |
-
"node": ">= 0.
|
| 12800 |
},
|
| 12801 |
"funding": {
|
| 12802 |
"url": "https://github.com/sponsors/ljharb"
|
|
@@ -13263,6 +13277,7 @@
|
|
| 13263 |
}
|
| 13264 |
],
|
| 13265 |
"license": "MIT",
|
|
|
|
| 13266 |
"dependencies": {
|
| 13267 |
"nanoid": "^3.3.11",
|
| 13268 |
"picocolors": "^1.1.1",
|
|
@@ -14397,6 +14412,7 @@
|
|
| 14397 |
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
| 14398 |
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
| 14399 |
"license": "MIT",
|
|
|
|
| 14400 |
"dependencies": {
|
| 14401 |
"cssesc": "^3.0.0",
|
| 14402 |
"util-deprecate": "^1.0.2"
|
|
@@ -14767,6 +14783,7 @@
|
|
| 14767 |
"resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz",
|
| 14768 |
"integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==",
|
| 14769 |
"license": "MIT",
|
|
|
|
| 14770 |
"engines": {
|
| 14771 |
"node": ">=0.10.0"
|
| 14772 |
}
|
|
@@ -14898,6 +14915,7 @@
|
|
| 14898 |
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz",
|
| 14899 |
"integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==",
|
| 14900 |
"license": "MIT",
|
|
|
|
| 14901 |
"dependencies": {
|
| 14902 |
"scheduler": "^0.27.0"
|
| 14903 |
},
|
|
@@ -14915,7 +14933,8 @@
|
|
| 14915 |
"version": "17.0.2",
|
| 14916 |
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
| 14917 |
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
| 14918 |
-
"license": "MIT"
|
|
|
|
| 14919 |
},
|
| 14920 |
"node_modules/react-markdown": {
|
| 14921 |
"version": "9.1.0",
|
|
@@ -14949,6 +14968,7 @@
|
|
| 14949 |
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
| 14950 |
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
| 14951 |
"license": "MIT",
|
|
|
|
| 14952 |
"dependencies": {
|
| 14953 |
"@types/use-sync-external-store": "^0.0.6",
|
| 14954 |
"use-sync-external-store": "^1.4.0"
|
|
@@ -14972,6 +14992,7 @@
|
|
| 14972 |
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
| 14973 |
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==",
|
| 14974 |
"license": "MIT",
|
|
|
|
| 14975 |
"engines": {
|
| 14976 |
"node": ">=0.10.0"
|
| 14977 |
}
|
|
@@ -15210,7 +15231,8 @@
|
|
| 15210 |
"version": "5.0.1",
|
| 15211 |
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
| 15212 |
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
| 15213 |
-
"license": "MIT"
|
|
|
|
| 15214 |
},
|
| 15215 |
"node_modules/redux-thunk": {
|
| 15216 |
"version": "3.1.0",
|
|
@@ -15569,6 +15591,7 @@
|
|
| 15569 |
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
|
| 15570 |
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
| 15571 |
"license": "MIT",
|
|
|
|
| 15572 |
"bin": {
|
| 15573 |
"rollup": "dist/bin/rollup"
|
| 15574 |
},
|
|
@@ -15811,6 +15834,7 @@
|
|
| 15811 |
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
| 15812 |
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
| 15813 |
"license": "MIT",
|
|
|
|
| 15814 |
"dependencies": {
|
| 15815 |
"fast-deep-equal": "^3.1.3",
|
| 15816 |
"fast-uri": "^3.0.1",
|
|
@@ -15872,9 +15896,9 @@
|
|
| 15872 |
}
|
| 15873 |
},
|
| 15874 |
"node_modules/send": {
|
| 15875 |
-
"version": "0.19.
|
| 15876 |
-
"resolved": "https://registry.npmjs.org/send/-/send-0.19.
|
| 15877 |
-
"integrity": "sha512-
|
| 15878 |
"license": "MIT",
|
| 15879 |
"dependencies": {
|
| 15880 |
"debug": "2.6.9",
|
|
@@ -15883,13 +15907,13 @@
|
|
| 15883 |
"encodeurl": "~2.0.0",
|
| 15884 |
"escape-html": "~1.0.3",
|
| 15885 |
"etag": "~1.8.1",
|
| 15886 |
-
"fresh": "0.5.2",
|
| 15887 |
-
"http-errors": "2.0.
|
| 15888 |
"mime": "1.6.0",
|
| 15889 |
"ms": "2.1.3",
|
| 15890 |
-
"on-finished": "2.4.1",
|
| 15891 |
"range-parser": "~1.2.1",
|
| 15892 |
-
"statuses": "2.0.
|
| 15893 |
},
|
| 15894 |
"engines": {
|
| 15895 |
"node": ">= 0.8.0"
|
|
@@ -15910,31 +15934,6 @@
|
|
| 15910 |
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
| 15911 |
"license": "MIT"
|
| 15912 |
},
|
| 15913 |
-
"node_modules/send/node_modules/http-errors": {
|
| 15914 |
-
"version": "2.0.0",
|
| 15915 |
-
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
| 15916 |
-
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
| 15917 |
-
"license": "MIT",
|
| 15918 |
-
"dependencies": {
|
| 15919 |
-
"depd": "2.0.0",
|
| 15920 |
-
"inherits": "2.0.4",
|
| 15921 |
-
"setprototypeof": "1.2.0",
|
| 15922 |
-
"statuses": "2.0.1",
|
| 15923 |
-
"toidentifier": "1.0.1"
|
| 15924 |
-
},
|
| 15925 |
-
"engines": {
|
| 15926 |
-
"node": ">= 0.8"
|
| 15927 |
-
}
|
| 15928 |
-
},
|
| 15929 |
-
"node_modules/send/node_modules/statuses": {
|
| 15930 |
-
"version": "2.0.1",
|
| 15931 |
-
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
| 15932 |
-
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
| 15933 |
-
"license": "MIT",
|
| 15934 |
-
"engines": {
|
| 15935 |
-
"node": ">= 0.8"
|
| 15936 |
-
}
|
| 15937 |
-
},
|
| 15938 |
"node_modules/serialize-javascript": {
|
| 15939 |
"version": "6.0.2",
|
| 15940 |
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
|
@@ -16023,93 +16022,20 @@
|
|
| 16023 |
}
|
| 16024 |
},
|
| 16025 |
"node_modules/serve-static": {
|
| 16026 |
-
"version": "1.16.
|
| 16027 |
-
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.
|
| 16028 |
-
"integrity": "sha512-
|
| 16029 |
"license": "MIT",
|
| 16030 |
"dependencies": {
|
| 16031 |
"encodeurl": "~2.0.0",
|
| 16032 |
"escape-html": "~1.0.3",
|
| 16033 |
"parseurl": "~1.3.3",
|
| 16034 |
-
"send": "0.19.
|
| 16035 |
},
|
| 16036 |
"engines": {
|
| 16037 |
"node": ">= 0.8.0"
|
| 16038 |
}
|
| 16039 |
},
|
| 16040 |
-
"node_modules/serve-static/node_modules/debug": {
|
| 16041 |
-
"version": "2.6.9",
|
| 16042 |
-
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
| 16043 |
-
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
| 16044 |
-
"license": "MIT",
|
| 16045 |
-
"dependencies": {
|
| 16046 |
-
"ms": "2.0.0"
|
| 16047 |
-
}
|
| 16048 |
-
},
|
| 16049 |
-
"node_modules/serve-static/node_modules/debug/node_modules/ms": {
|
| 16050 |
-
"version": "2.0.0",
|
| 16051 |
-
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
| 16052 |
-
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
| 16053 |
-
"license": "MIT"
|
| 16054 |
-
},
|
| 16055 |
-
"node_modules/serve-static/node_modules/http-errors": {
|
| 16056 |
-
"version": "2.0.0",
|
| 16057 |
-
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
| 16058 |
-
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
| 16059 |
-
"license": "MIT",
|
| 16060 |
-
"dependencies": {
|
| 16061 |
-
"depd": "2.0.0",
|
| 16062 |
-
"inherits": "2.0.4",
|
| 16063 |
-
"setprototypeof": "1.2.0",
|
| 16064 |
-
"statuses": "2.0.1",
|
| 16065 |
-
"toidentifier": "1.0.1"
|
| 16066 |
-
},
|
| 16067 |
-
"engines": {
|
| 16068 |
-
"node": ">= 0.8"
|
| 16069 |
-
}
|
| 16070 |
-
},
|
| 16071 |
-
"node_modules/serve-static/node_modules/send": {
|
| 16072 |
-
"version": "0.19.0",
|
| 16073 |
-
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
| 16074 |
-
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
| 16075 |
-
"license": "MIT",
|
| 16076 |
-
"dependencies": {
|
| 16077 |
-
"debug": "2.6.9",
|
| 16078 |
-
"depd": "2.0.0",
|
| 16079 |
-
"destroy": "1.2.0",
|
| 16080 |
-
"encodeurl": "~1.0.2",
|
| 16081 |
-
"escape-html": "~1.0.3",
|
| 16082 |
-
"etag": "~1.8.1",
|
| 16083 |
-
"fresh": "0.5.2",
|
| 16084 |
-
"http-errors": "2.0.0",
|
| 16085 |
-
"mime": "1.6.0",
|
| 16086 |
-
"ms": "2.1.3",
|
| 16087 |
-
"on-finished": "2.4.1",
|
| 16088 |
-
"range-parser": "~1.2.1",
|
| 16089 |
-
"statuses": "2.0.1"
|
| 16090 |
-
},
|
| 16091 |
-
"engines": {
|
| 16092 |
-
"node": ">= 0.8.0"
|
| 16093 |
-
}
|
| 16094 |
-
},
|
| 16095 |
-
"node_modules/serve-static/node_modules/send/node_modules/encodeurl": {
|
| 16096 |
-
"version": "1.0.2",
|
| 16097 |
-
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
| 16098 |
-
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
| 16099 |
-
"license": "MIT",
|
| 16100 |
-
"engines": {
|
| 16101 |
-
"node": ">= 0.8"
|
| 16102 |
-
}
|
| 16103 |
-
},
|
| 16104 |
-
"node_modules/serve-static/node_modules/statuses": {
|
| 16105 |
-
"version": "2.0.1",
|
| 16106 |
-
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
| 16107 |
-
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
| 16108 |
-
"license": "MIT",
|
| 16109 |
-
"engines": {
|
| 16110 |
-
"node": ">= 0.8"
|
| 16111 |
-
}
|
| 16112 |
-
},
|
| 16113 |
"node_modules/set-cookie-parser": {
|
| 16114 |
"version": "2.7.2",
|
| 16115 |
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
|
|
@@ -17290,9 +17216,9 @@
|
|
| 17290 |
}
|
| 17291 |
},
|
| 17292 |
"node_modules/terser-webpack-plugin": {
|
| 17293 |
-
"version": "5.3.
|
| 17294 |
-
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.
|
| 17295 |
-
"integrity": "sha512-
|
| 17296 |
"license": "MIT",
|
| 17297 |
"dependencies": {
|
| 17298 |
"@jridgewell/trace-mapping": "^0.3.25",
|
|
@@ -17426,6 +17352,7 @@
|
|
| 17426 |
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
| 17427 |
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
| 17428 |
"license": "MIT",
|
|
|
|
| 17429 |
"engines": {
|
| 17430 |
"node": ">=12"
|
| 17431 |
},
|
|
@@ -17718,9 +17645,9 @@
|
|
| 17718 |
}
|
| 17719 |
},
|
| 17720 |
"node_modules/typescript": {
|
| 17721 |
-
"version": "
|
| 17722 |
-
"resolved": "https://registry.npmjs.org/typescript/-/typescript-
|
| 17723 |
-
"integrity": "sha512-
|
| 17724 |
"license": "Apache-2.0",
|
| 17725 |
"peer": true,
|
| 17726 |
"bin": {
|
|
@@ -17728,7 +17655,7 @@
|
|
| 17728 |
"tsserver": "bin/tsserver"
|
| 17729 |
},
|
| 17730 |
"engines": {
|
| 17731 |
-
"node": ">=
|
| 17732 |
}
|
| 17733 |
},
|
| 17734 |
"node_modules/unbox-primitive": {
|
|
@@ -18160,9 +18087,9 @@
|
|
| 18160 |
}
|
| 18161 |
},
|
| 18162 |
"node_modules/watchpack": {
|
| 18163 |
-
"version": "2.
|
| 18164 |
-
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.
|
| 18165 |
-
"integrity": "sha512-
|
| 18166 |
"license": "MIT",
|
| 18167 |
"dependencies": {
|
| 18168 |
"glob-to-regexp": "^0.4.1",
|
|
@@ -18197,10 +18124,11 @@
|
|
| 18197 |
}
|
| 18198 |
},
|
| 18199 |
"node_modules/webpack": {
|
| 18200 |
-
"version": "5.
|
| 18201 |
-
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.
|
| 18202 |
-
"integrity": "sha512-
|
| 18203 |
"license": "MIT",
|
|
|
|
| 18204 |
"dependencies": {
|
| 18205 |
"@types/eslint-scope": "^3.7.7",
|
| 18206 |
"@types/estree": "^1.0.8",
|
|
@@ -18210,10 +18138,10 @@
|
|
| 18210 |
"@webassemblyjs/wasm-parser": "^1.14.1",
|
| 18211 |
"acorn": "^8.15.0",
|
| 18212 |
"acorn-import-phases": "^1.0.3",
|
| 18213 |
-
"browserslist": "^4.
|
| 18214 |
"chrome-trace-event": "^1.0.2",
|
| 18215 |
-
"enhanced-resolve": "^5.17.
|
| 18216 |
-
"es-module-lexer": "^
|
| 18217 |
"eslint-scope": "5.1.1",
|
| 18218 |
"events": "^3.2.0",
|
| 18219 |
"glob-to-regexp": "^0.4.1",
|
|
@@ -18224,7 +18152,7 @@
|
|
| 18224 |
"neo-async": "^2.6.2",
|
| 18225 |
"schema-utils": "^4.3.3",
|
| 18226 |
"tapable": "^2.3.0",
|
| 18227 |
-
"terser-webpack-plugin": "^5.3.
|
| 18228 |
"watchpack": "^2.4.4",
|
| 18229 |
"webpack-sources": "^3.3.3"
|
| 18230 |
},
|
|
@@ -18684,6 +18612,7 @@
|
|
| 18684 |
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
| 18685 |
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
| 18686 |
"license": "MIT",
|
|
|
|
| 18687 |
"dependencies": {
|
| 18688 |
"fast-deep-equal": "^3.1.3",
|
| 18689 |
"fast-uri": "^3.0.1",
|
|
|
|
| 18 |
"react-dom": "^19.1.0",
|
| 19 |
"react-markdown": "^9.0.1",
|
| 20 |
"react-router-dom": "^7.10.1",
|
| 21 |
+
"react-scripts": "^5.0.1",
|
| 22 |
"recharts": "^3.5.1",
|
| 23 |
"web-vitals": "^2.1.4"
|
| 24 |
},
|
|
|
|
| 77 |
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
| 78 |
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
| 79 |
"license": "MIT",
|
| 80 |
+
"peer": true,
|
| 81 |
"dependencies": {
|
| 82 |
"@babel/code-frame": "^7.27.1",
|
| 83 |
"@babel/generator": "^7.28.5",
|
|
|
|
| 727 |
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz",
|
| 728 |
"integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==",
|
| 729 |
"license": "MIT",
|
| 730 |
+
"peer": true,
|
| 731 |
"dependencies": {
|
| 732 |
"@babel/helper-plugin-utils": "^7.27.1"
|
| 733 |
},
|
|
|
|
| 1611 |
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz",
|
| 1612 |
"integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==",
|
| 1613 |
"license": "MIT",
|
| 1614 |
+
"peer": true,
|
| 1615 |
"dependencies": {
|
| 1616 |
"@babel/helper-annotate-as-pure": "^7.27.1",
|
| 1617 |
"@babel/helper-module-imports": "^7.27.1",
|
|
|
|
| 3389 |
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
| 3390 |
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
| 3391 |
"license": "MIT",
|
| 3392 |
+
"peer": true,
|
| 3393 |
"dependencies": {
|
| 3394 |
"@babel/code-frame": "^7.10.4",
|
| 3395 |
"@babel/runtime": "^7.12.5",
|
|
|
|
| 3867 |
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
| 3868 |
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
| 3869 |
"license": "MIT",
|
| 3870 |
+
"peer": true,
|
| 3871 |
"dependencies": {
|
| 3872 |
"csstype": "^3.2.2"
|
| 3873 |
}
|
|
|
|
| 3878 |
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
|
| 3879 |
"devOptional": true,
|
| 3880 |
"license": "MIT",
|
| 3881 |
+
"peer": true,
|
| 3882 |
"peerDependencies": {
|
| 3883 |
"@types/react": "^19.2.0"
|
| 3884 |
}
|
|
|
|
| 4005 |
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
|
| 4006 |
"integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
|
| 4007 |
"license": "MIT",
|
| 4008 |
+
"peer": true,
|
| 4009 |
"dependencies": {
|
| 4010 |
"@eslint-community/regexpp": "^4.4.0",
|
| 4011 |
"@typescript-eslint/scope-manager": "5.62.0",
|
|
|
|
| 4059 |
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
|
| 4060 |
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
|
| 4061 |
"license": "BSD-2-Clause",
|
| 4062 |
+
"peer": true,
|
| 4063 |
"dependencies": {
|
| 4064 |
"@typescript-eslint/scope-manager": "5.62.0",
|
| 4065 |
"@typescript-eslint/types": "5.62.0",
|
|
|
|
| 4429 |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
| 4430 |
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
| 4431 |
"license": "MIT",
|
| 4432 |
+
"peer": true,
|
| 4433 |
"bin": {
|
| 4434 |
"acorn": "bin/acorn"
|
| 4435 |
},
|
|
|
|
| 4528 |
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
| 4529 |
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
| 4530 |
"license": "MIT",
|
| 4531 |
+
"peer": true,
|
| 4532 |
"dependencies": {
|
| 4533 |
"fast-deep-equal": "^3.1.1",
|
| 4534 |
"fast-json-stable-stringify": "^2.0.0",
|
|
|
|
| 5446 |
}
|
| 5447 |
],
|
| 5448 |
"license": "MIT",
|
| 5449 |
+
"peer": true,
|
| 5450 |
"dependencies": {
|
| 5451 |
"baseline-browser-mapping": "^2.9.0",
|
| 5452 |
"caniuse-lite": "^1.0.30001759",
|
|
|
|
| 7239 |
}
|
| 7240 |
},
|
| 7241 |
"node_modules/enhanced-resolve": {
|
| 7242 |
+
"version": "5.18.4",
|
| 7243 |
+
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
|
| 7244 |
+
"integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
|
| 7245 |
"license": "MIT",
|
| 7246 |
"dependencies": {
|
| 7247 |
"graceful-fs": "^4.2.4",
|
|
|
|
| 7279 |
}
|
| 7280 |
},
|
| 7281 |
"node_modules/es-abstract": {
|
| 7282 |
+
"version": "1.24.1",
|
| 7283 |
+
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
|
| 7284 |
+
"integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
|
| 7285 |
"license": "MIT",
|
| 7286 |
"dependencies": {
|
| 7287 |
"array-buffer-byte-length": "^1.0.2",
|
|
|
|
| 7371 |
}
|
| 7372 |
},
|
| 7373 |
"node_modules/es-iterator-helpers": {
|
| 7374 |
+
"version": "1.2.2",
|
| 7375 |
+
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz",
|
| 7376 |
+
"integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==",
|
| 7377 |
"license": "MIT",
|
| 7378 |
"dependencies": {
|
| 7379 |
"call-bind": "^1.0.8",
|
| 7380 |
+
"call-bound": "^1.0.4",
|
| 7381 |
"define-properties": "^1.2.1",
|
| 7382 |
+
"es-abstract": "^1.24.1",
|
| 7383 |
"es-errors": "^1.3.0",
|
| 7384 |
+
"es-set-tostringtag": "^2.1.0",
|
| 7385 |
"function-bind": "^1.1.2",
|
| 7386 |
+
"get-intrinsic": "^1.3.0",
|
| 7387 |
"globalthis": "^1.0.4",
|
| 7388 |
"gopd": "^1.2.0",
|
| 7389 |
"has-property-descriptors": "^1.0.2",
|
| 7390 |
"has-proto": "^1.2.0",
|
| 7391 |
"has-symbols": "^1.1.0",
|
| 7392 |
"internal-slot": "^1.1.0",
|
| 7393 |
+
"iterator.prototype": "^1.1.5",
|
| 7394 |
"safe-array-concat": "^1.1.3"
|
| 7395 |
},
|
| 7396 |
"engines": {
|
|
|
|
| 7398 |
}
|
| 7399 |
},
|
| 7400 |
"node_modules/es-module-lexer": {
|
| 7401 |
+
"version": "2.0.0",
|
| 7402 |
+
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
|
| 7403 |
+
"integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
|
| 7404 |
"license": "MIT"
|
| 7405 |
},
|
| 7406 |
"node_modules/es-object-atoms": {
|
|
|
|
| 7533 |
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
| 7534 |
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
| 7535 |
"license": "MIT",
|
| 7536 |
+
"peer": true,
|
| 7537 |
"dependencies": {
|
| 7538 |
"@eslint-community/eslint-utils": "^4.2.0",
|
| 7539 |
"@eslint-community/regexpp": "^4.6.1",
|
|
|
|
| 10405 |
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
|
| 10406 |
"integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==",
|
| 10407 |
"license": "MIT",
|
| 10408 |
+
"peer": true,
|
| 10409 |
"dependencies": {
|
| 10410 |
"@jest/core": "^27.5.1",
|
| 10411 |
"import-local": "^3.0.2",
|
|
|
|
| 11291 |
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
| 11292 |
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
| 11293 |
"license": "MIT",
|
| 11294 |
+
"peer": true,
|
| 11295 |
"bin": {
|
| 11296 |
"jiti": "bin/jiti.js"
|
| 11297 |
}
|
|
|
|
| 12796 |
}
|
| 12797 |
},
|
| 12798 |
"node_modules/object.getownpropertydescriptors": {
|
| 12799 |
+
"version": "2.1.9",
|
| 12800 |
+
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.9.tgz",
|
| 12801 |
+
"integrity": "sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==",
|
| 12802 |
"license": "MIT",
|
| 12803 |
"dependencies": {
|
| 12804 |
+
"array.prototype.reduce": "^1.0.8",
|
| 12805 |
+
"call-bind": "^1.0.8",
|
| 12806 |
"define-properties": "^1.2.1",
|
| 12807 |
+
"es-abstract": "^1.24.0",
|
| 12808 |
+
"es-object-atoms": "^1.1.1",
|
| 12809 |
+
"gopd": "^1.2.0",
|
| 12810 |
+
"safe-array-concat": "^1.1.3"
|
| 12811 |
},
|
| 12812 |
"engines": {
|
| 12813 |
+
"node": ">= 0.4"
|
| 12814 |
},
|
| 12815 |
"funding": {
|
| 12816 |
"url": "https://github.com/sponsors/ljharb"
|
|
|
|
| 13277 |
}
|
| 13278 |
],
|
| 13279 |
"license": "MIT",
|
| 13280 |
+
"peer": true,
|
| 13281 |
"dependencies": {
|
| 13282 |
"nanoid": "^3.3.11",
|
| 13283 |
"picocolors": "^1.1.1",
|
|
|
|
| 14412 |
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
| 14413 |
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
| 14414 |
"license": "MIT",
|
| 14415 |
+
"peer": true,
|
| 14416 |
"dependencies": {
|
| 14417 |
"cssesc": "^3.0.0",
|
| 14418 |
"util-deprecate": "^1.0.2"
|
|
|
|
| 14783 |
"resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz",
|
| 14784 |
"integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==",
|
| 14785 |
"license": "MIT",
|
| 14786 |
+
"peer": true,
|
| 14787 |
"engines": {
|
| 14788 |
"node": ">=0.10.0"
|
| 14789 |
}
|
|
|
|
| 14915 |
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz",
|
| 14916 |
"integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==",
|
| 14917 |
"license": "MIT",
|
| 14918 |
+
"peer": true,
|
| 14919 |
"dependencies": {
|
| 14920 |
"scheduler": "^0.27.0"
|
| 14921 |
},
|
|
|
|
| 14933 |
"version": "17.0.2",
|
| 14934 |
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
| 14935 |
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
| 14936 |
+
"license": "MIT",
|
| 14937 |
+
"peer": true
|
| 14938 |
},
|
| 14939 |
"node_modules/react-markdown": {
|
| 14940 |
"version": "9.1.0",
|
|
|
|
| 14968 |
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
| 14969 |
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
| 14970 |
"license": "MIT",
|
| 14971 |
+
"peer": true,
|
| 14972 |
"dependencies": {
|
| 14973 |
"@types/use-sync-external-store": "^0.0.6",
|
| 14974 |
"use-sync-external-store": "^1.4.0"
|
|
|
|
| 14992 |
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
| 14993 |
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==",
|
| 14994 |
"license": "MIT",
|
| 14995 |
+
"peer": true,
|
| 14996 |
"engines": {
|
| 14997 |
"node": ">=0.10.0"
|
| 14998 |
}
|
|
|
|
| 15231 |
"version": "5.0.1",
|
| 15232 |
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
| 15233 |
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
| 15234 |
+
"license": "MIT",
|
| 15235 |
+
"peer": true
|
| 15236 |
},
|
| 15237 |
"node_modules/redux-thunk": {
|
| 15238 |
"version": "3.1.0",
|
|
|
|
| 15591 |
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
|
| 15592 |
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
| 15593 |
"license": "MIT",
|
| 15594 |
+
"peer": true,
|
| 15595 |
"bin": {
|
| 15596 |
"rollup": "dist/bin/rollup"
|
| 15597 |
},
|
|
|
|
| 15834 |
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
| 15835 |
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
| 15836 |
"license": "MIT",
|
| 15837 |
+
"peer": true,
|
| 15838 |
"dependencies": {
|
| 15839 |
"fast-deep-equal": "^3.1.3",
|
| 15840 |
"fast-uri": "^3.0.1",
|
|
|
|
| 15896 |
}
|
| 15897 |
},
|
| 15898 |
"node_modules/send": {
|
| 15899 |
+
"version": "0.19.2",
|
| 15900 |
+
"resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz",
|
| 15901 |
+
"integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
|
| 15902 |
"license": "MIT",
|
| 15903 |
"dependencies": {
|
| 15904 |
"debug": "2.6.9",
|
|
|
|
| 15907 |
"encodeurl": "~2.0.0",
|
| 15908 |
"escape-html": "~1.0.3",
|
| 15909 |
"etag": "~1.8.1",
|
| 15910 |
+
"fresh": "~0.5.2",
|
| 15911 |
+
"http-errors": "~2.0.1",
|
| 15912 |
"mime": "1.6.0",
|
| 15913 |
"ms": "2.1.3",
|
| 15914 |
+
"on-finished": "~2.4.1",
|
| 15915 |
"range-parser": "~1.2.1",
|
| 15916 |
+
"statuses": "~2.0.2"
|
| 15917 |
},
|
| 15918 |
"engines": {
|
| 15919 |
"node": ">= 0.8.0"
|
|
|
|
| 15934 |
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
| 15935 |
"license": "MIT"
|
| 15936 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15937 |
"node_modules/serialize-javascript": {
|
| 15938 |
"version": "6.0.2",
|
| 15939 |
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
|
|
|
| 16022 |
}
|
| 16023 |
},
|
| 16024 |
"node_modules/serve-static": {
|
| 16025 |
+
"version": "1.16.3",
|
| 16026 |
+
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
|
| 16027 |
+
"integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
|
| 16028 |
"license": "MIT",
|
| 16029 |
"dependencies": {
|
| 16030 |
"encodeurl": "~2.0.0",
|
| 16031 |
"escape-html": "~1.0.3",
|
| 16032 |
"parseurl": "~1.3.3",
|
| 16033 |
+
"send": "~0.19.1"
|
| 16034 |
},
|
| 16035 |
"engines": {
|
| 16036 |
"node": ">= 0.8.0"
|
| 16037 |
}
|
| 16038 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16039 |
"node_modules/set-cookie-parser": {
|
| 16040 |
"version": "2.7.2",
|
| 16041 |
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
|
|
|
|
| 17216 |
}
|
| 17217 |
},
|
| 17218 |
"node_modules/terser-webpack-plugin": {
|
| 17219 |
+
"version": "5.3.16",
|
| 17220 |
+
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz",
|
| 17221 |
+
"integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==",
|
| 17222 |
"license": "MIT",
|
| 17223 |
"dependencies": {
|
| 17224 |
"@jridgewell/trace-mapping": "^0.3.25",
|
|
|
|
| 17352 |
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
| 17353 |
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
| 17354 |
"license": "MIT",
|
| 17355 |
+
"peer": true,
|
| 17356 |
"engines": {
|
| 17357 |
"node": ">=12"
|
| 17358 |
},
|
|
|
|
| 17645 |
}
|
| 17646 |
},
|
| 17647 |
"node_modules/typescript": {
|
| 17648 |
+
"version": "5.9.3",
|
| 17649 |
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
| 17650 |
+
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
| 17651 |
"license": "Apache-2.0",
|
| 17652 |
"peer": true,
|
| 17653 |
"bin": {
|
|
|
|
| 17655 |
"tsserver": "bin/tsserver"
|
| 17656 |
},
|
| 17657 |
"engines": {
|
| 17658 |
+
"node": ">=14.17"
|
| 17659 |
}
|
| 17660 |
},
|
| 17661 |
"node_modules/unbox-primitive": {
|
|
|
|
| 18087 |
}
|
| 18088 |
},
|
| 18089 |
"node_modules/watchpack": {
|
| 18090 |
+
"version": "2.5.0",
|
| 18091 |
+
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz",
|
| 18092 |
+
"integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==",
|
| 18093 |
"license": "MIT",
|
| 18094 |
"dependencies": {
|
| 18095 |
"glob-to-regexp": "^0.4.1",
|
|
|
|
| 18124 |
}
|
| 18125 |
},
|
| 18126 |
"node_modules/webpack": {
|
| 18127 |
+
"version": "5.104.1",
|
| 18128 |
+
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz",
|
| 18129 |
+
"integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
|
| 18130 |
"license": "MIT",
|
| 18131 |
+
"peer": true,
|
| 18132 |
"dependencies": {
|
| 18133 |
"@types/eslint-scope": "^3.7.7",
|
| 18134 |
"@types/estree": "^1.0.8",
|
|
|
|
| 18138 |
"@webassemblyjs/wasm-parser": "^1.14.1",
|
| 18139 |
"acorn": "^8.15.0",
|
| 18140 |
"acorn-import-phases": "^1.0.3",
|
| 18141 |
+
"browserslist": "^4.28.1",
|
| 18142 |
"chrome-trace-event": "^1.0.2",
|
| 18143 |
+
"enhanced-resolve": "^5.17.4",
|
| 18144 |
+
"es-module-lexer": "^2.0.0",
|
| 18145 |
"eslint-scope": "5.1.1",
|
| 18146 |
"events": "^3.2.0",
|
| 18147 |
"glob-to-regexp": "^0.4.1",
|
|
|
|
| 18152 |
"neo-async": "^2.6.2",
|
| 18153 |
"schema-utils": "^4.3.3",
|
| 18154 |
"tapable": "^2.3.0",
|
| 18155 |
+
"terser-webpack-plugin": "^5.3.16",
|
| 18156 |
"watchpack": "^2.4.4",
|
| 18157 |
"webpack-sources": "^3.3.3"
|
| 18158 |
},
|
|
|
|
| 18612 |
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
| 18613 |
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
| 18614 |
"license": "MIT",
|
| 18615 |
+
"peer": true,
|
| 18616 |
"dependencies": {
|
| 18617 |
"fast-deep-equal": "^3.1.3",
|
| 18618 |
"fast-uri": "^3.0.1",
|
package.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
| 7 |
"@testing-library/jest-dom": "^6.6.3",
|
| 8 |
"@testing-library/react": "^16.3.0",
|
| 9 |
"@testing-library/user-event": "^13.5.0",
|
| 10 |
-
"react-markdown": "^9.0.1",
|
| 11 |
"lucide-react": "^0.561.0",
|
| 12 |
"postgres": "^3.4.7",
|
| 13 |
"react": "^19.1.0",
|
| 14 |
"react-dom": "^19.1.0",
|
|
|
|
| 15 |
"react-router-dom": "^7.10.1",
|
| 16 |
-
"react-scripts": "5.0.1",
|
| 17 |
"recharts": "^3.5.1",
|
| 18 |
"web-vitals": "^2.1.4"
|
| 19 |
},
|
|
|
|
| 7 |
"@testing-library/jest-dom": "^6.6.3",
|
| 8 |
"@testing-library/react": "^16.3.0",
|
| 9 |
"@testing-library/user-event": "^13.5.0",
|
|
|
|
| 10 |
"lucide-react": "^0.561.0",
|
| 11 |
"postgres": "^3.4.7",
|
| 12 |
"react": "^19.1.0",
|
| 13 |
"react-dom": "^19.1.0",
|
| 14 |
+
"react-markdown": "^9.0.1",
|
| 15 |
"react-router-dom": "^7.10.1",
|
| 16 |
+
"react-scripts": "^5.0.1",
|
| 17 |
"recharts": "^3.5.1",
|
| 18 |
"web-vitals": "^2.1.4"
|
| 19 |
},
|
src/app/components/chat/MessageList.tsx
CHANGED
|
@@ -12,6 +12,19 @@ type MessageListProps = {
|
|
| 12 |
onRetry?: () => void;
|
| 13 |
};
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
const MessageList = ({ messages, isLoading = false, error = null, onRetry }: MessageListProps) => {
|
| 16 |
const messagesEndRef = useRef<HTMLDivElement>(null);
|
| 17 |
|
|
@@ -32,9 +45,9 @@ const MessageList = ({ messages, isLoading = false, error = null, onRetry }: Mes
|
|
| 32 |
|
| 33 |
const getToolClasses = (message: ChatMessage) => {
|
| 34 |
if (message.role !== 'assistant' || !message.tool) return '';
|
| 35 |
-
|
| 36 |
const toolLower = message.tool.toLowerCase();
|
| 37 |
-
|
| 38 |
// Match tool names flexibly (case-insensitive, handles variations)
|
| 39 |
if (toolLower.includes('detect') && toolLower.includes('stance')) {
|
| 40 |
return 'border-l-4 border-blue-400 pl-3 bg-blue-50/30 dark:bg-blue-900/10';
|
|
@@ -45,16 +58,16 @@ const MessageList = ({ messages, isLoading = false, error = null, onRetry }: Mes
|
|
| 45 |
if (toolLower.includes('extract') && toolLower.includes('topic')) {
|
| 46 |
return 'border-l-4 border-emerald-400 pl-3 bg-emerald-50/30 dark:bg-emerald-900/10';
|
| 47 |
}
|
| 48 |
-
|
| 49 |
// Default styling for other tools
|
| 50 |
return 'border-l-4 border-teal-400 pl-3 bg-teal-50/30 dark:bg-teal-900/10';
|
| 51 |
};
|
| 52 |
|
| 53 |
const getToolLabel = (tool: string | null | undefined): string => {
|
| 54 |
if (!tool) return '';
|
| 55 |
-
|
| 56 |
const toolLower = tool.toLowerCase();
|
| 57 |
-
|
| 58 |
if (toolLower.includes('detect') && toolLower.includes('stance')) {
|
| 59 |
return 'Detect Stance';
|
| 60 |
}
|
|
@@ -64,13 +77,13 @@ const MessageList = ({ messages, isLoading = false, error = null, onRetry }: Mes
|
|
| 64 |
if (toolLower.includes('extract') && toolLower.includes('topic')) {
|
| 65 |
return 'Extract Topic';
|
| 66 |
}
|
| 67 |
-
|
| 68 |
// Return formatted tool name (capitalize first letter of each word)
|
| 69 |
-
return tool.split(/[\s_-]+/).map(word =>
|
| 70 |
word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
| 71 |
).join(' ');
|
| 72 |
};
|
| 73 |
-
|
| 74 |
return (
|
| 75 |
<div className="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
| 76 |
{messages.length === 0 && !isLoading && (
|
|
@@ -91,236 +104,190 @@ const MessageList = ({ messages, isLoading = false, error = null, onRetry }: Mes
|
|
| 91 |
</div>
|
| 92 |
)}
|
| 93 |
|
| 94 |
-
{messages.map((message, index) =>
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
>
|
| 99 |
<div
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
| 102 |
? 'bg-teal-500 text-white ml-12'
|
| 103 |
: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100 mr-12'
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
/>
|
| 113 |
<TranscriptToggle content={message.content} />
|
| 114 |
-
</div>
|
| 115 |
-
) : (
|
| 116 |
-
// Regular text message
|
| 117 |
-
<div>
|
| 118 |
-
{message.tool && message.role === 'assistant' && (
|
| 119 |
-
<div className="mb-2 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
| 120 |
-
{getToolLabel(message.tool)}
|
| 121 |
-
</div>
|
| 122 |
-
)}
|
| 123 |
-
|
| 124 |
-
{/* Format user message for detect stance tool */}
|
| 125 |
-
{message.tool &&
|
| 126 |
-
message.role === 'user' &&
|
| 127 |
-
message.tool.toLowerCase().includes('detect') &&
|
| 128 |
-
message.tool.toLowerCase().includes('stance') &&
|
| 129 |
-
message.content.includes('**Topic:**') ? (
|
| 130 |
-
<div className="space-y-2">
|
| 131 |
-
{message.content.split('\n').map((line, idx) => {
|
| 132 |
-
if (line.startsWith('**Topic:**')) {
|
| 133 |
-
const topicText = line.replace('**Topic:**', '').trim();
|
| 134 |
-
return (
|
| 135 |
-
<div key={idx}>
|
| 136 |
-
<span className="text-xs font-semibold opacity-90">Topic: </span>
|
| 137 |
-
<span className="text-sm">{topicText}</span>
|
| 138 |
-
</div>
|
| 139 |
-
);
|
| 140 |
-
} else if (line.startsWith('**Argument:**')) {
|
| 141 |
-
const argumentText = line.replace('**Argument:**', '').trim();
|
| 142 |
-
return (
|
| 143 |
-
<div key={idx}>
|
| 144 |
-
<span className="text-xs font-semibold opacity-90">Argument: </span>
|
| 145 |
-
<span className="text-sm">{argumentText}</span>
|
| 146 |
-
</div>
|
| 147 |
-
);
|
| 148 |
-
}
|
| 149 |
-
return null;
|
| 150 |
-
})}
|
| 151 |
-
</div>
|
| 152 |
-
) : message.role === 'user' ? (
|
| 153 |
-
<div className="whitespace-pre-wrap break-words">
|
| 154 |
-
{message.content}
|
| 155 |
-
</div>
|
| 156 |
-
) : null}
|
| 157 |
-
|
| 158 |
-
{/* Detect stance results with formatted display (only for assistant messages) */}
|
| 159 |
-
{message.role === 'assistant' &&
|
| 160 |
-
message.tool &&
|
| 161 |
-
message.tool.toLowerCase().includes('detect') &&
|
| 162 |
-
message.tool.toLowerCase().includes('stance') ? (
|
| 163 |
-
<div className="space-y-3">
|
| 164 |
-
{message.content.split('\n').map((line, idx) => {
|
| 165 |
-
if (line.startsWith('**Stance:**')) {
|
| 166 |
-
const stanceText = line.replace('**Stance:**', '').trim();
|
| 167 |
-
const isPro = stanceText.includes('PRO') || stanceText.toLowerCase().includes('positive');
|
| 168 |
-
return (
|
| 169 |
-
<div key={idx} className="flex items-center gap-2">
|
| 170 |
-
<span className="text-xs font-semibold text-gray-600 dark:text-gray-400">Stance:</span>
|
| 171 |
-
<span className={`px-2.5 py-1 rounded-full text-xs font-semibold ${
|
| 172 |
-
isPro
|
| 173 |
-
? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200'
|
| 174 |
-
: 'bg-rose-100 text-rose-800 dark:bg-rose-900/40 dark:text-rose-200'
|
| 175 |
-
}`}>
|
| 176 |
-
{stanceText}
|
| 177 |
-
</span>
|
| 178 |
-
</div>
|
| 179 |
-
);
|
| 180 |
-
} else if (line.startsWith('**Confidence:**')) {
|
| 181 |
-
const confidenceText = line.replace('**Confidence:**', '').trim();
|
| 182 |
-
// Extract numeric value from percentage string (e.g., "96.0%" -> 96.0)
|
| 183 |
-
const confidenceValue = parseFloat(confidenceText.replace('%', '')) || 0;
|
| 184 |
-
// Determine color based on confidence level
|
| 185 |
-
const getConfidenceColor = (value: number) => {
|
| 186 |
-
if (value >= 80) return 'bg-emerald-500';
|
| 187 |
-
if (value >= 60) return 'bg-yellow-500';
|
| 188 |
-
return 'bg-orange-500';
|
| 189 |
-
};
|
| 190 |
-
return (
|
| 191 |
-
<div key={idx} className="space-y-2">
|
| 192 |
-
<div className="flex items-center justify-between gap-2">
|
| 193 |
-
<span className="text-xs font-semibold text-gray-600 dark:text-gray-400">Confidence:</span>
|
| 194 |
-
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">{confidenceText}</span>
|
| 195 |
-
</div>
|
| 196 |
-
{/* Confidence temperature scale */}
|
| 197 |
-
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 overflow-hidden">
|
| 198 |
-
<div
|
| 199 |
-
className={`h-full transition-all duration-500 ${getConfidenceColor(confidenceValue)}`}
|
| 200 |
-
style={{ width: `${Math.min(confidenceValue, 100)}%` }}
|
| 201 |
-
/>
|
| 202 |
-
</div>
|
| 203 |
-
{/* Confidence level indicators */}
|
| 204 |
-
<div className="flex justify-between text-[10px] text-gray-400 dark:text-gray-500">
|
| 205 |
-
<span>Low</span>
|
| 206 |
-
<span>Medium</span>
|
| 207 |
-
<span>High</span>
|
| 208 |
-
</div>
|
| 209 |
-
</div>
|
| 210 |
-
);
|
| 211 |
-
} else if (line.startsWith('**Explanation:**')) {
|
| 212 |
-
// Extract explanation text (everything after "**Explanation:**\n")
|
| 213 |
-
const explanationParts = message.content.split('**Explanation:**\n');
|
| 214 |
-
const explanationText = explanationParts.length > 1 ? explanationParts[1] : '';
|
| 215 |
-
return (
|
| 216 |
-
<div key={idx} className="pt-2 border-t border-gray-200 dark:border-gray-700">
|
| 217 |
-
<div className="text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2">Explanation:</div>
|
| 218 |
-
<div className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap leading-relaxed">
|
| 219 |
-
{explanationText}
|
| 220 |
-
</div>
|
| 221 |
-
</div>
|
| 222 |
-
);
|
| 223 |
-
} else if (line.trim() === '') {
|
| 224 |
-
return null;
|
| 225 |
-
}
|
| 226 |
-
return null;
|
| 227 |
-
})}
|
| 228 |
-
</div>
|
| 229 |
-
) : message.role === 'assistant' ? (
|
| 230 |
-
<div className="whitespace-pre-wrap break-words">
|
| 231 |
-
{message.content}
|
| 232 |
-
</div>
|
| 233 |
-
) : null}
|
| 234 |
-
|
| 235 |
-
{/* Process pipeline for extract topic tool */}
|
| 236 |
-
{message.role === 'assistant' &&
|
| 237 |
-
message.tool &&
|
| 238 |
-
message.tool.toLowerCase().includes('extract') &&
|
| 239 |
-
message.tool.toLowerCase().includes('topic') &&
|
| 240 |
-
message.process && (
|
| 241 |
-
<div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
|
| 242 |
-
<div className="flex items-center gap-2 flex-wrap">
|
| 243 |
-
<span className="text-[10px] uppercase tracking-wide text-gray-400 dark:text-gray-500 font-medium">
|
| 244 |
-
Process:
|
| 245 |
-
</span>
|
| 246 |
-
{message.process.split('→').map((step, index, steps) => (
|
| 247 |
-
<React.Fragment key={index}>
|
| 248 |
-
<span className="px-2 py-0.5 text-[10px] bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 rounded font-medium">
|
| 249 |
-
{step.trim()}
|
| 250 |
-
</span>
|
| 251 |
-
{index < steps.length - 1 && (
|
| 252 |
-
<span className="text-gray-400 dark:text-gray-600 text-xs">→</span>
|
| 253 |
-
)}
|
| 254 |
-
</React.Fragment>
|
| 255 |
-
))}
|
| 256 |
-
</div>
|
| 257 |
-
</div>
|
| 258 |
-
)}
|
| 259 |
-
<div className="text-sm leading-relaxed break-words">
|
| 260 |
-
<ReactMarkdown
|
| 261 |
-
components={{
|
| 262 |
-
p: ({ node, ...props }) => (
|
| 263 |
-
<p {...props} className="whitespace-pre-wrap mb-2 last:mb-0" />
|
| 264 |
-
),
|
| 265 |
-
ul: ({ node, ...props }) => (
|
| 266 |
-
<ul
|
| 267 |
-
{...props}
|
| 268 |
-
className="list-disc ml-5 space-y-1 mb-2 last:mb-0"
|
| 269 |
-
/>
|
| 270 |
-
),
|
| 271 |
-
ol: ({ node, ...props }) => (
|
| 272 |
-
<ol
|
| 273 |
-
{...props}
|
| 274 |
-
className="list-decimal ml-5 space-y-1 mb-2 last:mb-0"
|
| 275 |
-
/>
|
| 276 |
-
),
|
| 277 |
-
li: ({ node, ...props }) => (
|
| 278 |
-
<li {...props} className="ml-1" />
|
| 279 |
-
),
|
| 280 |
-
}}
|
| 281 |
-
>
|
| 282 |
-
{message.content}
|
| 283 |
-
</ReactMarkdown>
|
| 284 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
>
|
| 296 |
-
|
| 297 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 298 |
)}
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 306 |
)}
|
| 307 |
-
|
| 308 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
</div>
|
| 310 |
-
)}
|
| 311 |
-
<div
|
| 312 |
-
className={`text-xs mt-1 ${
|
| 313 |
-
message.role === 'user'
|
| 314 |
-
? 'text-teal-100'
|
| 315 |
-
: 'text-gray-500 dark:text-gray-400'
|
| 316 |
-
}`}
|
| 317 |
-
>
|
| 318 |
-
{formatTime(message.timestamp)}
|
| 319 |
</div>
|
| 320 |
</div>
|
| 321 |
-
|
| 322 |
-
)
|
| 323 |
-
|
| 324 |
|
| 325 |
{isLoading && (
|
| 326 |
<div className="flex justify-start">
|
|
|
|
| 12 |
onRetry?: () => void;
|
| 13 |
};
|
| 14 |
|
| 15 |
+
/**
|
| 16 |
+
* Helper to determine if a message should use the specialized detection stance UI
|
| 17 |
+
*/
|
| 18 |
+
const isSpecializedStanceUI = (message: ChatMessage): boolean => {
|
| 19 |
+
const toolLower = message.tool?.toLowerCase() || '';
|
| 20 |
+
if (!toolLower.includes('detect') || !toolLower.includes('stance')) return false;
|
| 21 |
+
|
| 22 |
+
if (message.role === 'user') {
|
| 23 |
+
return message.content.includes('**Topic:**');
|
| 24 |
+
}
|
| 25 |
+
return message.role === 'assistant';
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
const MessageList = ({ messages, isLoading = false, error = null, onRetry }: MessageListProps) => {
|
| 29 |
const messagesEndRef = useRef<HTMLDivElement>(null);
|
| 30 |
|
|
|
|
| 45 |
|
| 46 |
const getToolClasses = (message: ChatMessage) => {
|
| 47 |
if (message.role !== 'assistant' || !message.tool) return '';
|
| 48 |
+
|
| 49 |
const toolLower = message.tool.toLowerCase();
|
| 50 |
+
|
| 51 |
// Match tool names flexibly (case-insensitive, handles variations)
|
| 52 |
if (toolLower.includes('detect') && toolLower.includes('stance')) {
|
| 53 |
return 'border-l-4 border-blue-400 pl-3 bg-blue-50/30 dark:bg-blue-900/10';
|
|
|
|
| 58 |
if (toolLower.includes('extract') && toolLower.includes('topic')) {
|
| 59 |
return 'border-l-4 border-emerald-400 pl-3 bg-emerald-50/30 dark:bg-emerald-900/10';
|
| 60 |
}
|
| 61 |
+
|
| 62 |
// Default styling for other tools
|
| 63 |
return 'border-l-4 border-teal-400 pl-3 bg-teal-50/30 dark:bg-teal-900/10';
|
| 64 |
};
|
| 65 |
|
| 66 |
const getToolLabel = (tool: string | null | undefined): string => {
|
| 67 |
if (!tool) return '';
|
| 68 |
+
|
| 69 |
const toolLower = tool.toLowerCase();
|
| 70 |
+
|
| 71 |
if (toolLower.includes('detect') && toolLower.includes('stance')) {
|
| 72 |
return 'Detect Stance';
|
| 73 |
}
|
|
|
|
| 77 |
if (toolLower.includes('extract') && toolLower.includes('topic')) {
|
| 78 |
return 'Extract Topic';
|
| 79 |
}
|
| 80 |
+
|
| 81 |
// Return formatted tool name (capitalize first letter of each word)
|
| 82 |
+
return tool.split(/[\s_-]+/).map(word =>
|
| 83 |
word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
| 84 |
).join(' ');
|
| 85 |
};
|
| 86 |
+
|
| 87 |
return (
|
| 88 |
<div className="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
| 89 |
{messages.length === 0 && !isLoading && (
|
|
|
|
| 104 |
</div>
|
| 105 |
)}
|
| 106 |
|
| 107 |
+
{messages.map((message, index) => {
|
| 108 |
+
const showSpecializedStance = isSpecializedStanceUI(message);
|
| 109 |
+
|
| 110 |
+
return (
|
|
|
|
| 111 |
<div
|
| 112 |
+
key={message.id}
|
| 113 |
+
className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
|
| 114 |
+
>
|
| 115 |
+
<div
|
| 116 |
+
className={`max-w-3xl px-4 py-3 rounded-2xl ${message.role === 'user'
|
| 117 |
? 'bg-teal-500 text-white ml-12'
|
| 118 |
: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100 mr-12'
|
| 119 |
+
}${getToolClasses(message) ? ' ' + getToolClasses(message) : ''}`}
|
| 120 |
+
>
|
| 121 |
+
{message.audioUrl ? (
|
| 122 |
+
<div>
|
| 123 |
+
<AudioPlayer
|
| 124 |
+
src={message.audioUrl}
|
| 125 |
+
autoPlay={message.role === 'assistant' && index === messages.length - 1}
|
| 126 |
+
/>
|
|
|
|
| 127 |
<TranscriptToggle content={message.content} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
</div>
|
| 129 |
+
) : (
|
| 130 |
+
<div className="space-y-3">
|
| 131 |
+
{message.tool && message.role === 'assistant' && (
|
| 132 |
+
<div className="mb-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
| 133 |
+
{getToolLabel(message.tool)}
|
| 134 |
+
</div>
|
| 135 |
+
)}
|
| 136 |
|
| 137 |
+
{showSpecializedStance ? (
|
| 138 |
+
<div className="space-y-3">
|
| 139 |
+
{message.role === 'user' ? (
|
| 140 |
+
<div className="space-y-2">
|
| 141 |
+
{message.content.split('\n').map((line, idx) => {
|
| 142 |
+
if (line.startsWith('**Topic:**')) {
|
| 143 |
+
const topicText = line.replace('**Topic:**', '').trim();
|
| 144 |
+
return (
|
| 145 |
+
<div key={idx}>
|
| 146 |
+
<span className="text-xs font-semibold opacity-90">Topic: </span>
|
| 147 |
+
<span className="text-sm">{topicText}</span>
|
| 148 |
+
</div>
|
| 149 |
+
);
|
| 150 |
+
} else if (line.startsWith('**Argument:**')) {
|
| 151 |
+
const argumentText = line.replace('**Argument:**', '').trim();
|
| 152 |
+
return (
|
| 153 |
+
<div key={idx}>
|
| 154 |
+
<span className="text-xs font-semibold opacity-90">Argument: </span>
|
| 155 |
+
<span className="text-sm">{argumentText}</span>
|
| 156 |
+
</div>
|
| 157 |
+
);
|
| 158 |
+
}
|
| 159 |
+
return null;
|
| 160 |
+
})}
|
| 161 |
+
</div>
|
| 162 |
+
) : (
|
| 163 |
+
<div className="space-y-3">
|
| 164 |
+
{message.content.split('\n').map((line, idx) => {
|
| 165 |
+
if (line.startsWith('**Stance:**')) {
|
| 166 |
+
const stanceText = line.replace('**Stance:**', '').trim();
|
| 167 |
+
const isPro = stanceText.includes('PRO') || stanceText.toLowerCase().includes('positive');
|
| 168 |
+
return (
|
| 169 |
+
<div key={idx} className="flex items-center gap-2">
|
| 170 |
+
<span className="text-xs font-semibold text-gray-600 dark:text-gray-400">Stance:</span>
|
| 171 |
+
<span className={`px-2.5 py-1 rounded-full text-xs font-semibold ${isPro
|
| 172 |
+
? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200'
|
| 173 |
+
: 'bg-rose-100 text-rose-800 dark:bg-rose-900/40 dark:text-rose-200'
|
| 174 |
+
}`}>
|
| 175 |
+
{stanceText}
|
| 176 |
+
</span>
|
| 177 |
+
</div>
|
| 178 |
+
);
|
| 179 |
+
} else if (line.startsWith('**Confidence:**')) {
|
| 180 |
+
const confidenceText = line.replace('**Confidence:**', '').trim();
|
| 181 |
+
const confidenceValue = parseFloat(confidenceText.replace('%', '')) || 0;
|
| 182 |
+
const getConfidenceColor = (value: number) => {
|
| 183 |
+
if (value >= 80) return 'bg-emerald-500';
|
| 184 |
+
if (value >= 60) return 'bg-yellow-500';
|
| 185 |
+
return 'bg-orange-500';
|
| 186 |
+
};
|
| 187 |
+
return (
|
| 188 |
+
<div key={idx} className="space-y-2">
|
| 189 |
+
<div className="flex items-center justify-between gap-2">
|
| 190 |
+
<span className="text-xs font-semibold text-gray-600 dark:text-gray-400">Confidence:</span>
|
| 191 |
+
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">{confidenceText}</span>
|
| 192 |
+
</div>
|
| 193 |
+
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-1.5 overflow-hidden">
|
| 194 |
+
<div
|
| 195 |
+
className={`h-full transition-all duration-500 ${getConfidenceColor(confidenceValue)}`}
|
| 196 |
+
style={{ width: `${Math.min(confidenceValue, 100)}%` }}
|
| 197 |
+
/>
|
| 198 |
+
</div>
|
| 199 |
+
</div>
|
| 200 |
+
);
|
| 201 |
+
} else if (line.startsWith('**Explanation:**')) {
|
| 202 |
+
const explanationParts = message.content.split('**Explanation:**\n');
|
| 203 |
+
const explanationText = explanationParts.length > 1 ? explanationParts[1] : '';
|
| 204 |
+
return (
|
| 205 |
+
<div key={idx} className="pt-2 border-t border-gray-200 dark:border-gray-700">
|
| 206 |
+
<div className="text-xs font-semibold text-gray-600 dark:text-gray-400 mb-1">Explanation:</div>
|
| 207 |
+
<div className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap leading-relaxed">
|
| 208 |
+
{explanationText}
|
| 209 |
+
</div>
|
| 210 |
+
</div>
|
| 211 |
+
);
|
| 212 |
+
}
|
| 213 |
+
return null;
|
| 214 |
+
})}
|
| 215 |
+
</div>
|
| 216 |
+
)}
|
| 217 |
+
</div>
|
| 218 |
+
) : (
|
| 219 |
+
<div className="text-sm leading-relaxed break-words">
|
| 220 |
+
<ReactMarkdown
|
| 221 |
+
components={{
|
| 222 |
+
p: ({ node, ...props }) => (
|
| 223 |
+
<p {...props} className="whitespace-pre-wrap mb-2 last:mb-0" />
|
| 224 |
+
),
|
| 225 |
+
ul: ({ node, ...props }) => (
|
| 226 |
+
<ul {...props} className="list-disc ml-5 space-y-1 mb-2 last:mb-0" />
|
| 227 |
+
),
|
| 228 |
+
ol: ({ node, ...props }) => (
|
| 229 |
+
<ol {...props} className="list-decimal ml-5 space-y-1 mb-2 last:mb-0" />
|
| 230 |
+
),
|
| 231 |
+
li: ({ node, ...props }) => (
|
| 232 |
+
<li {...props} className="ml-1" />
|
| 233 |
+
),
|
| 234 |
+
}}
|
| 235 |
>
|
| 236 |
+
{typeof message.content === 'string' ? message.content : ''}
|
| 237 |
+
</ReactMarkdown>
|
| 238 |
+
</div>
|
| 239 |
+
)}
|
| 240 |
+
|
| 241 |
+
{/* Process pipeline for extract topic tool */}
|
| 242 |
+
{message.role === 'assistant' &&
|
| 243 |
+
message.tool?.toLowerCase().includes('extract') &&
|
| 244 |
+
message.tool?.toLowerCase().includes('topic') &&
|
| 245 |
+
message.process && (
|
| 246 |
+
<div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
|
| 247 |
+
<div className="flex items-center gap-2 flex-wrap">
|
| 248 |
+
<span className="text-[10px] uppercase tracking-wide text-gray-400 dark:text-gray-500 font-medium">
|
| 249 |
+
Process:
|
| 250 |
+
</span>
|
| 251 |
+
{message.process.split('→').map((step, sIdx, steps) => (
|
| 252 |
+
<React.Fragment key={sIdx}>
|
| 253 |
+
<span className="px-2 py-0.5 text-[10px] bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 rounded font-medium">
|
| 254 |
+
{step.trim()}
|
| 255 |
+
</span>
|
| 256 |
+
{sIdx < steps.length - 1 && (
|
| 257 |
+
<span className="text-gray-400 dark:text-gray-600 text-xs">→</span>
|
| 258 |
+
)}
|
| 259 |
+
</React.Fragment>
|
| 260 |
+
))}
|
| 261 |
+
</div>
|
| 262 |
+
</div>
|
| 263 |
)}
|
| 264 |
+
|
| 265 |
+
{/* Stance info for generate argument tool */}
|
| 266 |
+
{message.role === 'assistant' &&
|
| 267 |
+
message.tool?.toLowerCase().includes('generate') &&
|
| 268 |
+
message.tool?.toLowerCase().includes('argument') &&
|
| 269 |
+
message.stance && (
|
| 270 |
+
<div className="mt-2 flex gap-2">
|
| 271 |
+
<span className={`px-2.5 py-0.5 text-[10px] rounded-full font-semibold uppercase tracking-wider ${message.stance === 'positive'
|
| 272 |
+
? 'bg-emerald-500 text-white'
|
| 273 |
+
: 'bg-rose-500 text-white'
|
| 274 |
+
}`}>
|
| 275 |
+
{message.stance} stance
|
| 276 |
+
</span>
|
| 277 |
+
</div>
|
| 278 |
)}
|
| 279 |
+
</div>
|
| 280 |
+
)}
|
| 281 |
+
<div
|
| 282 |
+
className={`text-[10px] mt-2 opacity-60 ${message.role === 'user' ? 'text-right opacity-80' : 'text-left'
|
| 283 |
+
}`}
|
| 284 |
+
>
|
| 285 |
+
{formatTime(message.timestamp)}
|
| 286 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
</div>
|
| 288 |
</div>
|
| 289 |
+
);
|
| 290 |
+
})}
|
|
|
|
| 291 |
|
| 292 |
{isLoading && (
|
| 293 |
<div className="flex justify-start">
|