mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-09-20 21:33:56 +02:00
@@ -106,6 +106,9 @@ def json_chat_processor(question: str, documents: list[str]) -> list[dict[str, s
|
|||||||
'Start by reading the following documents and responding with "Acknowledged".'
|
'Start by reading the following documents and responding with "Acknowledged".'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
complete_answer_not_found_response = (
|
||||||
|
'{"answer": "' + UNCERTAINTY_PAT + '", "quotes": []}'
|
||||||
|
)
|
||||||
task_msg = (
|
task_msg = (
|
||||||
"Now answer the next user query based on documents above and quote relevant sections.\n"
|
"Now answer the next user query based on documents above and quote relevant sections.\n"
|
||||||
"Respond with a JSON containing the answer and up to three most relevant quotes from the documents.\n"
|
"Respond with a JSON containing the answer and up to three most relevant quotes from the documents.\n"
|
||||||
@@ -113,7 +116,7 @@ def json_chat_processor(question: str, documents: list[str]) -> list[dict[str, s
|
|||||||
"Your responses should be informative and concise.\n"
|
"Your responses should be informative and concise.\n"
|
||||||
"You MUST prioritize information from provided documents over internal knowledge.\n"
|
"You MUST prioritize information from provided documents over internal knowledge.\n"
|
||||||
"If the query cannot be answered based on the documents, respond with "
|
"If the query cannot be answered based on the documents, respond with "
|
||||||
'{"answer": "Information not found", "quotes": []}\n'
|
f"{complete_answer_not_found_response}\n"
|
||||||
"If the query requires aggregating whole documents, respond with "
|
"If the query requires aggregating whole documents, respond with "
|
||||||
'{"answer": "Aggregations not supported", "quotes": []}\n'
|
'{"answer": "Aggregations not supported", "quotes": []}\n'
|
||||||
f"Sample response:\n{json.dumps(SAMPLE_JSON_RESPONSE)}"
|
f"Sample response:\n{json.dumps(SAMPLE_JSON_RESPONSE)}"
|
||||||
|
@@ -63,8 +63,8 @@ def extract_answer_quotes_freeform(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# If model just gives back the uncertainty pattern to signify answer isn't found or nothing at all
|
# If model just gives back the uncertainty pattern to signify answer isn't found or nothing at all
|
||||||
if null_answer_check == UNCERTAINTY_PAT or not null_answer_check:
|
# if null_answer_check == UNCERTAINTY_PAT or not null_answer_check:
|
||||||
return None, None
|
# return None, None
|
||||||
|
|
||||||
# If no answer section, don't care about the quote
|
# If no answer section, don't care about the quote
|
||||||
if answer_raw.lower().strip().startswith(QUOTE_PAT.lower()):
|
if answer_raw.lower().strip().startswith(QUOTE_PAT.lower()):
|
||||||
|
178
web/package-lock.json
generated
178
web/package-lock.json
generated
@@ -18,7 +18,7 @@
|
|||||||
"eslint-config-next": "13.2.4",
|
"eslint-config-next": "13.2.4",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"next": "^13.2.4",
|
"next": "^13.4.4",
|
||||||
"postcss": "^8.4.23",
|
"postcss": "^8.4.23",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
@@ -172,9 +172,9 @@
|
|||||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||||
},
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.4.tgz",
|
||||||
"integrity": "sha512-eD6WCBMFjLFooLM19SIhSkWBHtaFrZFfg2Cxnyl3vS3DAdFRfnx5TY2RxlkuKXdIRCC0ySbtK9JXXt8qLCqzZg=="
|
"integrity": "sha512-q/y7VZj/9YpgzDe64Zi6rY1xPizx80JjlU2BTevlajtaE3w1LqweH1gGgxou2N7hdFosXHjGrI4OUvtFXXhGLg=="
|
||||||
},
|
},
|
||||||
"node_modules/@next/eslint-plugin-next": {
|
"node_modules/@next/eslint-plugin-next": {
|
||||||
"version": "13.2.4",
|
"version": "13.2.4",
|
||||||
@@ -185,9 +185,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-arm64": {
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz",
|
||||||
"integrity": "sha512-eF8ARHtYfnoYtDa6xFHriUKA/Mfj/cCbmKb3NofeKhMccs65G6/loZ15a6wYCCx4rPAd6x4t1WmVYtri7EdeBg==",
|
"integrity": "sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -200,9 +200,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-x64": {
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz",
|
||||||
"integrity": "sha512-7cmDgF9tGWTgn5Gw+vP17miJbH4wcraMHDCOHTYWkO/VeKT73dUWG23TNRLfgtCNSPgH4V5B4uLHoZTanx9bAw==",
|
"integrity": "sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -215,9 +215,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz",
|
||||||
"integrity": "sha512-qwJqmCri2ie8aTtE5gjTSr8S6O8B67KCYgVZhv9gKH44yvc/zXbAY8u23QGULsYOyh1islWE5sWfQNLOj9iryg==",
|
"integrity": "sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -230,9 +230,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-musl": {
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz",
|
||||||
"integrity": "sha512-qcC54tWNGDv/VVIFkazxhqH1Bnagjfs4enzELVRlUOoJPD2BGJTPI7z08pQPbbgxLtRiu8gl2mXvpB8WlOkMeA==",
|
"integrity": "sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -245,9 +245,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-gnu": {
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.4.tgz",
|
||||||
"integrity": "sha512-9TeWFlpLsBosZ+tsm/rWBaMwt5It9tPH8m3nawZqFUUrZyGRfGcI67js774vtx0k3rL9qbyY6+3pw9BCVpaYUA==",
|
"integrity": "sha512-PX706XcCHr2FfkyhP2lpf+pX/tUvq6/ke7JYnnr0ykNdEMo+sb7cC/o91gnURh4sPYSiZJhsF2gbIqg9rciOHQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -260,9 +260,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-musl": {
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.4.tgz",
|
||||||
"integrity": "sha512-sNDGaWmSqTS4QRUzw61wl4mVPeSqNIr1OOjLlQTRuyInxMxtqImRqdvzDvFTlDfdeUMU/DZhWGYoHrXLlZXe6A==",
|
"integrity": "sha512-TKUUx3Ftd95JlHV6XagEnqpT204Y+IsEa3awaYIjayn0MOGjgKZMZibqarK3B1FsMSPaieJf2FEAcu9z0yT5aA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -275,9 +275,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz",
|
||||||
"integrity": "sha512-+CXZC7u1iXdLRudecoUYbhbsXpglYv8KFYsFxKBPn7kg+bk7eJo738wAA4jXIl8grTF2mPdmO93JOQym+BlYGA==",
|
"integrity": "sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -290,9 +290,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz",
|
||||||
"integrity": "sha512-vIoXVVc7UYO68VwVMDKwJC2+HqAZQtCYiVlApyKEeIPIQpz2gpufzGxk1z3/gwrJt/kJ5CDZjlhYDCzd3hdz+g==",
|
"integrity": "sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -305,9 +305,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-x64-msvc": {
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz",
|
||||||
"integrity": "sha512-n8V5ImLQZibKTu10UUdI3nIeTLkliEXe628qxqW9v8My3BAH2a7H0SaCqkV2OgqFnn8sG1wxKYw9/SNJ632kSA==",
|
"integrity": "sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -2742,11 +2742,11 @@
|
|||||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
||||||
},
|
},
|
||||||
"node_modules/next": {
|
"node_modules/next": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-13.4.4.tgz",
|
||||||
"integrity": "sha512-JBw2kAIyhKDpjhEWvNVoFeIzNp9xNxg8wrthDOtMctfn3EpqGCmW0FSviNyGgOSOSn6zDaX48pmvbdf6X2W9xA==",
|
"integrity": "sha512-C5S0ysM0Ily9McL4Jb48nOQHT1BukOWI59uC3X/xCMlYIh9rJZCv7nzG92J6e1cOBqQbKovlpgvHWFmz4eKKEA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "13.4.1",
|
"@next/env": "13.4.4",
|
||||||
"@swc/helpers": "0.5.1",
|
"@swc/helpers": "0.5.1",
|
||||||
"busboy": "1.6.0",
|
"busboy": "1.6.0",
|
||||||
"caniuse-lite": "^1.0.30001406",
|
"caniuse-lite": "^1.0.30001406",
|
||||||
@@ -2761,20 +2761,19 @@
|
|||||||
"node": ">=16.8.0"
|
"node": ">=16.8.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@next/swc-darwin-arm64": "13.4.1",
|
"@next/swc-darwin-arm64": "13.4.4",
|
||||||
"@next/swc-darwin-x64": "13.4.1",
|
"@next/swc-darwin-x64": "13.4.4",
|
||||||
"@next/swc-linux-arm64-gnu": "13.4.1",
|
"@next/swc-linux-arm64-gnu": "13.4.4",
|
||||||
"@next/swc-linux-arm64-musl": "13.4.1",
|
"@next/swc-linux-arm64-musl": "13.4.4",
|
||||||
"@next/swc-linux-x64-gnu": "13.4.1",
|
"@next/swc-linux-x64-gnu": "13.4.4",
|
||||||
"@next/swc-linux-x64-musl": "13.4.1",
|
"@next/swc-linux-x64-musl": "13.4.4",
|
||||||
"@next/swc-win32-arm64-msvc": "13.4.1",
|
"@next/swc-win32-arm64-msvc": "13.4.4",
|
||||||
"@next/swc-win32-ia32-msvc": "13.4.1",
|
"@next/swc-win32-ia32-msvc": "13.4.4",
|
||||||
"@next/swc-win32-x64-msvc": "13.4.1"
|
"@next/swc-win32-x64-msvc": "13.4.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@opentelemetry/api": "^1.1.0",
|
"@opentelemetry/api": "^1.1.0",
|
||||||
"fibers": ">= 3.1.0",
|
"fibers": ">= 3.1.0",
|
||||||
"node-sass": "^6.0.0 || ^7.0.0",
|
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"sass": "^1.3.0"
|
"sass": "^1.3.0"
|
||||||
@@ -2786,9 +2785,6 @@
|
|||||||
"fibers": {
|
"fibers": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node-sass": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"sass": {
|
"sass": {
|
||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
@@ -4254,9 +4250,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@next/env": {
|
"@next/env": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.4.tgz",
|
||||||
"integrity": "sha512-eD6WCBMFjLFooLM19SIhSkWBHtaFrZFfg2Cxnyl3vS3DAdFRfnx5TY2RxlkuKXdIRCC0ySbtK9JXXt8qLCqzZg=="
|
"integrity": "sha512-q/y7VZj/9YpgzDe64Zi6rY1xPizx80JjlU2BTevlajtaE3w1LqweH1gGgxou2N7hdFosXHjGrI4OUvtFXXhGLg=="
|
||||||
},
|
},
|
||||||
"@next/eslint-plugin-next": {
|
"@next/eslint-plugin-next": {
|
||||||
"version": "13.2.4",
|
"version": "13.2.4",
|
||||||
@@ -4267,57 +4263,57 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@next/swc-darwin-arm64": {
|
"@next/swc-darwin-arm64": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz",
|
||||||
"integrity": "sha512-eF8ARHtYfnoYtDa6xFHriUKA/Mfj/cCbmKb3NofeKhMccs65G6/loZ15a6wYCCx4rPAd6x4t1WmVYtri7EdeBg==",
|
"integrity": "sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-darwin-x64": {
|
"@next/swc-darwin-x64": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz",
|
||||||
"integrity": "sha512-7cmDgF9tGWTgn5Gw+vP17miJbH4wcraMHDCOHTYWkO/VeKT73dUWG23TNRLfgtCNSPgH4V5B4uLHoZTanx9bAw==",
|
"integrity": "sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-linux-arm64-gnu": {
|
"@next/swc-linux-arm64-gnu": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz",
|
||||||
"integrity": "sha512-qwJqmCri2ie8aTtE5gjTSr8S6O8B67KCYgVZhv9gKH44yvc/zXbAY8u23QGULsYOyh1islWE5sWfQNLOj9iryg==",
|
"integrity": "sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-linux-arm64-musl": {
|
"@next/swc-linux-arm64-musl": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz",
|
||||||
"integrity": "sha512-qcC54tWNGDv/VVIFkazxhqH1Bnagjfs4enzELVRlUOoJPD2BGJTPI7z08pQPbbgxLtRiu8gl2mXvpB8WlOkMeA==",
|
"integrity": "sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-linux-x64-gnu": {
|
"@next/swc-linux-x64-gnu": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.4.tgz",
|
||||||
"integrity": "sha512-9TeWFlpLsBosZ+tsm/rWBaMwt5It9tPH8m3nawZqFUUrZyGRfGcI67js774vtx0k3rL9qbyY6+3pw9BCVpaYUA==",
|
"integrity": "sha512-PX706XcCHr2FfkyhP2lpf+pX/tUvq6/ke7JYnnr0ykNdEMo+sb7cC/o91gnURh4sPYSiZJhsF2gbIqg9rciOHQ==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-linux-x64-musl": {
|
"@next/swc-linux-x64-musl": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.4.tgz",
|
||||||
"integrity": "sha512-sNDGaWmSqTS4QRUzw61wl4mVPeSqNIr1OOjLlQTRuyInxMxtqImRqdvzDvFTlDfdeUMU/DZhWGYoHrXLlZXe6A==",
|
"integrity": "sha512-TKUUx3Ftd95JlHV6XagEnqpT204Y+IsEa3awaYIjayn0MOGjgKZMZibqarK3B1FsMSPaieJf2FEAcu9z0yT5aA==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-win32-arm64-msvc": {
|
"@next/swc-win32-arm64-msvc": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz",
|
||||||
"integrity": "sha512-+CXZC7u1iXdLRudecoUYbhbsXpglYv8KFYsFxKBPn7kg+bk7eJo738wAA4jXIl8grTF2mPdmO93JOQym+BlYGA==",
|
"integrity": "sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-win32-ia32-msvc": {
|
"@next/swc-win32-ia32-msvc": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz",
|
||||||
"integrity": "sha512-vIoXVVc7UYO68VwVMDKwJC2+HqAZQtCYiVlApyKEeIPIQpz2gpufzGxk1z3/gwrJt/kJ5CDZjlhYDCzd3hdz+g==",
|
"integrity": "sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-win32-x64-msvc": {
|
"@next/swc-win32-x64-msvc": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz",
|
||||||
"integrity": "sha512-n8V5ImLQZibKTu10UUdI3nIeTLkliEXe628qxqW9v8My3BAH2a7H0SaCqkV2OgqFnn8sG1wxKYw9/SNJ632kSA==",
|
"integrity": "sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@nodelib/fs.scandir": {
|
"@nodelib/fs.scandir": {
|
||||||
@@ -6034,20 +6030,20 @@
|
|||||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"version": "13.4.1",
|
"version": "13.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-13.4.4.tgz",
|
||||||
"integrity": "sha512-JBw2kAIyhKDpjhEWvNVoFeIzNp9xNxg8wrthDOtMctfn3EpqGCmW0FSviNyGgOSOSn6zDaX48pmvbdf6X2W9xA==",
|
"integrity": "sha512-C5S0ysM0Ily9McL4Jb48nOQHT1BukOWI59uC3X/xCMlYIh9rJZCv7nzG92J6e1cOBqQbKovlpgvHWFmz4eKKEA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@next/env": "13.4.1",
|
"@next/env": "13.4.4",
|
||||||
"@next/swc-darwin-arm64": "13.4.1",
|
"@next/swc-darwin-arm64": "13.4.4",
|
||||||
"@next/swc-darwin-x64": "13.4.1",
|
"@next/swc-darwin-x64": "13.4.4",
|
||||||
"@next/swc-linux-arm64-gnu": "13.4.1",
|
"@next/swc-linux-arm64-gnu": "13.4.4",
|
||||||
"@next/swc-linux-arm64-musl": "13.4.1",
|
"@next/swc-linux-arm64-musl": "13.4.4",
|
||||||
"@next/swc-linux-x64-gnu": "13.4.1",
|
"@next/swc-linux-x64-gnu": "13.4.4",
|
||||||
"@next/swc-linux-x64-musl": "13.4.1",
|
"@next/swc-linux-x64-musl": "13.4.4",
|
||||||
"@next/swc-win32-arm64-msvc": "13.4.1",
|
"@next/swc-win32-arm64-msvc": "13.4.4",
|
||||||
"@next/swc-win32-ia32-msvc": "13.4.1",
|
"@next/swc-win32-ia32-msvc": "13.4.4",
|
||||||
"@next/swc-win32-x64-msvc": "13.4.1",
|
"@next/swc-win32-x64-msvc": "13.4.4",
|
||||||
"@swc/helpers": "0.5.1",
|
"@swc/helpers": "0.5.1",
|
||||||
"busboy": "1.6.0",
|
"busboy": "1.6.0",
|
||||||
"caniuse-lite": "^1.0.30001406",
|
"caniuse-lite": "^1.0.30001406",
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
"eslint-config-next": "13.2.4",
|
"eslint-config-next": "13.2.4",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"next": "^13.2.4",
|
"next": "^13.4.4",
|
||||||
"postcss": "^8.4.23",
|
"postcss": "^8.4.23",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
@@ -8,7 +8,7 @@ import { ApiKeyModal } from "@/components/openai/ApiKeyModal";
|
|||||||
import { buildUrl } from "@/lib/utilsSS";
|
import { buildUrl } from "@/lib/utilsSS";
|
||||||
import { Connector, User } from "@/lib/types";
|
import { Connector, User } from "@/lib/types";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import { SearchType } from "@/components/search/SearchTypeSelector";
|
import { SearchType } from "@/lib/search/interfaces";
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
const tasks = [
|
const tasks = [
|
||||||
@@ -35,13 +35,13 @@ export default async function Home() {
|
|||||||
|
|
||||||
// needs to be done in a non-client side component due to nextjs
|
// needs to be done in a non-client side component due to nextjs
|
||||||
const storedSearchType = cookies().get("searchType")?.value as
|
const storedSearchType = cookies().get("searchType")?.value as
|
||||||
| keyof typeof SearchType
|
| string
|
||||||
| undefined;
|
| undefined;
|
||||||
let searchTypeDefault: SearchType =
|
let searchTypeDefault: SearchType =
|
||||||
storedSearchType !== undefined &&
|
storedSearchType !== undefined &&
|
||||||
SearchType.hasOwnProperty(storedSearchType)
|
SearchType.hasOwnProperty(storedSearchType)
|
||||||
? SearchType[storedSearchType]
|
? (storedSearchType as SearchType)
|
||||||
: SearchType.SEMANTIC; // default to semantic search
|
: SearchType.AUTOMATIC; // default to automatic
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@@ -9,6 +9,8 @@ import {
|
|||||||
LinkBreak,
|
LinkBreak,
|
||||||
Link,
|
Link,
|
||||||
Plug,
|
Plug,
|
||||||
|
Bird,
|
||||||
|
Brain,
|
||||||
} from "@phosphor-icons/react";
|
} from "@phosphor-icons/react";
|
||||||
import { SiConfluence, SiGithub, SiGoogledrive, SiSlack } from "react-icons/si";
|
import { SiConfluence, SiGithub, SiGoogledrive, SiSlack } from "react-icons/si";
|
||||||
import { FaFile, FaGlobe } from "react-icons/fa";
|
import { FaFile, FaGlobe } from "react-icons/fa";
|
||||||
@@ -117,3 +119,10 @@ export const InfoIcon = ({
|
|||||||
}: IconProps) => {
|
}: IconProps) => {
|
||||||
return <Info size={size} className={className} />;
|
return <Info size={size} className={className} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const BrainIcon = ({
|
||||||
|
size = "16",
|
||||||
|
className = defaultTailwindCSS,
|
||||||
|
}: IconProps) => {
|
||||||
|
return <Brain size={size} className={className} />;
|
||||||
|
};
|
||||||
|
@@ -35,7 +35,7 @@ export function SourceSelector({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 px-6">
|
<div className="bg-gray-900">
|
||||||
<div className="flex mb-2 pb-1 pl-2 border-b border-gray-800 mx-2">
|
<div className="flex mb-2 pb-1 pl-2 border-b border-gray-800 mx-2">
|
||||||
<h2 className="font-bold my-auto">Filters</h2>
|
<h2 className="font-bold my-auto">Filters</h2>
|
||||||
<Funnel className="my-auto ml-2" size="20" />
|
<Funnel className="my-auto ml-2" size="20" />
|
||||||
|
@@ -2,15 +2,19 @@ import React, { useState, KeyboardEvent, ChangeEvent } from "react";
|
|||||||
import { MagnifyingGlass } from "@phosphor-icons/react";
|
import { MagnifyingGlass } from "@phosphor-icons/react";
|
||||||
|
|
||||||
interface SearchBarProps {
|
interface SearchBarProps {
|
||||||
onSearch: (searchTerm: string) => void;
|
query: string;
|
||||||
|
setQuery: (query: string) => void;
|
||||||
|
onSearch: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SearchBar: React.FC<SearchBarProps> = ({ onSearch }) => {
|
export const SearchBar: React.FC<SearchBarProps> = ({
|
||||||
const [searchTerm, setSearchTerm] = useState<string>("");
|
query,
|
||||||
|
setQuery,
|
||||||
|
onSearch,
|
||||||
|
}) => {
|
||||||
const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
setSearchTerm(target.value);
|
setQuery(target.value);
|
||||||
|
|
||||||
// Resize the textarea to fit the content
|
// Resize the textarea to fit the content
|
||||||
target.style.height = "24px";
|
target.style.height = "24px";
|
||||||
@@ -20,7 +24,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({ onSearch }) => {
|
|||||||
|
|
||||||
const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
|
const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
if (event.key === "Enter" && !event.shiftKey) {
|
if (event.key === "Enter" && !event.shiftKey) {
|
||||||
onSearch(searchTerm);
|
onSearch();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -34,7 +38,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({ onSearch }) => {
|
|||||||
role="textarea"
|
role="textarea"
|
||||||
aria-multiline
|
aria-multiline
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
value={searchTerm}
|
value={query}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
suppressContentEditableWarning={true}
|
suppressContentEditableWarning={true}
|
||||||
|
142
web/src/components/search/SearchHelper.tsx
Normal file
142
web/src/components/search/SearchHelper.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import {
|
||||||
|
FlowType,
|
||||||
|
SearchDefaultOverrides,
|
||||||
|
SearchRequestOverrides,
|
||||||
|
SearchResponse,
|
||||||
|
SearchType,
|
||||||
|
} from "@/lib/search/interfaces";
|
||||||
|
import { BrainIcon } from "../icons/icons";
|
||||||
|
|
||||||
|
const CLICKABLE_CLASS_NAME = "text-blue-400 cursor-pointer";
|
||||||
|
const NUM_DOCUMENTS_FED_TO_GPT = 5;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
isFetching: boolean;
|
||||||
|
searchResponse: SearchResponse | null;
|
||||||
|
selectedSearchType: SearchType;
|
||||||
|
setSelectedSearchType: (searchType: SearchType) => void;
|
||||||
|
defaultOverrides: SearchDefaultOverrides;
|
||||||
|
restartSearch: (overrides?: SearchRequestOverrides) => void;
|
||||||
|
forceQADisplay: () => void;
|
||||||
|
setOffset: (offset: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAssistantMessage = ({
|
||||||
|
isFetching,
|
||||||
|
searchResponse,
|
||||||
|
selectedSearchType,
|
||||||
|
setSelectedSearchType,
|
||||||
|
defaultOverrides,
|
||||||
|
restartSearch,
|
||||||
|
forceQADisplay,
|
||||||
|
setOffset,
|
||||||
|
}: Props): string | JSX.Element | null => {
|
||||||
|
if (!searchResponse || !searchResponse.suggestedFlowType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
searchResponse.suggestedFlowType === FlowType.SEARCH &&
|
||||||
|
!defaultOverrides.forceDisplayQA &&
|
||||||
|
!isFetching &&
|
||||||
|
searchResponse.answer
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
This doesn't seem like a question for a Generative AI. Do you still
|
||||||
|
want to have{" "}
|
||||||
|
<span className={CLICKABLE_CLASS_NAME} onClick={forceQADisplay}>
|
||||||
|
GPT give a response?
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(searchResponse.suggestedSearchType);
|
||||||
|
console.log(selectedSearchType);
|
||||||
|
if (
|
||||||
|
selectedSearchType !== SearchType.AUTOMATIC &&
|
||||||
|
searchResponse.suggestedSearchType !== selectedSearchType
|
||||||
|
) {
|
||||||
|
if (searchResponse.suggestedSearchType === SearchType.SEMANTIC) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
Your query looks more like natural language, Semantic Search may yield
|
||||||
|
better results. Would you like to{" "}
|
||||||
|
<span
|
||||||
|
className={CLICKABLE_CLASS_NAME}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedSearchType(SearchType.SEMANTIC);
|
||||||
|
restartSearch({ searchType: SearchType.SEMANTIC });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
try AI search?
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
Your query seems to be a better fit for keyword search. Would you like
|
||||||
|
to{" "}
|
||||||
|
<span
|
||||||
|
className={CLICKABLE_CLASS_NAME}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedSearchType(SearchType.KEYWORD);
|
||||||
|
restartSearch({ searchType: SearchType.KEYWORD });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
try Keyword search?
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(searchResponse.suggestedFlowType === FlowType.QUESTION_ANSWER ||
|
||||||
|
defaultOverrides.forceDisplayQA) &&
|
||||||
|
!isFetching &&
|
||||||
|
searchResponse.answer === ""
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
GPT was unable to find an answer in the most relevant{" "}
|
||||||
|
<b>{` ${(defaultOverrides.offset + 1) * NUM_DOCUMENTS_FED_TO_GPT} `}</b>{" "}
|
||||||
|
documents. Do you want to{" "}
|
||||||
|
<span
|
||||||
|
className={CLICKABLE_CLASS_NAME}
|
||||||
|
onClick={() => {
|
||||||
|
const newOffset = defaultOverrides.offset + 1;
|
||||||
|
setOffset(newOffset);
|
||||||
|
restartSearch({
|
||||||
|
offset: newOffset,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
keep searching?
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SearchHelper: React.FC<Props> = (props) => {
|
||||||
|
const message = getAssistantMessage(props);
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="border border-gray-800 rounded p-3 text-sm">
|
||||||
|
<div className="flex">
|
||||||
|
<BrainIcon size="20" />
|
||||||
|
<b className="ml-2">AI Assistant</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="mt-1 text-gray-300">{message}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@@ -6,8 +6,9 @@ import {
|
|||||||
DanswerDocument,
|
DanswerDocument,
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
Quote,
|
Quote,
|
||||||
|
FlowType,
|
||||||
|
SearchDefaultOverrides,
|
||||||
} from "@/lib/search/interfaces";
|
} from "@/lib/search/interfaces";
|
||||||
import { SearchType } from "./SearchTypeSelector";
|
|
||||||
|
|
||||||
const removeDuplicateDocs = (documents: DanswerDocument[]) => {
|
const removeDuplicateDocs = (documents: DanswerDocument[]) => {
|
||||||
const seen = new Set<string>();
|
const seen = new Set<string>();
|
||||||
@@ -27,11 +28,13 @@ const removeDuplicateDocs = (documents: DanswerDocument[]) => {
|
|||||||
interface SearchResultsDisplayProps {
|
interface SearchResultsDisplayProps {
|
||||||
searchResponse: SearchResponse | null;
|
searchResponse: SearchResponse | null;
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
|
defaultOverrides: SearchDefaultOverrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
||||||
searchResponse,
|
searchResponse,
|
||||||
isFetching,
|
isFetching,
|
||||||
|
defaultOverrides,
|
||||||
}) => {
|
}) => {
|
||||||
if (!searchResponse) {
|
if (!searchResponse) {
|
||||||
return null;
|
return null;
|
||||||
@@ -66,58 +69,58 @@ export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{answer && (
|
{answer &&
|
||||||
<div className="h-56">
|
(searchResponse.suggestedFlowType !== FlowType.SEARCH ||
|
||||||
<div className="p-4 border-2 rounded-md border-gray-700">
|
defaultOverrides.forceDisplayQA) && (
|
||||||
<div className="flex mb-1">
|
<div className="min-h-[14rem]">
|
||||||
<h2 className="text font-bold my-auto">AI Answer</h2>
|
<div className="p-4 border-2 rounded-md border-gray-700">
|
||||||
</div>
|
<div className="flex mb-1">
|
||||||
<p className="mb-4">{answer}</p>
|
<h2 className="text font-bold my-auto">AI Answer</h2>
|
||||||
|
</div>
|
||||||
|
<p className="mb-4">{answer}</p>
|
||||||
|
|
||||||
{quotes !== null && (
|
{quotes !== null && (
|
||||||
<>
|
<>
|
||||||
<h2 className="text-sm font-bold mb-2">Sources</h2>
|
<h2 className="text-sm font-bold mb-2">Sources</h2>
|
||||||
{isFetching && dedupedQuotes.length === 0 ? (
|
{isFetching && dedupedQuotes.length === 0 ? (
|
||||||
<LoadingAnimation text="Finding quotes" size="text-sm" />
|
<LoadingAnimation text="Finding quotes" size="text-sm" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
{dedupedQuotes.map((quoteInfo) => (
|
{dedupedQuotes.map((quoteInfo) => (
|
||||||
<a
|
<a
|
||||||
key={quoteInfo.document_id}
|
key={quoteInfo.document_id}
|
||||||
className="p-2 ml-1 border border-gray-800 rounded-lg text-sm flex max-w-[280px] hover:bg-gray-800"
|
className="p-2 ml-1 border border-gray-800 rounded-lg text-sm flex max-w-[280px] hover:bg-gray-800"
|
||||||
href={quoteInfo.link}
|
href={quoteInfo.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
{getSourceIcon(quoteInfo.source_type, "20")}
|
{getSourceIcon(quoteInfo.source_type, "20")}
|
||||||
<p className="truncate break-all ml-2">
|
<p className="truncate break-all ml-2">
|
||||||
{quoteInfo.semantic_identifier ||
|
{quoteInfo.semantic_identifier ||
|
||||||
quoteInfo.document_id}
|
quoteInfo.document_id}
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!answer &&
|
|
||||||
!isFetching &&
|
|
||||||
searchResponse.searchType === SearchType.SEMANTIC && (
|
|
||||||
<div className="flex">
|
|
||||||
<InfoIcon
|
|
||||||
size="20"
|
|
||||||
className="text-red-500 my-auto flex flex-shrink-0"
|
|
||||||
/>
|
|
||||||
<div className="text-red-500 text-xs my-auto ml-1">
|
|
||||||
GPT hurt itself in its confusion :(
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{(answer === null || answer === undefined) && !isFetching && (
|
||||||
|
<div className="flex">
|
||||||
|
<InfoIcon
|
||||||
|
size="20"
|
||||||
|
className="text-red-500 my-auto flex flex-shrink-0"
|
||||||
|
/>
|
||||||
|
<div className="text-red-500 text-xs my-auto ml-1">
|
||||||
|
GPT hurt itself in its confusion :(
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{documents && documents.length > 0 && (
|
{documents && documents.length > 0 && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<div className="font-bold border-b mb-4 pb-1 border-gray-800">
|
<div className="font-bold border-b mb-4 pb-1 border-gray-800">
|
||||||
|
@@ -5,15 +5,25 @@ import { SearchBar } from "./SearchBar";
|
|||||||
import { SearchResultsDisplay } from "./SearchResultsDisplay";
|
import { SearchResultsDisplay } from "./SearchResultsDisplay";
|
||||||
import { SourceSelector } from "./Filters";
|
import { SourceSelector } from "./Filters";
|
||||||
import { Connector } from "@/lib/types";
|
import { Connector } from "@/lib/types";
|
||||||
import { SearchType, SearchTypeSelector } from "./SearchTypeSelector";
|
import { SearchTypeSelector } from "./SearchTypeSelector";
|
||||||
import {
|
import {
|
||||||
DanswerDocument,
|
DanswerDocument,
|
||||||
Quote,
|
Quote,
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
Source,
|
Source,
|
||||||
|
FlowType,
|
||||||
|
SearchType,
|
||||||
|
SearchDefaultOverrides,
|
||||||
|
SearchRequestOverrides,
|
||||||
} from "@/lib/search/interfaces";
|
} from "@/lib/search/interfaces";
|
||||||
import { aiSearchRequestStreamed } from "@/lib/search/ai";
|
import { searchRequestStreamed } from "@/lib/search/streaming";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
import { SearchHelper } from "./SearchHelper";
|
||||||
|
|
||||||
|
const SEARCH_DEFAULT_OVERRIDES_START: SearchDefaultOverrides = {
|
||||||
|
forceDisplayQA: false,
|
||||||
|
offset: 0,
|
||||||
|
};
|
||||||
|
|
||||||
interface SearchSectionProps {
|
interface SearchSectionProps {
|
||||||
connectors: Connector<any>[];
|
connectors: Connector<any>[];
|
||||||
@@ -24,6 +34,9 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
connectors,
|
connectors,
|
||||||
defaultSearchType,
|
defaultSearchType,
|
||||||
}) => {
|
}) => {
|
||||||
|
// Search Bar
|
||||||
|
const [query, setQuery] = useState<string>("");
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
const [searchResponse, setSearchResponse] = useState<SearchResponse | null>(
|
const [searchResponse, setSearchResponse] = useState<SearchResponse | null>(
|
||||||
null
|
null
|
||||||
@@ -37,12 +50,17 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
const [selectedSearchType, setSelectedSearchType] =
|
const [selectedSearchType, setSelectedSearchType] =
|
||||||
useState<SearchType>(defaultSearchType);
|
useState<SearchType>(defaultSearchType);
|
||||||
|
|
||||||
// helpers
|
// Overrides for default behavior that only last a single query
|
||||||
|
const [defaultOverrides, setDefaultOverrides] =
|
||||||
|
useState<SearchDefaultOverrides>(SEARCH_DEFAULT_OVERRIDES_START);
|
||||||
|
|
||||||
|
// Helpers
|
||||||
const initialSearchResponse: SearchResponse = {
|
const initialSearchResponse: SearchResponse = {
|
||||||
answer: null,
|
answer: null,
|
||||||
quotes: null,
|
quotes: null,
|
||||||
documents: null,
|
documents: null,
|
||||||
searchType: selectedSearchType,
|
suggestedSearchType: null,
|
||||||
|
suggestedFlowType: null,
|
||||||
};
|
};
|
||||||
const updateCurrentAnswer = (answer: string) =>
|
const updateCurrentAnswer = (answer: string) =>
|
||||||
setSearchResponse((prevState) => ({
|
setSearchResponse((prevState) => ({
|
||||||
@@ -59,10 +77,42 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
...(prevState || initialSearchResponse),
|
...(prevState || initialSearchResponse),
|
||||||
documents,
|
documents,
|
||||||
}));
|
}));
|
||||||
|
const updateSuggestedSearchType = (suggestedSearchType: SearchType) =>
|
||||||
|
setSearchResponse((prevState) => ({
|
||||||
|
...(prevState || initialSearchResponse),
|
||||||
|
suggestedSearchType,
|
||||||
|
}));
|
||||||
|
const updateSuggestedFlowType = (suggestedFlowType: FlowType) =>
|
||||||
|
setSearchResponse((prevState) => ({
|
||||||
|
...(prevState || initialSearchResponse),
|
||||||
|
suggestedFlowType,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const onSearch = async ({
|
||||||
|
searchType,
|
||||||
|
offset,
|
||||||
|
}: SearchRequestOverrides = {}) => {
|
||||||
|
setIsFetching(true);
|
||||||
|
setSearchResponse(initialSearchResponse);
|
||||||
|
|
||||||
|
await searchRequestStreamed({
|
||||||
|
query,
|
||||||
|
sources,
|
||||||
|
updateCurrentAnswer,
|
||||||
|
updateQuotes,
|
||||||
|
updateDocs,
|
||||||
|
updateSuggestedSearchType,
|
||||||
|
updateSuggestedFlowType,
|
||||||
|
selectedSearchType: searchType ?? selectedSearchType,
|
||||||
|
offset: offset ?? defaultOverrides.offset,
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsFetching(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative max-w-[1500px] mx-auto">
|
<div className="relative max-w-[2000px] xl:max-w-[1400px] mx-auto">
|
||||||
<div className="absolute left-0 ml-24 hidden 2xl:block">
|
<div className="absolute left-0 hidden 2xl:block w-64">
|
||||||
{connectors.length > 0 && (
|
{connectors.length > 0 && (
|
||||||
<SourceSelector
|
<SourceSelector
|
||||||
selectedSources={sources}
|
selectedSources={sources}
|
||||||
@@ -70,6 +120,29 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
existingSources={connectors.map((connector) => connector.source)}
|
existingSources={connectors.map((connector) => connector.source)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="mt-10">
|
||||||
|
<SearchHelper
|
||||||
|
isFetching={isFetching}
|
||||||
|
searchResponse={searchResponse}
|
||||||
|
selectedSearchType={selectedSearchType}
|
||||||
|
setSelectedSearchType={setSelectedSearchType}
|
||||||
|
defaultOverrides={defaultOverrides}
|
||||||
|
restartSearch={onSearch}
|
||||||
|
forceQADisplay={() =>
|
||||||
|
setDefaultOverrides((prevState) => ({
|
||||||
|
...(prevState || SEARCH_DEFAULT_OVERRIDES_START),
|
||||||
|
forceDisplayQA: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
setOffset={(offset) => {
|
||||||
|
setDefaultOverrides((prevState) => ({
|
||||||
|
...(prevState || SEARCH_DEFAULT_OVERRIDES_START),
|
||||||
|
offset,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-[800px] mx-auto">
|
<div className="w-[800px] mx-auto">
|
||||||
<SearchTypeSelector
|
<SearchTypeSelector
|
||||||
@@ -81,25 +154,11 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<SearchBar
|
<SearchBar
|
||||||
onSearch={async (query) => {
|
query={query}
|
||||||
setIsFetching(true);
|
setQuery={setQuery}
|
||||||
setSearchResponse({
|
onSearch={async () => {
|
||||||
answer: null,
|
setDefaultOverrides(SEARCH_DEFAULT_OVERRIDES_START);
|
||||||
quotes: null,
|
await onSearch({ offset: 0 });
|
||||||
documents: null,
|
|
||||||
searchType: selectedSearchType,
|
|
||||||
});
|
|
||||||
|
|
||||||
await aiSearchRequestStreamed({
|
|
||||||
query,
|
|
||||||
sources,
|
|
||||||
updateCurrentAnswer,
|
|
||||||
updateQuotes,
|
|
||||||
updateDocs,
|
|
||||||
searchType: selectedSearchType,
|
|
||||||
});
|
|
||||||
|
|
||||||
setIsFetching(false);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -107,6 +166,7 @@ export const SearchSection: React.FC<SearchSectionProps> = ({
|
|||||||
<SearchResultsDisplay
|
<SearchResultsDisplay
|
||||||
searchResponse={searchResponse}
|
searchResponse={searchResponse}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
|
defaultOverrides={defaultOverrides}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,11 +1,8 @@
|
|||||||
|
import { SearchType } from "@/lib/search/interfaces";
|
||||||
|
|
||||||
const defaultStyle =
|
const defaultStyle =
|
||||||
"py-1 px-2 border rounded border-gray-700 cursor-pointer font-bold ";
|
"py-1 px-2 border rounded border-gray-700 cursor-pointer font-bold ";
|
||||||
|
|
||||||
export enum SearchType {
|
|
||||||
SEMANTIC = "SEMANTIC",
|
|
||||||
KEYWORD = "KEYWORD",
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
selectedSearchType: SearchType;
|
selectedSearchType: SearchType;
|
||||||
setSelectedSearchType: (searchType: SearchType) => void;
|
setSelectedSearchType: (searchType: SearchType) => void;
|
||||||
@@ -20,6 +17,19 @@ export const SearchTypeSelector: React.FC<Props> = ({
|
|||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
defaultStyle +
|
defaultStyle +
|
||||||
|
(selectedSearchType === SearchType.AUTOMATIC
|
||||||
|
? "bg-blue-500"
|
||||||
|
: "bg-gray-800 hover:bg-gray-600")
|
||||||
|
}
|
||||||
|
onClick={() => setSelectedSearchType(SearchType.AUTOMATIC)}
|
||||||
|
>
|
||||||
|
Auto
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
defaultStyle +
|
||||||
|
"ml-2 " +
|
||||||
(selectedSearchType === SearchType.SEMANTIC
|
(selectedSearchType === SearchType.SEMANTIC
|
||||||
? "bg-blue-500"
|
? "bg-blue-500"
|
||||||
: "bg-gray-800 hover:bg-gray-600")
|
: "bg-gray-800 hover:bg-gray-600")
|
||||||
|
@@ -1,6 +1,17 @@
|
|||||||
import { SearchType } from "@/components/search/SearchTypeSelector";
|
|
||||||
import { ValidSources } from "../types";
|
import { ValidSources } from "../types";
|
||||||
|
|
||||||
|
export const FlowType = {
|
||||||
|
SEARCH: "search",
|
||||||
|
QUESTION_ANSWER: "question-answer",
|
||||||
|
};
|
||||||
|
export type FlowType = (typeof FlowType)[keyof typeof FlowType];
|
||||||
|
export const SearchType = {
|
||||||
|
SEMANTIC: "semantic",
|
||||||
|
KEYWORD: "keyword",
|
||||||
|
AUTOMATIC: "automatic",
|
||||||
|
};
|
||||||
|
export type SearchType = (typeof SearchType)[keyof typeof SearchType];
|
||||||
|
|
||||||
export interface Quote {
|
export interface Quote {
|
||||||
document_id: string;
|
document_id: string;
|
||||||
link: string;
|
link: string;
|
||||||
@@ -18,7 +29,8 @@ export interface DanswerDocument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchResponse {
|
export interface SearchResponse {
|
||||||
searchType: SearchType;
|
suggestedSearchType: SearchType | null;
|
||||||
|
suggestedFlowType: FlowType | null;
|
||||||
answer: string | null;
|
answer: string | null;
|
||||||
quotes: Record<string, Quote> | null;
|
quotes: Record<string, Quote> | null;
|
||||||
documents: DanswerDocument[] | null;
|
documents: DanswerDocument[] | null;
|
||||||
@@ -29,11 +41,24 @@ export interface Source {
|
|||||||
internalName: ValidSources;
|
internalName: ValidSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SearchDefaultOverrides {
|
||||||
|
forceDisplayQA: boolean;
|
||||||
|
offset: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SearchRequestArgs {
|
export interface SearchRequestArgs {
|
||||||
query: string;
|
query: string;
|
||||||
sources: Source[];
|
sources: Source[];
|
||||||
updateCurrentAnswer: (val: string) => void;
|
updateCurrentAnswer: (val: string) => void;
|
||||||
updateQuotes: (quotes: Record<string, Quote>) => void;
|
updateQuotes: (quotes: Record<string, Quote>) => void;
|
||||||
updateDocs: (documents: DanswerDocument[]) => void;
|
updateDocs: (documents: DanswerDocument[]) => void;
|
||||||
searchType: SearchType;
|
updateSuggestedSearchType: (searchType: SearchType) => void;
|
||||||
|
updateSuggestedFlowType: (flowType: FlowType) => void;
|
||||||
|
selectedSearchType: SearchType | null;
|
||||||
|
offset: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchRequestOverrides {
|
||||||
|
searchType?: SearchType;
|
||||||
|
offset?: number;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
import { SearchType } from "@/components/search/SearchTypeSelector";
|
import {
|
||||||
import { DanswerDocument, Quote, SearchRequestArgs } from "./interfaces";
|
DanswerDocument,
|
||||||
|
Quote,
|
||||||
|
SearchRequestArgs,
|
||||||
|
SearchType,
|
||||||
|
} from "./interfaces";
|
||||||
|
|
||||||
const processSingleChunk = (
|
const processSingleChunk = (
|
||||||
chunk: string,
|
chunk: string,
|
||||||
@@ -45,14 +49,22 @@ const processRawChunkString = (
|
|||||||
return [parsedChunkSections, currPartialChunk];
|
return [parsedChunkSections, currPartialChunk];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const aiSearchRequestStreamed = async ({
|
export const searchRequestStreamed = async ({
|
||||||
query,
|
query,
|
||||||
sources,
|
sources,
|
||||||
updateCurrentAnswer,
|
updateCurrentAnswer,
|
||||||
updateQuotes,
|
updateQuotes,
|
||||||
updateDocs,
|
updateDocs,
|
||||||
searchType,
|
updateSuggestedSearchType,
|
||||||
|
updateSuggestedFlowType,
|
||||||
|
selectedSearchType,
|
||||||
|
offset,
|
||||||
}: SearchRequestArgs) => {
|
}: SearchRequestArgs) => {
|
||||||
|
let useKeyword = null;
|
||||||
|
if (selectedSearchType !== SearchType.AUTOMATIC) {
|
||||||
|
useKeyword = selectedSearchType === SearchType.KEYWORD ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
let answer = "";
|
let answer = "";
|
||||||
let quotes: Record<string, Quote> | null = null;
|
let quotes: Record<string, Quote> | null = null;
|
||||||
let relevantDocuments: DanswerDocument[] | null = null;
|
let relevantDocuments: DanswerDocument[] | null = null;
|
||||||
@@ -62,7 +74,7 @@ export const aiSearchRequestStreamed = async ({
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
query,
|
query,
|
||||||
collection: "danswer_index",
|
collection: "danswer_index",
|
||||||
use_keyword: searchType === SearchType.KEYWORD,
|
use_keyword: useKeyword,
|
||||||
...(sources.length > 0
|
...(sources.length > 0
|
||||||
? {
|
? {
|
||||||
filters: [
|
filters: [
|
||||||
@@ -72,6 +84,7 @@ export const aiSearchRequestStreamed = async ({
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
|
offset: offset,
|
||||||
}),
|
}),
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -113,12 +126,15 @@ export const aiSearchRequestStreamed = async ({
|
|||||||
// we're now looking for quotes
|
// we're now looking for quotes
|
||||||
updateQuotes({});
|
updateQuotes({});
|
||||||
if (
|
if (
|
||||||
|
answer &&
|
||||||
!answer.endsWith(".") &&
|
!answer.endsWith(".") &&
|
||||||
!answer.endsWith("?") &&
|
!answer.endsWith("?") &&
|
||||||
!answer.endsWith("!")
|
!answer.endsWith("!")
|
||||||
) {
|
) {
|
||||||
answer += ".";
|
answer += ".";
|
||||||
updateCurrentAnswer(answer);
|
updateCurrentAnswer(answer);
|
||||||
|
} else {
|
||||||
|
updateCurrentAnswer("");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Object.hasOwn(chunk, "top_documents")) {
|
if (Object.hasOwn(chunk, "top_documents")) {
|
||||||
@@ -129,6 +145,13 @@ export const aiSearchRequestStreamed = async ({
|
|||||||
);
|
);
|
||||||
updateDocs(relevantDocuments);
|
updateDocs(relevantDocuments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chunk.predicted_flow) {
|
||||||
|
updateSuggestedFlowType(chunk.predicted_flow);
|
||||||
|
}
|
||||||
|
if (chunk.predicted_search) {
|
||||||
|
updateSuggestedSearchType(chunk.predicted_search);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
quotes = chunk as Record<string, Quote>;
|
quotes = chunk as Record<string, Quote>;
|
||||||
updateQuotes(quotes);
|
updateQuotes(quotes);
|
Reference in New Issue
Block a user