mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-06-30 09:40:50 +02:00
UI for AI thoughts (#385)
This commit is contained in:
@ -46,27 +46,27 @@ logger = setup_logger()
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/search-intent")
|
@router.post("/search-intent")
|
||||||
def get_search_type(
|
def get_search_type(
|
||||||
question: QuestionRequest = Depends(), _: User = Depends(current_user)
|
question: QuestionRequest, _: User = Depends(current_user)
|
||||||
) -> HelperResponse:
|
) -> HelperResponse:
|
||||||
query = question.query
|
query = question.query
|
||||||
use_keyword = question.use_keyword if question.use_keyword is not None else False
|
use_keyword = question.use_keyword if question.use_keyword is not None else False
|
||||||
return recommend_search_flow(query, use_keyword)
|
return recommend_search_flow(query, use_keyword)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/query-validation")
|
@router.post("/query-validation")
|
||||||
def query_validation(
|
def query_validation(
|
||||||
question: QuestionRequest = Depends(), _: User = Depends(current_user)
|
question: QuestionRequest, _: User = Depends(current_user)
|
||||||
) -> QueryValidationResponse:
|
) -> QueryValidationResponse:
|
||||||
query = question.query
|
query = question.query
|
||||||
reasoning, answerable = get_query_answerability(query)
|
reasoning, answerable = get_query_answerability(query)
|
||||||
return QueryValidationResponse(reasoning=reasoning, answerable=answerable)
|
return QueryValidationResponse(reasoning=reasoning, answerable=answerable)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/stream-query-validation")
|
@router.post("/stream-query-validation")
|
||||||
def stream_query_validation(
|
def stream_query_validation(
|
||||||
question: QuestionRequest = Depends(), _: User = Depends(current_user)
|
question: QuestionRequest, _: User = Depends(current_user)
|
||||||
) -> StreamingResponse:
|
) -> StreamingResponse:
|
||||||
query = question.query
|
query = question.query
|
||||||
return StreamingResponse(
|
return StreamingResponse(
|
||||||
|
@ -29,6 +29,11 @@ const nextConfig = {
|
|||||||
destination: "http://127.0.0.1:8080/stream-direct-qa:params*", // Proxy to Backend
|
destination: "http://127.0.0.1:8080/stream-direct-qa:params*", // Proxy to Backend
|
||||||
permanent: true,
|
permanent: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
source: "/api/stream-query-validation:params*",
|
||||||
|
destination: "http://127.0.0.1:8080/stream-query-validation:params*", // Proxy to Backend
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
681
web/package-lock.json
generated
681
web/package-lock.json
generated
@ -22,6 +22,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
"react-icons": "^4.8.0",
|
"react-icons": "^4.8.0",
|
||||||
|
"react-loader-spinner": "^5.4.5",
|
||||||
"semver": "^7.5.4",
|
"semver": "^7.5.4",
|
||||||
"swr": "^2.1.5",
|
"swr": "^2.1.5",
|
||||||
"tailwindcss": "^3.3.1",
|
"tailwindcss": "^3.3.1",
|
||||||
@ -54,6 +55,453 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ampproject/remapping": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/gen-mapping": "^0.3.0",
|
||||||
|
"@jridgewell/trace-mapping": "^0.3.9"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame": {
|
||||||
|
"version": "7.22.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||||
|
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/highlight": "^7.22.13",
|
||||||
|
"chalk": "^2.4.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/chalk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^3.2.1",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"supports-color": "^5.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/color-convert": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/code-frame/node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/compat-data": {
|
||||||
|
"version": "7.22.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
|
||||||
|
"integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/core": {
|
||||||
|
"version": "7.22.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz",
|
||||||
|
"integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@ampproject/remapping": "^2.2.0",
|
||||||
|
"@babel/code-frame": "^7.22.10",
|
||||||
|
"@babel/generator": "^7.22.10",
|
||||||
|
"@babel/helper-compilation-targets": "^7.22.10",
|
||||||
|
"@babel/helper-module-transforms": "^7.22.9",
|
||||||
|
"@babel/helpers": "^7.22.11",
|
||||||
|
"@babel/parser": "^7.22.11",
|
||||||
|
"@babel/template": "^7.22.5",
|
||||||
|
"@babel/traverse": "^7.22.11",
|
||||||
|
"@babel/types": "^7.22.11",
|
||||||
|
"convert-source-map": "^1.7.0",
|
||||||
|
"debug": "^4.1.0",
|
||||||
|
"gensync": "^1.0.0-beta.2",
|
||||||
|
"json5": "^2.2.3",
|
||||||
|
"semver": "^6.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/babel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/core/node_modules/json5": {
|
||||||
|
"version": "2.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||||
|
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"json5": "lib/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/core/node_modules/semver": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/generator": {
|
||||||
|
"version": "7.22.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz",
|
||||||
|
"integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.10",
|
||||||
|
"@jridgewell/gen-mapping": "^0.3.2",
|
||||||
|
"@jridgewell/trace-mapping": "^0.3.17",
|
||||||
|
"jsesc": "^2.5.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-annotate-as-pure": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-compilation-targets": {
|
||||||
|
"version": "7.22.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz",
|
||||||
|
"integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/compat-data": "^7.22.9",
|
||||||
|
"@babel/helper-validator-option": "^7.22.5",
|
||||||
|
"browserslist": "^4.21.9",
|
||||||
|
"lru-cache": "^5.1.1",
|
||||||
|
"semver": "^6.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-environment-visitor": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-function-name": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/template": "^7.22.5",
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-hoist-variables": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-module-imports": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-module-transforms": {
|
||||||
|
"version": "7.22.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
|
||||||
|
"integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-environment-visitor": "^7.22.5",
|
||||||
|
"@babel/helper-module-imports": "^7.22.5",
|
||||||
|
"@babel/helper-simple-access": "^7.22.5",
|
||||||
|
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||||
|
"@babel/helper-validator-identifier": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-plugin-utils": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-simple-access": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-split-export-declaration": {
|
||||||
|
"version": "7.22.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||||
|
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-string-parser": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-validator-option": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helpers": {
|
||||||
|
"version": "7.22.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz",
|
||||||
|
"integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/template": "^7.22.5",
|
||||||
|
"@babel/traverse": "^7.22.11",
|
||||||
|
"@babel/types": "^7.22.11"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight": {
|
||||||
|
"version": "7.22.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz",
|
||||||
|
"integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-validator-identifier": "^7.22.5",
|
||||||
|
"chalk": "^2.4.2",
|
||||||
|
"js-tokens": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/chalk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^3.2.1",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"supports-color": "^5.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/color-convert": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/parser": {
|
||||||
|
"version": "7.22.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz",
|
||||||
|
"integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==",
|
||||||
|
"bin": {
|
||||||
|
"parser": "bin/babel-parser.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/plugin-syntax-jsx": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-plugin-utils": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.22.11",
|
"version": "7.22.11",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz",
|
||||||
@ -66,6 +514,83 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/template": {
|
||||||
|
"version": "7.22.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
|
||||||
|
"integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.22.5",
|
||||||
|
"@babel/parser": "^7.22.5",
|
||||||
|
"@babel/types": "^7.22.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse": {
|
||||||
|
"version": "7.22.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz",
|
||||||
|
"integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.22.10",
|
||||||
|
"@babel/generator": "^7.22.10",
|
||||||
|
"@babel/helper-environment-visitor": "^7.22.5",
|
||||||
|
"@babel/helper-function-name": "^7.22.5",
|
||||||
|
"@babel/helper-hoist-variables": "^7.22.5",
|
||||||
|
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||||
|
"@babel/parser": "^7.22.11",
|
||||||
|
"@babel/types": "^7.22.11",
|
||||||
|
"debug": "^4.1.0",
|
||||||
|
"globals": "^11.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse/node_modules/globals": {
|
||||||
|
"version": "11.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||||
|
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/types": {
|
||||||
|
"version": "7.22.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz",
|
||||||
|
"integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.22.5",
|
||||||
|
"@babel/helper-validator-identifier": "^7.22.5",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/is-prop-valid": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/memoize": "^0.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/memoize": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/stylis": {
|
||||||
|
"version": "0.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
|
||||||
|
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/unitless": {
|
||||||
|
"version": "0.7.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
|
||||||
|
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
@ -867,6 +1392,21 @@
|
|||||||
"dequal": "^2.0.3"
|
"dequal": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/babel-plugin-styled-components": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-annotate-as-pure": "^7.22.5",
|
||||||
|
"@babel/helper-module-imports": "^7.22.5",
|
||||||
|
"@babel/plugin-syntax-jsx": "^7.22.5",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"picomatch": "^2.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"styled-components": ">= 2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
@ -972,6 +1512,14 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/camelize": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001524",
|
"version": "1.0.30001524",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
|
||||||
@ -1080,6 +1628,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/convert-source-map": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@ -1094,6 +1648,24 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/css-color-keywords": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/css-to-react-native": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"camelize": "^1.0.0",
|
||||||
|
"css-color-keywords": "^1.0.0",
|
||||||
|
"postcss-value-parser": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
@ -1120,7 +1692,6 @@
|
|||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
},
|
},
|
||||||
@ -1999,6 +2570,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/gensync": {
|
||||||
|
"version": "1.0.0-beta.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||||
|
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||||
@ -2680,6 +3260,17 @@
|
|||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsesc": {
|
||||||
|
"version": "2.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||||
|
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
|
||||||
|
"bin": {
|
||||||
|
"jsesc": "bin/jsesc"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/json-buffer": {
|
"node_modules/json-buffer": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
@ -2871,8 +3462,7 @@
|
|||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/mz": {
|
"node_modules/mz": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
@ -3509,6 +4099,25 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-loader-spinner": {
|
||||||
|
"version": "5.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-5.4.5.tgz",
|
||||||
|
"integrity": "sha512-32f+sb/v2tnNfyvnCCOS4fpyVHsGXjSyNo6QLniHcaj1XjKLxx14L2z0h6szRugOL8IEJ+53GPwNAdbkDqmy4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"react-is": "^18.2.0",
|
||||||
|
"styled-components": "^5.3.5",
|
||||||
|
"styled-tools": "^1.7.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-loader-spinner/node_modules/react-is": {
|
||||||
|
"version": "18.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||||
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
@ -3705,6 +4314,11 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/shallowequal": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@ -3862,6 +4476,54 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/styled-components": {
|
||||||
|
"version": "5.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz",
|
||||||
|
"integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-module-imports": "^7.0.0",
|
||||||
|
"@babel/traverse": "^7.4.5",
|
||||||
|
"@emotion/is-prop-valid": "^1.1.0",
|
||||||
|
"@emotion/stylis": "^0.8.4",
|
||||||
|
"@emotion/unitless": "^0.7.4",
|
||||||
|
"babel-plugin-styled-components": ">= 1.12.0",
|
||||||
|
"css-to-react-native": "^3.0.0",
|
||||||
|
"hoist-non-react-statics": "^3.0.0",
|
||||||
|
"shallowequal": "^1.1.0",
|
||||||
|
"supports-color": "^5.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/styled-components"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 16.8.0",
|
||||||
|
"react-dom": ">= 16.8.0",
|
||||||
|
"react-is": ">= 16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/styled-components/node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/styled-components/node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/styled-jsx": {
|
"node_modules/styled-jsx": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
|
||||||
@ -3884,6 +4546,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/styled-tools": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/styled-tools/-/styled-tools-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-IjLxzM20RMwAsx8M1QoRlCG/Kmq8lKzCGyospjtSXt/BTIIcvgTonaxQAsKnBrsZNwhpHzO9ADx5te0h76ILVg=="
|
||||||
|
},
|
||||||
"node_modules/sucrase": {
|
"node_modules/sucrase": {
|
||||||
"version": "3.34.0",
|
"version": "3.34.0",
|
||||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
||||||
@ -4039,6 +4706,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/to-fast-properties": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
"react-icons": "^4.8.0",
|
"react-icons": "^4.8.0",
|
||||||
|
"react-loader-spinner": "^5.4.5",
|
||||||
"semver": "^7.5.4",
|
"semver": "^7.5.4",
|
||||||
"swr": "^2.1.5",
|
"swr": "^2.1.5",
|
||||||
"tailwindcss": "^3.3.1",
|
"tailwindcss": "^3.3.1",
|
||||||
@ -30,8 +31,8 @@
|
|||||||
"yup": "^1.1.1"
|
"yup": "^1.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "2.8.8",
|
|
||||||
"eslint": "^8.48.0",
|
"eslint": "^8.48.0",
|
||||||
"eslint-config-next": "^13.4.9"
|
"eslint-config-next": "^13.4.9",
|
||||||
|
"prettier": "2.8.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,12 @@ import {
|
|||||||
FiGlobe,
|
FiGlobe,
|
||||||
FiThumbsDown,
|
FiThumbsDown,
|
||||||
FiThumbsUp,
|
FiThumbsUp,
|
||||||
|
FiChevronDown,
|
||||||
|
FiChevronUp,
|
||||||
|
FiAlertCircle,
|
||||||
|
FiChevronRight,
|
||||||
|
FiChevronLeft,
|
||||||
|
FiAlertTriangle,
|
||||||
} from "react-icons/fi";
|
} from "react-icons/fi";
|
||||||
import { SiBookstack } from "react-icons/si";
|
import { SiBookstack } from "react-icons/si";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
@ -172,6 +178,34 @@ export const ChevronsDownIcon = ({
|
|||||||
return <FiChevronsDown size={size} className={className} />;
|
return <FiChevronsDown size={size} className={className} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ChevronUpIcon = ({
|
||||||
|
size = 16,
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <FiChevronUp size={size} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ChevronDownIcon = ({
|
||||||
|
size = 16,
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <FiChevronDown size={size} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ChevronRightIcon = ({
|
||||||
|
size = 16,
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <FiChevronRight size={size} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ChevronLeftIcon = ({
|
||||||
|
size = 16,
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <FiChevronLeft size={size} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
export const CheckmarkIcon = ({
|
export const CheckmarkIcon = ({
|
||||||
size = 16,
|
size = 16,
|
||||||
className = defaultTailwindCSS,
|
className = defaultTailwindCSS,
|
||||||
@ -179,6 +213,20 @@ export const CheckmarkIcon = ({
|
|||||||
return <FiCheck size={size} className={className} />;
|
return <FiCheck size={size} className={className} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const AlertIcon = ({
|
||||||
|
size = 16,
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <FiAlertCircle size={size} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TriangleAlertIcon = ({
|
||||||
|
size = 16,
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <FiAlertTriangle size={size} className={className} />;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// COMPANY LOGOS
|
// COMPANY LOGOS
|
||||||
//
|
//
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { getSourceIcon } from "../source";
|
|
||||||
import { LoadingAnimation } from "../Loading";
|
|
||||||
import { InfoIcon } from "../icons/icons";
|
|
||||||
import {
|
import {
|
||||||
DanswerDocument,
|
DanswerDocument,
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
Quote,
|
Quote,
|
||||||
FlowType,
|
FlowType,
|
||||||
SearchDefaultOverrides,
|
SearchDefaultOverrides,
|
||||||
|
ValidQuestionResponse,
|
||||||
} from "@/lib/search/interfaces";
|
} from "@/lib/search/interfaces";
|
||||||
import { QAFeedbackBlock } from "./QAFeedback";
|
import { QAFeedbackBlock } from "./QAFeedback";
|
||||||
import { DocumentDisplay } from "./DocumentDisplay";
|
import { DocumentDisplay } from "./DocumentDisplay";
|
||||||
|
import { ResponseSection, StatusOptions } from "./results/ResponseSection";
|
||||||
|
import { QuotesSection } from "./results/QuotesSection";
|
||||||
|
import { AnswerSection } from "./results/AnswerSection";
|
||||||
|
import {
|
||||||
|
getAIThoughtsIsOpenSavedValue,
|
||||||
|
setAIThoughtsIsOpenSavedValue,
|
||||||
|
} from "@/lib/search/aiThoughtUtils";
|
||||||
|
import { Grid, ThreeDots } from "react-loader-spinner";
|
||||||
|
|
||||||
const removeDuplicateDocs = (documents: DanswerDocument[]) => {
|
const removeDuplicateDocs = (documents: DanswerDocument[]) => {
|
||||||
const seen = new Set<string>();
|
const seen = new Set<string>();
|
||||||
@ -26,15 +34,25 @@ const removeDuplicateDocs = (documents: DanswerDocument[]) => {
|
|||||||
|
|
||||||
interface SearchResultsDisplayProps {
|
interface SearchResultsDisplayProps {
|
||||||
searchResponse: SearchResponse | null;
|
searchResponse: SearchResponse | null;
|
||||||
|
validQuestionResponse: ValidQuestionResponse;
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
defaultOverrides: SearchDefaultOverrides;
|
defaultOverrides: SearchDefaultOverrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
||||||
searchResponse,
|
searchResponse,
|
||||||
|
validQuestionResponse,
|
||||||
isFetching,
|
isFetching,
|
||||||
defaultOverrides,
|
defaultOverrides,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isAIThoughtsOpen, setIsAIThoughtsOpen] = React.useState<boolean>(
|
||||||
|
getAIThoughtsIsOpenSavedValue()
|
||||||
|
);
|
||||||
|
const handleAIThoughtToggle = (newAIThoughtsOpenValue: boolean) => {
|
||||||
|
setAIThoughtsIsOpenSavedValue(newAIThoughtsOpenValue);
|
||||||
|
setIsAIThoughtsOpen(newAIThoughtsOpenValue);
|
||||||
|
};
|
||||||
|
|
||||||
if (!searchResponse) {
|
if (!searchResponse) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -45,7 +63,16 @@ export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<LoadingAnimation />
|
<ThreeDots
|
||||||
|
height="30"
|
||||||
|
width="40"
|
||||||
|
color="#3b82f6"
|
||||||
|
ariaLabel="grid-loading"
|
||||||
|
radius="12.5"
|
||||||
|
wrapperStyle={{}}
|
||||||
|
wrapperClass=""
|
||||||
|
visible={true}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -70,82 +97,64 @@ export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
|||||||
searchResponse.suggestedFlowType === FlowType.QUESTION_ANSWER ||
|
searchResponse.suggestedFlowType === FlowType.QUESTION_ANSWER ||
|
||||||
defaultOverrides.forceDisplayQA;
|
defaultOverrides.forceDisplayQA;
|
||||||
|
|
||||||
let answerDisplay = <LoadingAnimation text="" size="text-sm" />;
|
let questionValidityCheckStatus: StatusOptions = "in-progress";
|
||||||
if (error) {
|
if (validQuestionResponse.answerable) {
|
||||||
answerDisplay = (
|
questionValidityCheckStatus = "success";
|
||||||
<div className="flex">
|
} else if (validQuestionResponse.answerable === false) {
|
||||||
<InfoIcon
|
questionValidityCheckStatus = "failed";
|
||||||
size={20}
|
|
||||||
className="text-red-500 my-auto flex flex-shrink-0"
|
|
||||||
/>
|
|
||||||
<div className="text-red-500 text-sm my-auto ml-1">{error}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else if (answer) {
|
|
||||||
answerDisplay = <p className="mb-4">{answer}</p>;
|
|
||||||
} else if (!isFetching) {
|
|
||||||
answerDisplay = (
|
|
||||||
<div className="text-sm my-auto text-gray-300">Information not found</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{shouldDisplayQA && (
|
{shouldDisplayQA && (
|
||||||
<div className="min-h-[14rem]">
|
<div className="min-h-[16rem] p-4 border-2 rounded-md border-gray-700 relative">
|
||||||
<div className="p-4 border-2 rounded-md border-gray-700">
|
<div>
|
||||||
<div className="flex mb-1">
|
<div className="flex mb-1">
|
||||||
<h2 className="text font-bold my-auto">AI Answer</h2>
|
<h2 className="text font-bold my-auto mb-1 w-full">AI Answer</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-2 w-full">
|
||||||
|
<ResponseSection
|
||||||
|
status={questionValidityCheckStatus}
|
||||||
|
header={
|
||||||
|
validQuestionResponse.answerable === null ? (
|
||||||
|
<div className="flex ml-2">Evaluating question...</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex ml-2">AI thoughts</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
body={<div>{validQuestionResponse.reasoning}</div>}
|
||||||
|
desiredOpenStatus={isAIThoughtsOpen}
|
||||||
|
setDesiredOpenStatus={handleAIThoughtToggle}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-2 pt-1 border-t border-gray-700 w-full">
|
||||||
|
<AnswerSection
|
||||||
|
answer={answer}
|
||||||
|
quotes={quotes}
|
||||||
|
error={error}
|
||||||
|
isAnswerable={validQuestionResponse.answerable}
|
||||||
|
isFetching={isFetching}
|
||||||
|
aiThoughtsIsOpen={isAIThoughtsOpen}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{answerDisplay}
|
|
||||||
|
|
||||||
{quotes !== null && answer && (
|
{quotes !== null && answer && (
|
||||||
<>
|
<div className="pt-1 border-t border-gray-700 w-full">
|
||||||
<h2 className="text-sm font-bold">Sources</h2>
|
<QuotesSection
|
||||||
{isFetching && dedupedQuotes.length === 0 ? (
|
quotes={dedupedQuotes}
|
||||||
<LoadingAnimation text="Finding quotes" size="text-sm" />
|
isFetching={isFetching}
|
||||||
) : (
|
isAnswerable={validQuestionResponse.answerable}
|
||||||
<div className="flex flex-wrap">
|
|
||||||
{dedupedQuotes.length > 0 ? (
|
|
||||||
dedupedQuotes.map((quoteInfo) => (
|
|
||||||
<a
|
|
||||||
key={quoteInfo.document_id}
|
|
||||||
className="p-2 ml-1 mt-2 border border-gray-800 rounded-lg text-sm flex max-w-[280px] hover:bg-gray-800"
|
|
||||||
href={quoteInfo.link || undefined}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{getSourceIcon(quoteInfo.source_type, 20)}
|
|
||||||
<p className="truncate break-all ml-2">
|
|
||||||
{quoteInfo.semantic_identifier ||
|
|
||||||
quoteInfo.document_id}
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<div className="flex">
|
|
||||||
<InfoIcon
|
|
||||||
size={20}
|
|
||||||
className="text-red-500 my-auto flex flex-shrink-0"
|
|
||||||
/>
|
/>
|
||||||
<div className="text-red-500 text-sm my-auto ml-1">
|
|
||||||
Did not find any exact quotes to support the above
|
|
||||||
answer.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{searchResponse.queryEventId !== null && (
|
{searchResponse.queryEventId !== null && (
|
||||||
<div className="ml-auto mt-auto">
|
<div className="absolute right-3 bottom-3">
|
||||||
<QAFeedbackBlock
|
<QAFeedbackBlock queryId={searchResponse.queryEventId} />
|
||||||
queryId={searchResponse.queryEventId}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
SearchType,
|
SearchType,
|
||||||
SearchDefaultOverrides,
|
SearchDefaultOverrides,
|
||||||
SearchRequestOverrides,
|
SearchRequestOverrides,
|
||||||
|
ValidQuestionResponse,
|
||||||
} from "@/lib/search/interfaces";
|
} from "@/lib/search/interfaces";
|
||||||
import { searchRequestStreamed } from "@/lib/search/streamingQa";
|
import { searchRequestStreamed } from "@/lib/search/streamingQa";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
@ -22,12 +23,19 @@ import { SearchHelper } from "./SearchHelper";
|
|||||||
import { CancellationToken, cancellable } from "@/lib/search/cancellable";
|
import { CancellationToken, cancellable } from "@/lib/search/cancellable";
|
||||||
import { NEXT_PUBLIC_DISABLE_STREAMING } from "@/lib/constants";
|
import { NEXT_PUBLIC_DISABLE_STREAMING } from "@/lib/constants";
|
||||||
import { searchRequest } from "@/lib/search/qa";
|
import { searchRequest } from "@/lib/search/qa";
|
||||||
|
import { useObjectState } from "@/lib/hooks";
|
||||||
|
import { questionValidationStreamed } from "@/lib/search/streamingQuestionValidation";
|
||||||
|
|
||||||
const SEARCH_DEFAULT_OVERRIDES_START: SearchDefaultOverrides = {
|
const SEARCH_DEFAULT_OVERRIDES_START: SearchDefaultOverrides = {
|
||||||
forceDisplayQA: false,
|
forceDisplayQA: false,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const VALID_QUESTION_RESPONSE_DEFAULT: ValidQuestionResponse = {
|
||||||
|
reasoning: null,
|
||||||
|
answerable: null,
|
||||||
|
};
|
||||||
|
|
||||||
interface SearchSectionProps {
|
interface SearchSectionProps {
|
||||||
connectors: Connector<any>[];
|
connectors: Connector<any>[];
|
||||||
defaultSearchType: SearchType;
|
defaultSearchType: SearchType;
|
||||||
@ -46,6 +54,9 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
);
|
);
|
||||||
const [isFetching, setIsFetching] = useState(false);
|
const [isFetching, setIsFetching] = useState(false);
|
||||||
|
|
||||||
|
const [validQuestionResponse, setValidQuestionResponse] =
|
||||||
|
useObjectState<ValidQuestionResponse>(VALID_QUESTION_RESPONSE_DEFAULT);
|
||||||
|
|
||||||
// Filters
|
// Filters
|
||||||
const [sources, setSources] = useState<Source[]>([]);
|
const [sources, setSources] = useState<Source[]>([]);
|
||||||
|
|
||||||
@ -116,11 +127,12 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
|
|
||||||
setIsFetching(true);
|
setIsFetching(true);
|
||||||
setSearchResponse(initialSearchResponse);
|
setSearchResponse(initialSearchResponse);
|
||||||
|
setValidQuestionResponse(VALID_QUESTION_RESPONSE_DEFAULT);
|
||||||
|
|
||||||
const searchFn = NEXT_PUBLIC_DISABLE_STREAMING
|
const searchFn = NEXT_PUBLIC_DISABLE_STREAMING
|
||||||
? searchRequest
|
? searchRequest
|
||||||
: searchRequestStreamed;
|
: searchRequestStreamed;
|
||||||
await searchFn({
|
const searchFnArgs = {
|
||||||
query,
|
query,
|
||||||
sources,
|
sources,
|
||||||
updateCurrentAnswer: cancellable({
|
updateCurrentAnswer: cancellable({
|
||||||
@ -153,7 +165,17 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
}),
|
}),
|
||||||
selectedSearchType: searchType ?? selectedSearchType,
|
selectedSearchType: searchType ?? selectedSearchType,
|
||||||
offset: offset ?? defaultOverrides.offset,
|
offset: offset ?? defaultOverrides.offset,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const questionValidationArgs = {
|
||||||
|
query,
|
||||||
|
update: setValidQuestionResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
searchFn(searchFnArgs),
|
||||||
|
questionValidationStreamed(questionValidationArgs),
|
||||||
|
]);
|
||||||
|
|
||||||
setIsFetching(false);
|
setIsFetching(false);
|
||||||
};
|
};
|
||||||
@ -213,6 +235,7 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<SearchResultsDisplay
|
<SearchResultsDisplay
|
||||||
searchResponse={searchResponse}
|
searchResponse={searchResponse}
|
||||||
|
validQuestionResponse={validQuestionResponse}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
defaultOverrides={defaultOverrides}
|
defaultOverrides={defaultOverrides}
|
||||||
/>
|
/>
|
||||||
|
84
web/src/components/search/results/AnswerSection.tsx
Normal file
84
web/src/components/search/results/AnswerSection.tsx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { Quote } from "@/lib/search/interfaces";
|
||||||
|
import { ResponseSection, StatusOptions } from "./ResponseSection";
|
||||||
|
|
||||||
|
interface AnswerSectionProps {
|
||||||
|
answer: string | null;
|
||||||
|
quotes: Quote[] | null;
|
||||||
|
error: string | null;
|
||||||
|
isAnswerable: boolean | null;
|
||||||
|
isFetching: boolean;
|
||||||
|
aiThoughtsIsOpen: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnswerHeader = ({
|
||||||
|
answer,
|
||||||
|
error,
|
||||||
|
quotes,
|
||||||
|
isAnswerable,
|
||||||
|
isFetching,
|
||||||
|
}: AnswerSectionProps) => {
|
||||||
|
if (error) {
|
||||||
|
return <>Error while building answer</>;
|
||||||
|
} else if ((answer && quotes !== null) || !isFetching) {
|
||||||
|
if (isAnswerable === false) {
|
||||||
|
return <>Best effort AI answer</>;
|
||||||
|
}
|
||||||
|
return <>AI answer</>;
|
||||||
|
}
|
||||||
|
if (isAnswerable === false) {
|
||||||
|
return <>Building best effort AI answer...</>;
|
||||||
|
}
|
||||||
|
return <>Building answer...</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AnswerBody = ({ answer, error, isFetching }: AnswerSectionProps) => {
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<div className="text-red-500 my-auto ml-1">{error}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (answer) {
|
||||||
|
return <p className="">{answer}</p>;
|
||||||
|
} else if (!isFetching) {
|
||||||
|
return <div className="text-gray-300">Information not found</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AnswerSection = (props: AnswerSectionProps) => {
|
||||||
|
let status = "in-progress" as StatusOptions;
|
||||||
|
if (props.error) {
|
||||||
|
status = "failed";
|
||||||
|
}
|
||||||
|
// if AI thoughts is visible, don't mark this as a success until that section
|
||||||
|
// is complete
|
||||||
|
else if (!props.aiThoughtsIsOpen || props.isAnswerable !== null) {
|
||||||
|
if (props.isAnswerable === false) {
|
||||||
|
status = "warning";
|
||||||
|
} else if ((props.quotes !== null && props.answer) || !props.isFetching) {
|
||||||
|
status = "success";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ResponseSection
|
||||||
|
status={status}
|
||||||
|
header={
|
||||||
|
<div className="flex">
|
||||||
|
<div className="ml-2">{<AnswerHeader {...props} />}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
body={
|
||||||
|
<div className="">
|
||||||
|
<AnswerBody {...props} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
desiredOpenStatus={
|
||||||
|
props.aiThoughtsIsOpen ? props.isAnswerable !== null : true
|
||||||
|
}
|
||||||
|
isNotControllable={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
82
web/src/components/search/results/QuotesSection.tsx
Normal file
82
web/src/components/search/results/QuotesSection.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { Quote } from "@/lib/search/interfaces";
|
||||||
|
import { ResponseSection, StatusOptions } from "./ResponseSection";
|
||||||
|
import { getSourceIcon } from "@/components/source";
|
||||||
|
|
||||||
|
interface QuotesSectionProps {
|
||||||
|
quotes: Quote[] | null;
|
||||||
|
isAnswerable: boolean | null;
|
||||||
|
isFetching: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QuotesHeader = ({ quotes, isFetching }: QuotesSectionProps) => {
|
||||||
|
if ((!quotes || quotes.length === 0) && isFetching) {
|
||||||
|
return <>Extracting quotes...</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!quotes || quotes.length === 0) {
|
||||||
|
return <>No quotes found</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>Quotes</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const QuotesBody = ({ quotes, isFetching }: QuotesSectionProps) => {
|
||||||
|
if (!quotes && isFetching) {
|
||||||
|
// height of quotes section to avoid extra "jumps" from the quotes loading
|
||||||
|
return <div className="h-[42px]"></div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFetching && (!quotes || !quotes.length)) {
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<div className="text-red-500 text-sm my-auto">
|
||||||
|
Did not find any exact quotes to support the above answer.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap">
|
||||||
|
{quotes!.map((quoteInfo) => (
|
||||||
|
<a
|
||||||
|
key={quoteInfo.document_id}
|
||||||
|
className="p-2 mr-1 border border-gray-800 rounded-lg text-sm flex max-w-[280px] hover:bg-gray-800 w-fit"
|
||||||
|
href={quoteInfo.link || undefined}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{getSourceIcon(quoteInfo.source_type, 20)}
|
||||||
|
<p className="truncate break-all ml-2 mr-1">
|
||||||
|
{quoteInfo.semantic_identifier || quoteInfo.document_id}
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const QuotesSection = (props: QuotesSectionProps) => {
|
||||||
|
let status: StatusOptions = "in-progress";
|
||||||
|
if (!props.isFetching) {
|
||||||
|
if (props.quotes && props.quotes.length > 0) {
|
||||||
|
if (props.isAnswerable === false) {
|
||||||
|
status = "warning";
|
||||||
|
} else {
|
||||||
|
status = "success";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = "failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ResponseSection
|
||||||
|
status={status}
|
||||||
|
header={<div className="ml-2">{<QuotesHeader {...props} />}</div>}
|
||||||
|
body={<QuotesBody {...props} />}
|
||||||
|
desiredOpenStatus={true}
|
||||||
|
isNotControllable={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
101
web/src/components/search/results/ResponseSection.tsx
Normal file
101
web/src/components/search/results/ResponseSection.tsx
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import {
|
||||||
|
AlertIcon,
|
||||||
|
CheckmarkIcon,
|
||||||
|
ChevronDownIcon,
|
||||||
|
ChevronLeftIcon,
|
||||||
|
TriangleAlertIcon,
|
||||||
|
} from "@/components/icons/icons";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Grid } from "react-loader-spinner";
|
||||||
|
|
||||||
|
export type StatusOptions = "in-progress" | "failed" | "warning" | "success";
|
||||||
|
|
||||||
|
interface ResponseSectionProps {
|
||||||
|
header: JSX.Element | string;
|
||||||
|
body: JSX.Element | string;
|
||||||
|
status: StatusOptions;
|
||||||
|
desiredOpenStatus: boolean;
|
||||||
|
setDesiredOpenStatus?: (isOpen: boolean) => void;
|
||||||
|
isNotControllable?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ResponseSection = ({
|
||||||
|
header,
|
||||||
|
body,
|
||||||
|
status,
|
||||||
|
desiredOpenStatus,
|
||||||
|
setDesiredOpenStatus,
|
||||||
|
isNotControllable,
|
||||||
|
}: ResponseSectionProps) => {
|
||||||
|
const [isOpen, setIsOpen] = useState<boolean | null>(null);
|
||||||
|
|
||||||
|
let icon = null;
|
||||||
|
if (status === "in-progress") {
|
||||||
|
icon = (
|
||||||
|
<div className="m-auto">
|
||||||
|
<Grid
|
||||||
|
height="12"
|
||||||
|
width="12"
|
||||||
|
color="#3b82f6"
|
||||||
|
ariaLabel="grid-loading"
|
||||||
|
radius="12.5"
|
||||||
|
wrapperStyle={{}}
|
||||||
|
wrapperClass=""
|
||||||
|
visible={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (status === "failed") {
|
||||||
|
icon = <AlertIcon size={16} className="text-red-500" />;
|
||||||
|
}
|
||||||
|
if (status === "success") {
|
||||||
|
icon = <CheckmarkIcon size={16} className="text-green-600" />;
|
||||||
|
}
|
||||||
|
if (status === "warning") {
|
||||||
|
icon = <TriangleAlertIcon size={16} className="text-yellow-600" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use `desiredOpenStatus` if user has not clicked to open/close, otherwise use
|
||||||
|
// `isOpen` state
|
||||||
|
const finalIsOpen = isOpen !== null ? isOpen : desiredOpenStatus;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
flex
|
||||||
|
my-1
|
||||||
|
p-1
|
||||||
|
rounded
|
||||||
|
select-none
|
||||||
|
${isNotControllable ? "" : "hover:bg-gray-800 cursor-pointer"}`}
|
||||||
|
onClick={() => {
|
||||||
|
if (!isNotControllable) {
|
||||||
|
if (isOpen === null) {
|
||||||
|
setIsOpen(!desiredOpenStatus);
|
||||||
|
} else {
|
||||||
|
setIsOpen(!isOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (setDesiredOpenStatus) {
|
||||||
|
setDesiredOpenStatus(!desiredOpenStatus);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="my-auto">{icon}</div>
|
||||||
|
<div className="my-auto text-sm text-gray-200 italic">{header}</div>
|
||||||
|
|
||||||
|
{!isNotControllable && (
|
||||||
|
<div className="ml-auto">
|
||||||
|
{finalIsOpen ? (
|
||||||
|
<ChevronDownIcon size={16} className="text-gray-400" />
|
||||||
|
) : (
|
||||||
|
<ChevronLeftIcon size={16} className="text-gray-400" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{finalIsOpen && <div className="pb-1 mx-2 text-sm mb-1">{body}</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,7 @@
|
|||||||
import { Credential, DocumentBoostStatus } from "@/lib/types";
|
import { Credential, DocumentBoostStatus } from "@/lib/types";
|
||||||
import useSWR, { mutate, useSWRConfig } from "swr";
|
import useSWR, { mutate, useSWRConfig } from "swr";
|
||||||
import { fetcher } from "./fetcher";
|
import { fetcher } from "./fetcher";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
const CREDENTIAL_URL = "/api/manage/admin/credential";
|
const CREDENTIAL_URL = "/api/manage/admin/credential";
|
||||||
|
|
||||||
@ -14,8 +15,6 @@ export const usePublicCredentials = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const MOST_REACTED_DOCS_URL = "/api/manage/doc-boosts";
|
|
||||||
|
|
||||||
const buildReactedDocsUrl = (ascending: boolean, limit: number) => {
|
const buildReactedDocsUrl = (ascending: boolean, limit: number) => {
|
||||||
return `/api/manage/admin/doc-boosts?ascending=${ascending}&limit=${limit}`;
|
return `/api/manage/admin/doc-boosts?ascending=${ascending}&limit=${limit}`;
|
||||||
};
|
};
|
||||||
@ -32,3 +31,18 @@ export const useMostReactedToDocuments = (
|
|||||||
refreshDocs: () => mutate(url),
|
refreshDocs: () => mutate(url),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useObjectState = <T>(
|
||||||
|
initialValue: T
|
||||||
|
): [T, (update: Partial<T>) => void] => {
|
||||||
|
const [state, setState] = useState<T>(initialValue);
|
||||||
|
const set = (update: Partial<T>) => {
|
||||||
|
setState((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
...update,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return [state, set];
|
||||||
|
};
|
||||||
|
16
web/src/lib/search/aiThoughtUtils.ts
Normal file
16
web/src/lib/search/aiThoughtUtils.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const IS_AI_THOUGHTS_OPEN_LOCAL_STORAGE_KEY = "isAIThoughtsOpen";
|
||||||
|
|
||||||
|
export const getAIThoughtsIsOpenSavedValue = () => {
|
||||||
|
// wrapping in `try / catch` to avoid SSR errors during development
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
localStorage.getItem(IS_AI_THOUGHTS_OPEN_LOCAL_STORAGE_KEY) === "true"
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setAIThoughtsIsOpenSavedValue = (isOpen: boolean) => {
|
||||||
|
localStorage.setItem(IS_AI_THOUGHTS_OPEN_LOCAL_STORAGE_KEY, String(isOpen));
|
||||||
|
};
|
@ -12,6 +12,10 @@ export const SearchType = {
|
|||||||
};
|
};
|
||||||
export type SearchType = (typeof SearchType)[keyof typeof SearchType];
|
export type SearchType = (typeof SearchType)[keyof typeof SearchType];
|
||||||
|
|
||||||
|
export interface AnswerPiece {
|
||||||
|
answer_piece: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Quote {
|
export interface Quote {
|
||||||
quote: string;
|
quote: string;
|
||||||
document_id: string;
|
document_id: string;
|
||||||
@ -69,3 +73,8 @@ export interface SearchRequestOverrides {
|
|||||||
searchType?: SearchType;
|
searchType?: SearchType;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ValidQuestionResponse {
|
||||||
|
answerable: boolean | null;
|
||||||
|
reasoning: string | null;
|
||||||
|
}
|
||||||
|
62
web/src/lib/search/streamingQuestionValidation.ts
Normal file
62
web/src/lib/search/streamingQuestionValidation.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { AnswerPiece, ValidQuestionResponse } from "./interfaces";
|
||||||
|
import { processRawChunkString } from "./streamingUtils";
|
||||||
|
|
||||||
|
export interface QuestionValidationArgs {
|
||||||
|
query: string;
|
||||||
|
update: (update: Partial<ValidQuestionResponse>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const questionValidationStreamed = async <T>({
|
||||||
|
query,
|
||||||
|
update,
|
||||||
|
}: QuestionValidationArgs) => {
|
||||||
|
const response = await fetch("/api/stream-query-validation", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
query,
|
||||||
|
collection: "danswer_index",
|
||||||
|
use_keyword: null,
|
||||||
|
filters: null,
|
||||||
|
offset: null,
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const reader = response.body?.getReader();
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
|
||||||
|
let reasoning = "";
|
||||||
|
let previousPartialChunk: string | null = null;
|
||||||
|
while (true) {
|
||||||
|
const rawChunk = await reader?.read();
|
||||||
|
if (!rawChunk) {
|
||||||
|
throw new Error("Unable to process chunk");
|
||||||
|
}
|
||||||
|
const { done, value } = rawChunk;
|
||||||
|
if (done) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [completedChunks, partialChunk] = processRawChunkString<
|
||||||
|
AnswerPiece | ValidQuestionResponse
|
||||||
|
>(decoder.decode(value, { stream: true }), previousPartialChunk);
|
||||||
|
if (!completedChunks.length && !partialChunk) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previousPartialChunk = partialChunk as string | null;
|
||||||
|
|
||||||
|
completedChunks.forEach((chunk) => {
|
||||||
|
if (Object.hasOwn(chunk, "answer_piece")) {
|
||||||
|
reasoning += (chunk as AnswerPiece).answer_piece;
|
||||||
|
update({
|
||||||
|
reasoning,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.hasOwn(chunk, "answerable")) {
|
||||||
|
update({ answerable: (chunk as ValidQuestionResponse).answerable });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
47
web/src/lib/search/streamingUtils.ts
Normal file
47
web/src/lib/search/streamingUtils.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
type NonEmptyObject = { [k: string]: any };
|
||||||
|
|
||||||
|
const processSingleChunk = <T extends NonEmptyObject>(
|
||||||
|
chunk: string,
|
||||||
|
currPartialChunk: string | null
|
||||||
|
): [T | null, string | null] => {
|
||||||
|
const completeChunk = (currPartialChunk || "") + chunk;
|
||||||
|
try {
|
||||||
|
// every complete chunk should be valid JSON
|
||||||
|
const chunkJson = JSON.parse(completeChunk);
|
||||||
|
return [chunkJson, null];
|
||||||
|
} catch (err) {
|
||||||
|
// if it's not valid JSON, then it's probably an incomplete chunk
|
||||||
|
return [null, completeChunk];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const processRawChunkString = <T extends NonEmptyObject>(
|
||||||
|
rawChunkString: string,
|
||||||
|
previousPartialChunk: string | null
|
||||||
|
): [T[], string | null] => {
|
||||||
|
/* This is required because, in practice, we see that nginx does not send over
|
||||||
|
each chunk one at a time even with buffering turned off. Instead,
|
||||||
|
chunks are sometimes in batches or are sometimes incomplete */
|
||||||
|
if (!rawChunkString) {
|
||||||
|
return [[], null];
|
||||||
|
}
|
||||||
|
const chunkSections = rawChunkString
|
||||||
|
.split("\n")
|
||||||
|
.filter((chunk) => chunk.length > 0);
|
||||||
|
let parsedChunkSections: T[] = [];
|
||||||
|
let currPartialChunk = previousPartialChunk;
|
||||||
|
chunkSections.forEach((chunk) => {
|
||||||
|
const [processedChunk, partialChunk] = processSingleChunk<T>(
|
||||||
|
chunk,
|
||||||
|
currPartialChunk
|
||||||
|
);
|
||||||
|
if (processedChunk) {
|
||||||
|
parsedChunkSections.push(processedChunk);
|
||||||
|
currPartialChunk = null;
|
||||||
|
} else {
|
||||||
|
currPartialChunk = partialChunk;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return [parsedChunkSections, currPartialChunk];
|
||||||
|
};
|
Reference in New Issue
Block a user