mbudisic commited on
Commit
db323de
Β·
1 Parent(s): b22a9a8

feat(chainlit): Allow EVA_SEARCH_PERMISSION to be set via Chainlit chat settings UI

Browse files
Files changed (4) hide show
  1. README.md +2 -1
  2. TODO.md +1 -3
  3. app.py +38 -5
  4. docs/DEVELOPER.md +15 -1
README.md CHANGED
@@ -63,6 +63,7 @@ chainlit run app.py
63
  - Web search integration via Tavily
64
  - Semantic chunking for better context retrieval
65
  - Interactive chat interface through Chainlit
 
66
 
67
  ## βš™οΈ Configuration Options
68
 
@@ -80,7 +81,7 @@ You can customize the behavior of PsTuts RAG using environment variables. Set th
80
  | `MAX_RESEARCH_LOOPS` | πŸ” Maximum number of research loops to perform. Default: `3` |
81
  | `LLM_TOOL_MODEL` | πŸ› οΈ Name of the LLM model to use for tool calling. Default: `smollm2:1.7b-instruct-q2_K` |
82
  | `N_CONTEXT_DOCS` | πŸ“š Number of context documents to retrieve for RAG. Default: `2` |
83
- | `EVA_SEARCH_PERMISSION` | 🌐 Permission for search (`yes`, `no`, or `ask`). Default: `no` |
84
  | `EVA_DB_PERSIST` | πŸ’Ύ Path or flag for DB persistence. Default: unset |
85
  | `EVA_REINITIALIZE` | πŸ”„ If true, reinitializes EVA DB. Default: `False` |
86
  | `THREAD_ID` | 🧡 Thread ID for the current session. Default: unset |
 
63
  - Web search integration via Tavily
64
  - Semantic chunking for better context retrieval
65
  - Interactive chat interface through Chainlit
66
+ - 🌐 **Web Search Permission Control**: You can now set whether the AI is allowed to perform web searches directly from the chat settings (top right βš™οΈ). Choose between "Ask every time", "Always allow", or "Never allow" for full control!
67
 
68
  ## βš™οΈ Configuration Options
69
 
 
81
  | `MAX_RESEARCH_LOOPS` | πŸ” Maximum number of research loops to perform. Default: `3` |
82
  | `LLM_TOOL_MODEL` | πŸ› οΈ Name of the LLM model to use for tool calling. Default: `smollm2:1.7b-instruct-q2_K` |
83
  | `N_CONTEXT_DOCS` | πŸ“š Number of context documents to retrieve for RAG. Default: `2` |
84
+ | `EVA_SEARCH_PERMISSION` | 🌐 Permission for search (`yes`, `no`, or `ask`). Default: `no`. **Can also be set in the chat UI!** |
85
  | `EVA_DB_PERSIST` | πŸ’Ύ Path or flag for DB persistence. Default: unset |
86
  | `EVA_REINITIALIZE` | πŸ”„ If true, reinitializes EVA DB. Default: `False` |
87
  | `THREAD_ID` | 🧡 Thread ID for the current session. Default: unset |
TODO.md CHANGED
@@ -1,9 +1,7 @@
1
  # πŸ“ TODOs in Codebase
2
 
3
  - `./app.py:44:# TODO: Create an introduction message here that explains the purpose of the app`
4
- - `./app.py:225: # TODO: Make the step label update instead of add`
5
- - `./app.py:295:# TODO: Clean up imports.`
6
- - `./app.py:297:# TODO Add buttons with pregenerated queries`
7
  - `./pstuts_rag/pstuts_rag/datastore.py:26:# TODO: Write MCP server that ingests `mp4` folder`
8
  - `./pstuts_rag/pstuts_rag/datastore.py:66:# TODO: accumulate transcripts of videos when loading, summarize each, then summarize summaries to get a description of the dataset for the prompt`
9
  - `./pstuts_rag/pstuts_rag/nodes.py:113:# TODO More robust generation of queries - multiquery launch`
 
1
  # πŸ“ TODOs in Codebase
2
 
3
  - `./app.py:44:# TODO: Create an introduction message here that explains the purpose of the app`
4
+ - `./app.py:251: # TODO: Make the step label update instead of add`
 
 
5
  - `./pstuts_rag/pstuts_rag/datastore.py:26:# TODO: Write MCP server that ingests `mp4` folder`
6
  - `./pstuts_rag/pstuts_rag/datastore.py:66:# TODO: accumulate transcripts of videos when loading, summarize each, then summarize summaries to get a description of the dataset for the prompt`
7
  - `./pstuts_rag/pstuts_rag/nodes.py:113:# TODO More robust generation of queries - multiquery launch`
app.py CHANGED
@@ -43,6 +43,24 @@ unique_id = uuid4().hex[0:8]
43
 
