Skip to content

Commit bbda9f9

Browse files
feat: Add additional logs
1 parent 9bf1fea commit bbda9f9

File tree

4 files changed

+61
-14
lines changed

4 files changed

+61
-14
lines changed

packages/slackBotFunction/app/services/ai_processor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def process_ai_query(user_query: str, session_id: str | None = None) -> AIProces
2323

2424
logger.info(
2525
"response from bedrock",
26-
extra={"has_citations": len(kb_response.get("citations", [])) > 0, "response_text": kb_response},
26+
extra={"response_text": kb_response},
2727
)
2828

2929
return {

packages/slackBotFunction/app/services/bedrock.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def query_bedrock(user_query: str, session_id: str = None) -> RetrieveAndGenerat
9090
response = client.retrieve_and_generate(**request_params)
9191
logger.info(
9292
"Got Bedrock response",
93-
extra={"session_id": response.get("sessionId"), "has_citations": len(response.get("citations", [])) > 0},
93+
extra={"session_id": response.get("sessionId")},
9494
)
9595
return response
9696

packages/slackBotFunction/app/slack/slack_events.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,13 @@ def _create_feedback_blocks(
160160
# Main response block
161161
blocks = []
162162

163-
# Citation buttons
163+
# Create citation buttons
164164
if citations is None or len(citations) == 0:
165165
logger.info("No citations")
166166
else:
167167
action_buttons = []
168168
for i, citation in enumerate(citations):
169+
logger.info("Creating citation", extra={"Citation": citation})
169170
# Create citation blocks
170171
# keys = ["source number", "title", "filename", "reference text", "link"]
171172
title = (
@@ -287,11 +288,9 @@ def process_async_slack_action(body: Dict[str, Any], client: WebClient) -> None:
287288
timestamp = body["message"]["ts"]
288289

289290
# Check if the action is for a citation
290-
if (action_id or "").startswith("cite_"):
291-
params = json.loads(action_data)
292-
291+
if action_id == "cite":
293292
# Update message to include citation content
294-
open_citation(channel_id, timestamp, message, params, client)
293+
open_citation(channel_id, timestamp, message, action_data, client)
295294
return
296295

297296
if message_ts and not is_latest_message(conversation_key=conversation_key, message_ts=message_ts):
@@ -404,15 +403,22 @@ def process_slack_message(event: Dict[str, Any], event_id: str, client: WebClien
404403
response_text = ai_response["text"]
405404

406405
# Split out citation block if present
407-
keys = ["source number", "title", "filename", "reference text", "link"]
408-
split = response_text.split("------")
409-
if len(split) == 1:
410-
citations = []
411-
else:
406+
# Citations are not returned in the object without using `$output_format_instructions$` which overrides the
407+
# system prompt. Instead, pull out and format the citations in the prompt manually
408+
prompt_value_keys = ["source number", "title", "filename", "reference text", "link"]
409+
split = response_text.split("------") # Citations are separated by ------
410+
citations = []
411+
if len(split) != 1:
412412
response_text = split[0]
413413
citation_block = split[1]
414-
citations = re.split("<cit>", citation_block)[1:] or []
415-
citations = [dict(zip(keys, citation.split("|"))) for citation in citations]
414+
415+
citations = re.compile(r"<cit\b[^>]*>(.*?)</cit>", citation_block, re.DOTALL | re.IGNORECASE).findall(
416+
citation_block
417+
)
418+
if len(citations) > 0:
419+
logger.info("Found citation(s)", extra={"Citations": citations})
420+
citation_dict = [dict(zip(prompt_value_keys, citation.split("|"))) for citation in citations]
421+
logger.info("Parsed citation(s)", extra={"CitationsDict": citation_dict})
416422

417423
# Post the answer (plain) to get message_ts
418424
post_params = {"channel": channel, "text": response_text}

packages/slackBotFunction/tests/test_slack_handlers.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,44 @@ def test_feedback_handler_pull_request(
201201
pull_request_id="123",
202202
)
203203
mock_process_async_slack_action.assert_not_called()
204+
205+
206+
@patch("app.slack.slack_events.open_citation")
207+
@patch("app.utils.handler_utils.extract_session_pull_request_id")
208+
@patch("app.utils.handler_utils.forward_action_to_pull_request_lambda")
209+
def test_citation(
210+
mock_forward_action_to_pull_request_lambda: Mock,
211+
mock_extract_session_pull_request_id: Mock,
212+
mock_open_citation: Mock,
213+
mock_get_parameter: Mock,
214+
mock_env: Mock,
215+
):
216+
"""Test citations action handler"""
217+
# setup mocks
218+
mock_extract_session_pull_request_id.return_value = None
219+
220+
mock_body = {
221+
"user": {"id": "U123"},
222+
"actions": [
223+
{
224+
"action_id": "cite",
225+
"value": '{"ck": "conv-key", "ch": "C123", "tt": "123", "mt": "456", "title": "title", "body": "body",'
226+
+ '"link": "citation_link"}',
227+
}
228+
],
229+
"channel": {"id": "C123"},
230+
"message": {"ts": "123", "blocks": []},
231+
}
232+
mock_client = Mock()
233+
234+
# delete and import module to test
235+
if "app.slack.slack_handlers" in sys.modules:
236+
del sys.modules["app.slack.slack_handlers"]
237+
from app.slack.slack_handlers import feedback_handler
238+
239+
# perform operation
240+
feedback_handler(body=mock_body, client=mock_client)
241+
242+
# assertions
243+
mock_open_citation.assert_called_once()
244+
mock_forward_action_to_pull_request_lambda.assert_not_called()

0 commit comments

Comments
 (0)