77import time
88import traceback
99import json
10- import boto3
1110from botocore .exceptions import ClientError
1211from slack_sdk import WebClient
1312from app .core .config import (
2322 TTL_FEEDBACK ,
2423 TTL_SESSION ,
2524 get_bot_messages ,
26- get_guardrail_config ,
27- get_slack_bot_state_table ,
2825 get_logger ,
29- get_table ,
26+ )
27+ from app .services .bedrock import query_bedrock
28+ from app .services .dynamo import (
29+ delete_state_information ,
30+ get_state_information ,
31+ store_state_information ,
32+ update_state_information ,
3033)
3134from app .services .query_reformulator import reformulate_query
3235
@@ -47,10 +50,8 @@ def cleanup_previous_unfeedback_qa(conversation_key, current_message_ts, session
4750 return
4851
4952 # Atomically delete Q&A only if no feedback received
50- table = get_table ()
51- table .delete_item (
52- Key = {"pk" : f"qa#{ conversation_key } #{ previous_message_ts } " , "sk" : "turn" },
53- ConditionExpression = "attribute_not_exists(feedback_received)" ,
53+ delete_state_information (
54+ f"qa#{ conversation_key } #{ previous_message_ts } " , "turn" , "attribute_not_exists(feedback_received)"
5455 )
5556 logger .info ("Deleted unfeedback Q&A for privacy" , extra = {"message_ts" : previous_message_ts })
5657
@@ -68,20 +69,18 @@ def store_qa_pair(conversation_key, user_query, bot_response, message_ts, sessio
6869 Store Q&A pair for feedback correlation
6970 """
7071 try :
71- table = get_table ()
72- table .put_item (
73- Item = {
74- "pk" : f"qa#{ conversation_key } #{ message_ts } " ,
75- "sk" : "turn" ,
76- "user_query" : user_query [:1000 ] if user_query else None ,
77- "bot_response" : bot_response [:2000 ] if bot_response else None ,
78- "session_id" : session_id ,
79- "user_id" : user_id ,
80- "message_ts" : message_ts ,
81- "created_at" : int (time .time ()),
82- "ttl" : int (time .time ()) + TTL_FEEDBACK ,
83- }
84- )
72+ item = {
73+ "pk" : f"qa#{ conversation_key } #{ message_ts } " ,
74+ "sk" : "turn" ,
75+ "user_query" : user_query [:1000 ] if user_query else None ,
76+ "bot_response" : bot_response [:2000 ] if bot_response else None ,
77+ "session_id" : session_id ,
78+ "user_id" : user_id ,
79+ "message_ts" : message_ts ,
80+ "created_at" : int (time .time ()),
81+ "ttl" : int (time .time ()) + TTL_FEEDBACK ,
82+ }
83+ store_state_information (item )
8584 logger .info ("Stored Q&A pair" , extra = {"conversation_key" : conversation_key , "message_ts" : message_ts })
8685 except Exception as e :
8786 logger .error ("Failed to store Q&A pair" , extra = {"error" : str (e )})
@@ -92,11 +91,10 @@ def _mark_qa_feedback_received(conversation_key, message_ts):
9291 Mark Q&A record as having received feedback to prevent deletion
9392 """
9493 try :
95- table = get_table ()
96- table .update_item (
97- Key = {"pk" : f"qa#{ conversation_key } #{ message_ts } " , "sk" : "turn" },
98- UpdateExpression = "SET feedback_received = :val" ,
99- ExpressionAttributeValues = {":val" : True },
94+ update_state_information (
95+ {"pk" : f"qa#{ conversation_key } #{ message_ts } " , "sk" : "turn" },
96+ "SET feedback_received = :val" ,
97+ {":val" : True },
10098 )
10199 except Exception as e :
102100 logger .error ("Error marking Q&A feedback received" , extra = {"error" : str (e )})
@@ -147,7 +145,7 @@ def _create_feedback_blocks(response_text, conversation_key, channel, message_ts
147145 if thread_ts : # Only include thread_ts for channel threads, not DMs
148146 feedback_data ["tt" ] = thread_ts
149147 feedback_value = json .dumps (feedback_data , separators = ("," , ":" ))
150-
148+ BOT_MESSAGES = get_bot_messages ()
151149 return [
152150 {"type" : "section" , "text" : {"type" : "mrkdwn" , "text" : response_text }},
153151 {"type" : "section" , "text" : {"type" : "plain_text" , "text" : BOT_MESSAGES ["feedback_prompt" ]}},
@@ -327,11 +325,7 @@ def store_feedback(
327325 if feedback_text :
328326 feedback_item ["feedback_text" ] = feedback_text [:4000 ]
329327
330- table = get_slack_bot_state_table ()
331- if condition :
332- table .put_item (Item = feedback_item , ConditionExpression = condition )
333- else :
334- table .put_item (Item = feedback_item )
328+ store_state_information (feedback_item , condition )
335329
336330 # Mark Q&A as having received feedback to prevent deletion
337331 if message_ts :
@@ -372,8 +366,7 @@ def get_conversation_session_data(conversation_key):
372366 Get full session data for this conversation
373367 """
374368 try :
375- slack_bot_state_table = get_slack_bot_state_table ()
376- response = slack_bot_state_table .get_item (Key = {"pk" : conversation_key , "sk" : "session" })
369+ response = get_state_information ({"pk" : conversation_key , "sk" : "session" })
377370 if "Item" in response :
378371 logger .info ("Found existing session" , extra = {"conversation_key" : conversation_key })
379372 return response ["Item" ]
@@ -388,7 +381,7 @@ def get_latest_message_ts(conversation_key):
388381 Get latest message timestamp from session
389382 """
390383 try :
391- response = table . get_item ( Key = {"pk" : conversation_key , "sk" : SESSION_SK })
384+ response = get_state_information ( {"pk" : conversation_key , "sk" : SESSION_SK })
392385 if "Item" in response :
393386 return response ["Item" ].get ("latest_message_ts" )
394387 return None
@@ -421,8 +414,7 @@ def store_conversation_session(
421414 if latest_message_ts :
422415 item ["latest_message_ts" ] = latest_message_ts
423416
424- table = get_slack_bot_state_table ()
425- table .put_item (Item = item )
417+ store_state_information (item )
426418 logger .info ("Stored session" , extra = {"session_id" : session_id , "conversation_key" : conversation_key })
427419 except Exception :
428420 logger .error ("Error storing session" , extra = {"error" : traceback .format_exc ()})
@@ -433,61 +425,10 @@ def update_session_latest_message(conversation_key, message_ts):
433425 Update session with latest message timestamp
434426 """
435427 try :
436- table = get_slack_bot_state_table ()
437- table .update_item (
438- Key = {"pk" : conversation_key , "sk" : SESSION_SK },
439- UpdateExpression = "SET latest_message_ts = :ts" ,
440- ExpressionAttributeValues = {":ts" : message_ts },
428+ update_state_information (
429+ {"pk" : conversation_key , "sk" : SESSION_SK },
430+ "SET latest_message_ts = :ts" ,
431+ {":ts" : message_ts },
441432 )
442433 except Exception as e :
443434 logger .error ("Error updating session latest message" , extra = {"error" : str (e )})
444-
445-
446- # ================================================================
447- # Bedrock integration
448- # ================================================================
449-
450-
451- def query_bedrock (user_query , session_id = None ):
452- """
453- Query Amazon Bedrock Knowledge Base using RAG (Retrieval-Augmented Generation)
454-
455- This function retrieves relevant documents from the knowledge base and generates
456- a response using the configured LLM model with guardrails for safety.
457- """
458-
459- KNOWLEDGEBASE_ID , RAG_MODEL_ID , AWS_REGION , GUARD_RAIL_ID , GUARD_VERSION = get_guardrail_config ()
460- client = boto3 .client (
461- service_name = "bedrock-agent-runtime" ,
462- region_name = AWS_REGION ,
463- )
464- request_params = {
465- "input" : {"text" : user_query },
466- "retrieveAndGenerateConfiguration" : {
467- "type" : "KNOWLEDGE_BASE" ,
468- "knowledgeBaseConfiguration" : {
469- "knowledgeBaseId" : KNOWLEDGEBASE_ID ,
470- "modelArn" : RAG_MODEL_ID ,
471- "generationConfiguration" : {
472- "guardrailConfiguration" : {
473- "guardrailId" : GUARD_RAIL_ID ,
474- "guardrailVersion" : GUARD_VERSION ,
475- }
476- },
477- },
478- },
479- }
480-
481- # Include session ID for conversation continuity across messages
482- if session_id :
483- request_params ["sessionId" ] = session_id
484- logger .info ("Using existing session" , extra = {"session_id" : session_id })
485- else :
486- logger .info ("Starting new conversation" )
487-
488- response = client .retrieve_and_generate (** request_params )
489- logger .info (
490- "Got Bedrock response" ,
491- extra = {"session_id" : response .get ("sessionId" ), "has_citations" : len (response .get ("citations" , [])) > 0 },
492- )
493- return response
0 commit comments