44
  # TODO: Create an introduction message here that explains the purpose of the app
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  async def sample_prompt_send(action: cl.Action):
48
  # Simulate a user message using the payload
@@ -117,6 +135,14 @@ async def on_chat_start():
117
  thread_id = f"chat_{uuid4().hex[:8]}"
118
  configuration.thread_id = thread_id
119
 
 
 
 
 
 
 
 
 
120
  # Instantiate the Datastore and register a callback to notify when loading is complete
121
  datastore = Datastore(config=configuration)
122
  datastore.add_completion_callback(
@@ -292,11 +318,6 @@ class ChainlitCallbackHandler(BaseCallbackHandler):
292
  print(f"Error in on_chain_error: {e}")
293
 
294
 
295
- # TODO: Clean up imports.
296
-
297
- # TODO Add buttons with pregenerated queries
298
-
299
-
300
  async def handle_interrupt(query: str) -> YesNoDecision:
301
 
302
  try:
@@ -431,6 +452,18 @@ async def end():
431
  logging.info(f"Session ended: {session_id}")
432
 
433
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  if __name__ == "__main__":
435
 
436
  def handle_sigint(signum, frame):
 
43
 
44
  # TODO: Create an introduction message here that explains the purpose of the app
45
 
46
+ # 1. Define Chainlit settings schema for EVA_SEARCH_PERMISSION
47
+ cl.Settings(
48
+ [
49
+ cl.Dropdown(
50
+ id="eva_search_permission",
51
+ label="Web Search Permission",
52
+ description="Allow the AI to perform web searches?",
53
+ values=[
54
+ {"label": "Ask every time", "value": "ask"},
55
+ {"label": "Always allow", "value": "yes"},
56
+ {"label": "Never allow", "value": "no"},
57
+ ],
58
+ default_value="no",
59
+ required=True,
60
+ )
61
+ ]
62
+ )
63
+
64
 
65
  async def sample_prompt_send(action: cl.Action):
66
  # Simulate a user message using the payload
 
135
  thread_id = f"chat_{uuid4().hex[:8]}"
136
  configuration.thread_id = thread_id
137
 
138
+ # Set initial Chainlit setting for EVA_SEARCH_PERMISSION
139
+ cl.user_session.set(
140
+ "eva_search_permission", configuration.search_permission
141
+ )
142
+ await cl.set_settings(
143
+ {"eva_search_permission": configuration.search_permission}
144
+ )
145
+
146
  # Instantiate the Datastore and register a callback to notify when loading is complete
147
  datastore = Datastore(config=configuration)
148
  datastore.add_completion_callback(
 
318
  print(f"Error in on_chain_error: {e}")
319
 
320
 
 
 
 
 
 
321
  async def handle_interrupt(query: str) -> YesNoDecision:
322
 
323
  try:
 
452
  logging.info(f"Session ended: {session_id}")
453
 
454
 
455
+ # 2. Update Configuration on settings update
456
+ @cl.on_settings_update
457
+ async def on_settings_update(settings):
458
+ configuration = cl.user_session.get("configuration")
459
+ if configuration and "eva_search_permission" in settings:
460
+ configuration.search_permission = settings["eva_search_permission"]
461
+ cl.user_session.set("configuration", configuration)
462
+ cl.user_session.set(
463
+ "eva_search_permission", settings["eva_search_permission"]
464
+ )
465
+
466
+
467
  if __name__ == "__main__":
468
 
469
  def handle_sigint(signum, frame):
docs/DEVELOPER.md CHANGED
@@ -505,4 +505,18 @@ This repo uses [`flake8-todos`](https://github.com/awestlake87/flake8-todos) to
505
 
506
  Happy hacking! πŸš€
507
 
508
- <!-- Test edit for TODO.md automation check -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
 
506
  Happy hacking! πŸš€
507
 
508
+ <!-- Test edit for TODO.md automation check -->
509
+
510
+ ## πŸ› οΈ Chainlit Settings Integration: Web Search Permission 🌐
511
+
512
+ You can now control the EVA web search permission (`EVA_SEARCH_PERMISSION`) directly from the Chainlit chat UI! πŸŽ›οΈ
513
+
514
+ - The setting appears as a dropdown in the chat settings (top right βš™οΈ):
515
+ - "Ask every time" (ask)
516
+ - "Always allow" (yes)
517
+ - "Never allow" (no)
518
+ - When the user changes this setting, the backend updates the `Configuration` object in the session, so all subsequent actions use the new value.
519
+ - The rest of the app always reads the current value from the session's `Configuration`.
520
+
521
+ **How to extend:**
522
+ - To add more user-configurable settings, just add them to the Chainlit settings schema and update the session's `Configuration` in the `@cl.on_settings_update` handler. Easy as pie! πŸ₯§