-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Frevagpt #69
base: main
Are you sure you want to change the base?
Frevagpt #69
Conversation
Data treaming
We need to hammer out a proper deployment strategy. Currently, I am quite doubtful that we have a mild plan for shipping the whole thing. I haven't even seen a PR/MR for the backend. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is part one. I will comment more stuff later.
webpack/webpack.base.config.js
Outdated
resolve: { | ||
fullySpecified: false | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this also an old fragment? I couldn't find a purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be the case
webpack.config.js
Outdated
buffer: require.resolve("buffer"), | ||
}, | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the changes are necessary anymore except for maybe Dotenv (which could be moved to webpack.base.config.js
). Even this one would not be necessary when you apply all the changes I recommend, but I guess you can leave it here, as I am sure it will come in handy another time (I had already some ideas)..
package.json
Outdated
"react-table": "^7.7.0", | ||
"react-window": "^1.8.8", | ||
"redux": "^4.2.1", | ||
"redux-logger": "^3.0.6", | ||
"redux-thunk": "^2.4.1", | ||
"react-select": "5.7.3" | ||
"remark-gfm": "^3.0.1", | ||
"stream-browserify": "^3.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stream-browserify
, JSONStream
and buffer
are no longer necessary.
I would also propose to remove bootstrap-icons
. For this purpose we already have react-icons
(https://react-icons.github.io/react-icons/) which you should use instead. Consider to use the FontAwesome Set there, as this is what I was using for everything else (with a few minor exceptions) to keep things consistent.
@@ -281,6 +298,12 @@ def _set_favicon(html_color: str, project_root: Path) -> None: | |||
"variable", | |||
] | |||
MENU_ENTRIES = [] | |||
CHAT_BOT_URL = "http://vader5-icpub.lvt.dkrz.de:8502" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be configurable via os.environ.get
. @antarcticrainforest is this how you want this? I lost track when we are using web_config.get
and when os.environ.get
@@ -77,6 +77,23 @@ def _get_logo(logo_file, project_root): | |||
return f"/static/img/{logo_file.name}" | |||
|
|||
|
|||
def _read_secret(port: int = 5002, key: str = "email") -> dict[str, str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@antarcticrainforest I have no clue about those changes and where they come from. Do we need this? Apparently it is not in use.
return codeSnippets; | ||
} | ||
|
||
export const objectToQueryString = (obj) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a dependency query-string
which does essentially the same thing. Use that instead
assets/js/Containers/FrevaGPT/components/PendingAnswerComponent.js
Outdated
Show resolved
Hide resolved
const response = await fetch("/api/chatbot/ping"); | ||
if (response.status === 200) pingSuccessful = true; | ||
} catch (err) { | ||
console.error("PingError: ", err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
console.error is fine for debugging, but we don't want it in the finished code
async fetchData(input) { | ||
const queryObject = { | ||
input, | ||
auth_key: process.env.BOT_AUTH_KEY, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having process.env.BOT_AUTH_KEY
in the react-code means that we are exposing our API-Key to the whole world, which we really don't want. This must be moved to proxyview.py
instead. The same is true for freva_config
.
return ( | ||
<div> | ||
<Card className="mb-3 shadow-sm"> | ||
<div className="btn btn-outline-secondary border-0 p-3 rounded-top text-start card-header shadow-sm button-div"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The outer div doesn't seem necessary, you can replace it by a simple
<>
- Don't use
btn
here. Due to thebtn
the user experience here implies that the Header of the section/Card
is clickable, which it isn't. A simple<Card.Header>
is fine as well - Likewise,
<Card.Body>
looks fine for me, too. It isn't collapsible. - Maybe add some vertical margins between the links. It is visually a bit hard to distinguish between the different links.
- What's the point of hiding the link to the thread behind a
onClick
? I think a<a className="text-wrap" href={`/chatbot/?thread_id=${element.thread}`} >
would be totally fine. It would be even better, if you could use<Link to...
instead (fromimport { Link } from "react-router";
) because it wouldn't cause the whole website to reload and the user would stay inside react, but this would need more adjustments.
export const frevaGPTReducer = (state = frevaGPTInitialState, action) => { | ||
switch (action.type) { | ||
case constants.SET_CONVERSATION: | ||
return { ...state, conversation: action.payload }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retrieving old threads leads to unescaped URI-Fragments in the User
-Variants of the thread, which looks quite ugly (Name%20the%20most%20important%20parameters%20in%20meteorology
).
I would blame the backend for this, but I am not entirely sure as I have never seen the backend. We could try to solve it here, e.g. with something like this:
case constants.SET_CONVERSATION: {
const payload = action.payload;
for (const payloadElem of payload) {
if (payloadElem.variant === "User") {
payloadElem.content = decodeURIComponent(payloadElem.content);
}
}
return { ...state, conversation: payload };
}
Take it with a grain of salt, as I don't have a complete overview over possible edge-cases
this.setState({ userInput: "" }); | ||
} | ||
|
||
async handleSubmit(input) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be reasonable to prevent empty strings to be passed to the backend
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adapted the affected functions. But edge cases like submitting a whitespace or similar absurd inputs are not covered. Should we thin kabout a more comprehensive approach? The Bot seems to handle this kind of inputs well (at least the one I tested).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My take on this would be something like this as the first action in handleSubmit
(since this is the function which performs the actual action either way)
if (!input.trim()) {
return;
}
Or instead of negating the value (empty strings are falsy) you could as well surround it with isEmpty
. By this we would at least cover whitespaces.
webpack.config.js
Outdated
@@ -3,13 +3,22 @@ const { merge } = require("webpack-merge"); | |||
const baseConfig = require("./webpack/webpack.base.config"); | |||
const devConfig = require("./webpack/webpack.dev.config"); | |||
const prodConfig = require("./webpack/webpack.prod.config"); | |||
const webpack = require('webpack'); | |||
|
|||
const Dotenv = require("dotenv-webpack"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since you moved dotenv to the base, we can delete it here.
django_evaluation/settings/local.py
Outdated
@@ -282,6 +299,15 @@ def _set_favicon(html_color: str, project_root: Path) -> None: | |||
] | |||
MENU_ENTRIES = [] | |||
|
|||
CHAT_BOT_URL = "http://vader5-icpub.lvt.dkrz.de:8502" | |||
CHAT_BOT_AUTH_KEY = os.environ.get("CHAT_BOT_AUTH_KEY") | |||
CHAT_BOT_FREVA_CONFIG = os.environ.get("CHAT_BOT_AUTH_KEY") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple things here:
- You renamed
BOT_AUTH_KEY
toCHAT_BOT_AUTH_KEY
. This is not an issue per se but I stumbled upon this because I was not aware of the change and I am not sure if this was by accident. We can keep it though, I don't mind. - Copy-Paste error in the env-var of
CHAT_BOT_FREVA_CONFIG
, but: - I assume that
CHAT_BOT_FREVA_CONFIG
is not needed, as the web has already a env-var for this:EVALUATION_SYSTEM_CONFIG_FILE
(I should have mentioned it earlier, but I forgot, sorry). However, it isn't stored in a variable, as far as I can see. So you can rename the varCHAT_BOT_FREVA_CONFIG
toEVALUATION_SYSTEM_CONFIG_FILE
, I guess. One thing to node is, however, that in dev-envsEVALUATION_SYSTEM_CONFIG_FILE
will obviously refer to a file on the local file system where the (currently) globally deployed chatbot has no access to. I have also no idea what the bot does with this information. I have briefly tested it and it seems that it still works
django_evaluation/views.py
Outdated
@@ -0,0 +1 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete the file
placeholder="Ask a question" | ||
/> | ||
{this.state.loading ? ( | ||
<Button variant="outline-danger" onClick={this.handleStop}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nitpicky, but: Could you add className="d-flex align-items-center"
to both buttons which contain the icon?
The icons are not vertically centered out of the box and with this classes they look so much nicer.
return pingSuccessful; | ||
}; | ||
|
||
const getBotModels = async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error-handling. Do it by checking either the status code or response.ok
.
upstream_response = requests.get(base_url[:-1], params=params, stream=True) | ||
upstream_response.raise_for_status() | ||
except requests.RequestException as e: | ||
return StreamingHttpResponse( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I was dealing with broken BOT_AUTH_KEY
s, I had the pleasure to meet this Exception here and I think we need a few adjustments:
- replace
502
by the actual status_code. It seems that it is stored ine.response.status_code
- Maybe we also don't want to expose the actual error message, because it contains the URL to the bot-server which we don't want to expose (and probably it is not even available from the outside). We should log the actual error message but we only expose something generic. I have something like this in mind:
logger = logging.getLogger("freva-web")
logger.exception(e)
status_code = e.response.status_code
error_message = HTTPStatus(status_code).phrase
HTTPStatus
comes from from http import HTTPStatus
- I think it would make things easier if we would deal with a JSON instead of a string. My initial idea would be to replace the error response by something like
return StreamingHttpResponse(
json.dumps(
{
"variant": "ServerError",
"content": f"Error while connecting to the external API: {error_message}",
}
),
content_type="application/json",
status=status_code,
)
But I am not sure. In other parts of the django backend we simply create errors like {"error": "error message"}
, but if it helps you to keep the structure of the rest, feel free to alter it. Keep in mind that this error message will also appear for other bot-requests like availablebots
}; | ||
|
||
// response of a new bot request is streamed | ||
const response = await fetch( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When having an error case (backend returns some kind of Server Error), the user will not see any output. I think before going into reading the stream, you have to check response.ok
and respond accordingly.
@Karinon Could you have a look at the whole frevagpt and suggest changes and improvements?
I don't really want to merge the changes to main as long as the feature is still in development but a genereal look at the codebase would be helpful.
Thank you