Skip to content

feat: enter user location before chat #106

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

Merged
merged 13 commits into from
Jun 18, 2025
Merged

Conversation

apkostka
Copy link
Contributor

@apkostka apkostka commented Jun 11, 2025

I plan to do some refactoring of chat.py to extract core functionality to a separate module, as well as add some tests for this later this week.

  • updates create_vector_store.py to delete all files in store if it exists, and upload files from new directory structure with city and state metadata
  • new session data structure, includes parameters 'city', 'state', and 'messages', rather than just array of messages
  • new form that allows user to select city before chatting, and then saves city/state into session
  • uses city and state in prompt instructions as well as filters file search
  • removes citation drawer functionality due to new laws being added. Replaced by prompting LLM to include links in response

@yangm2
Copy link
Contributor

yangm2 commented Jun 12, 2025

Here's one optional part of the tool API that I found that might be useful to set to required ... https://platform.openai.com/docs/api-reference/responses/create#responses-create-tool_choice

@apkostka
Copy link
Contributor Author

Here's one optional part of the tool API that I found that might be useful to set to required ... https://platform.openai.com/docs/api-reference/responses/create#responses-create-tool_choice

OK that's exactly what I was looking for, thank you!

@apkostka
Copy link
Contributor Author

Lol, nvm, requiring tool calls isn't supported with o3.

@apkostka apkostka marked this pull request as ready for review June 12, 2025 18:10
@apkostka apkostka requested review from wittejm and leekahung June 12, 2025 18:14
Copy link
Contributor

@leekahung leekahung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like what I'm seeing here with the new changes! 🔥

Just a few things I've noted in my feedback.

@codeforpdx codeforpdx deleted a comment from claude bot Jun 13, 2025
@KentShikama
Copy link
Member

Pardon to be a backseat driver here, but my 2 cents is that we should just use the IP address of the user to categorize it into "Portland", "Eugene", "Other Oregon", "Non-oregon" as part of the system prompt. I think the less clicks the better but I'm also just guessing what people want.

@yangm2
Copy link
Contributor

yangm2 commented Jun 13, 2025

Pardon to be a backseat driver here, but my 2 cents is that we should just use the IP address of the user to categorize it into "Portland", "Eugene", "Other Oregon", "Non-oregon" as part of the system prompt. I think the less clicks the better but I'm also just guessing what people want.

I think this intent is good but I'm not confident that we can assume that users will be on their home Internet where their IP address geo locates their home. They could be on a mobile phone or a public terminal (e.g. library) or being helped by a 3rd-party (e.g. clinic). VPNs also confuse geo location.

Geo locating the IP could be used as a first guess but would need to be confirmed and be able to be overridden through some interaction.

@apkostka
Copy link
Contributor Author

Pardon to be a backseat driver here, but my 2 cents is that we should just use the IP address of the user to categorize it into "Portland", "Eugene", "Other Oregon", "Non-oregon" as part of the system prompt. I think the less clicks the better but I'm also just guessing what people want.

If they're using it from any location other than their home we can't assume their IP represents their home city, so this seemed like the best alternative. It's also possible they're asking a question about a city they want to move to but don't currently live in.

@apkostka
Copy link
Contributor Author

@leekahung made changes from your review.

Comment on lines +75 to +111
"filters": {
"type": "or",
"filters": [
{
"type": "and",
"filters": [
{
"type": "eq",
"key": "city",
"value": current_session["city"],
},
{
"type": "eq",
"key": "state",
"value": current_session["state"],
},
],
}
if current_session["city"] != "null"
else None,
{
"type": "and",
"filters": [
{
"type": "eq",
"key": "city",
"value": "null",
},
{
"type": "eq",
"key": "state",
"value": current_session["state"],
},
],
},
],
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this simplify to this? If current_session["state"] == "null", then the first filter (city) will be assigned "null". I think this avoids ORing filter[None, nested_filter].

Suggested change
"filters": {
"type": "or",
"filters": [
{
"type": "and",
"filters": [
{
"type": "eq",
"key": "city",
"value": current_session["city"],
},
{
"type": "eq",
"key": "state",
"value": current_session["state"],
},
],
}
if current_session["city"] != "null"
else None,
{
"type": "and",
"filters": [
{
"type": "eq",
"key": "city",
"value": "null",
},
{
"type": "eq",
"key": "state",
"value": current_session["state"],
},
],
},
],
},
"filters": {
"type": "and",
"filters": [
{
"type": "eq",
"key": "city",
"value": current_session["city"],
},
{
"type": "eq",
"key": "state",
"value": current_session["state"],
},
],
},

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it doesn't, because if the user is in Portland, we want to match documents that match both Portland AND Oregon and null and Oregon (Oregon Laws).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, then it might be worth a lengthier comment above and/or pulling out the filtering values/logic into separate named helper functions.

return json.loads(self.db_con.get(session_id) or "[]")
print("SESSION_ID", session_id)
return json.loads(
self.db_con.get(session_id) or '{"city": "", "state": "", "messages": []}'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it flag bugs earlier if this returned None or raised an error if the session_id is not found in the valkey DB? With None, static type-checking could flag when this branch is possible (so there is handling code). With raising an error, tests would flag this branch, requiring code coverage to see when handling code is missing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, but for right now the easiest thing to do was just to init a new session, since the chat history itself isn't terribly important. Error handling for session retrieval should probably be raised in a different PR, since this one just changes the structure of the session data.

Comment on lines 32 to 38
session_id = session.get("session_id")
if not session_id:
return jsonify([]), 200
saved_session = tenant_session.get(session_id)
if not saved_session:
return jsonify({"error": "No session found"}), 404
print(saved_session)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like this logic should be in session.py

Comment on lines +50 to +54
app.add_url_rule(
"/api/init",
view_func=InitSessionView.as_view("init", tenant_session),
methods=["POST"],
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear what the life-cycle of a Flask session and a TenantSession is. But maybe I'm the only one confused about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, it's a little confusing. Flask session would be the flask-supplied session ID and cookie (used to generate an ID), TenantSession is the user's info and chat history stored in Valkey.

@apkostka apkostka requested a review from leekahung June 16, 2025 19:40
Copy link
Contributor

@leekahung leekahung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recent changes to the select field appear to break the error functionality, see feedback.

Think I'll be good to approve after this patch. I'm good with all the other changes.

@apkostka apkostka requested a review from leekahung June 17, 2025 20:05
Copy link
Member

@KentShikama KentShikama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally they could tell the bot in their initial message that they are moving to X or the bot would prompt them / state their location assumptions.

@apkostka apkostka merged commit 7324543 into codeforpdx:main Jun 18, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants