Skip to content

Commit 08afea2

Browse files
committed
suggestions implemented
1 parent 10cda99 commit 08afea2

File tree

11 files changed

+201
-191
lines changed

11 files changed

+201
-191
lines changed

backend/apps/slack/admin/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Slack app admin."""
22

3-
from .chat import ChatAdmin
43
from .conversation import ConversationAdmin
54
from .event import EventAdmin
65
from .member import MemberAdmin

backend/apps/slack/admin/chat.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

backend/apps/slack/common/handlers/ai.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
from apps.ai.agent.tools.rag.rag_tool import RagTool
88
from apps.slack.blocks import markdown
9-
from apps.slack.models import Chat, Member, Workspace
9+
from apps.slack.constants import CONVERSATION_CONTEXT_LIMIT
10+
from apps.slack.models import Conversation, Workspace
1011

1112
logger = logging.getLogger(__name__)
1213

@@ -47,42 +48,41 @@ def process_ai_query(query: str) -> str | None:
4748
return rag_tool.query(question=query)
4849

4950

50-
def get_dm_blocks(query: str, user_id: str, workspace_id: str) -> list[dict]:
51+
def get_dm_blocks(query: str, workspace_id: str, channel_id: str) -> list[dict]:
5152
"""Get AI response blocks for DM with conversation context.
5253
5354
Args:
5455
query (str): The user's question.
55-
user_id (str): Slack user ID.
5656
workspace_id (str): Slack workspace ID.
57+
channel_id (str): Slack channel ID for the DM.
5758
5859
Returns:
5960
list: A list of Slack blocks representing the AI response.
6061
6162
"""
62-
ai_response = process_dm_ai_query(query.strip(), user_id, workspace_id)
63+
ai_response = process_dm_ai_query(query.strip(), workspace_id, channel_id)
6364

6465
if ai_response:
6566
return [markdown(ai_response)]
6667
return get_error_blocks()
6768

6869

69-
def process_dm_ai_query(query: str, user_id: str, workspace_id: str) -> str | None:
70+
def process_dm_ai_query(query: str, workspace_id: str, channel_id: str) -> str | None:
7071
"""Process the AI query with DM conversation context.
7172
7273
Args:
7374
query (str): The user's question.
74-
user_id (str): Slack user ID.
7575
workspace_id (str): Slack workspace ID.
76+
channel_id (str): Slack channel ID for the DM.
7677
7778
Returns:
7879
str | None: The AI response or None if error occurred.
7980
8081
"""
81-
user = Member.objects.get(slack_user_id=user_id)
8282
workspace = Workspace.objects.get(slack_workspace_id=workspace_id)
83+
conversation = Conversation.objects.get(slack_channel_id=channel_id, workspace=workspace)
8384

84-
chat = Chat.update_data(user, workspace)
85-
context = chat.get_context(limit_exchanges=20)
85+
context = conversation.get_context(conversation_context_limit=CONVERSATION_CONTEXT_LIMIT)
8686

8787
rag_tool = RagTool(
8888
chat_model="gpt-4o",
@@ -95,7 +95,7 @@ def process_dm_ai_query(query: str, user_id: str, workspace_id: str) -> str | No
9595
enhanced_query = query
9696

9797
response = rag_tool.query(question=enhanced_query)
98-
chat.add_to_context(query, response)
98+
conversation.add_to_context(query, response)
9999

100100
return response
101101

backend/apps/slack/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from apps.common.constants import NL
44

5+
CONVERSATION_CONTEXT_LIMIT = 20
56
NEST_BOT_NAME = "NestBot"
67

78
OWASP_APPSEC_CHANNEL_ID = "#C0F7D6DFH"

backend/apps/slack/events/message_posted.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,31 +81,27 @@ def handle_event(self, event, client):
8181
def handle_dm(self, event, client, channel_id, user_id, text):
8282
"""Handle direct messages with NestBot (DMs)."""
8383
workspace_id = event.get("team")
84+
channel_info = client.conversations_info(channel=channel_id)
8485

85-
if not workspace_id:
86-
try:
87-
channel_info = client.conversations_info(channel=channel_id)
88-
workspace_id = channel_info["channel"]["team"]
89-
except Exception:
90-
logger.exception("Failed to fetch workspace ID for DM.")
91-
return
86+
try:
87+
workspace = Workspace.objects.get(slack_workspace_id=workspace_id)
88+
except Workspace.DoesNotExist:
89+
logger.exception("Workspace not found for DM.")
90+
return
91+
92+
Conversation.update_data(channel_info["channel"], workspace)
9293

9394
try:
94-
Member.objects.get(slack_user_id=user_id, workspace__slack_workspace_id=workspace_id)
95+
Member.objects.get(slack_user_id=user_id, workspace=workspace)
9596
except Member.DoesNotExist:
96-
try:
97-
user_info = client.users_info(user=user_id)
98-
workspace = Workspace.objects.get(slack_workspace_id=workspace_id)
99-
Member.update_data(user_info["user"], workspace, save=True)
100-
logger.info("Created new member for DM")
101-
except Exception:
102-
logger.exception("Failed to create member for DM.")
103-
return
97+
user_info = client.users_info(user=user_id)
98+
Member.update_data(user_info["user"], workspace, save=True)
99+
logger.info("Created new member for DM")
104100

105101
thread_ts = event.get("thread_ts")
106102

107103
try:
108-
response_blocks = get_dm_blocks(text, user_id, workspace_id)
104+
response_blocks = get_dm_blocks(text, workspace_id, channel_id)
109105
if response_blocks:
110106
client.chat_postMessage(
111107
channel=channel_id,

backend/apps/slack/migrations/0020_chat.py

Lines changed: 0 additions & 56 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 5.2.6 on 2025-10-08 07:21
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("slack", "0019_conversation_is_nest_bot_assistant_enabled"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="conversation",
14+
name="conversation_context",
15+
field=models.TextField(blank=True, verbose_name="Conversation context"),
16+
),
17+
]

backend/apps/slack/models/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from .chat import Chat
21
from .conversation import Conversation
32
from .event import Event
43
from .member import Member

backend/apps/slack/models/chat.py

Lines changed: 0 additions & 90 deletions
This file was deleted.

backend/apps/slack/models/conversation.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Meta:
4242

4343
# Additional attributes.
4444
sync_messages = models.BooleanField(verbose_name="Sync messages", default=False)
45+
conversation_context = models.TextField(blank=True, verbose_name="Conversation context")
4546

4647
def __str__(self):
4748
"""Channel human readable representation."""
@@ -105,3 +106,43 @@ def update_data(conversation_data, workspace, *, save=True):
105106
conversation.save()
106107

107108
return conversation
109+
110+
def add_to_context(self, user_message: str, bot_response: str | None = None) -> None:
111+
"""Add messages to the conversation context.
112+
113+
Args:
114+
user_message: The user's message to add to context.
115+
bot_response: The bot's response to add to context.
116+
117+
"""
118+
if not self.conversation_context:
119+
self.conversation_context = ""
120+
121+
self.conversation_context = f"{self.conversation_context}{f'User: {user_message}\n'}"
122+
123+
if bot_response:
124+
self.conversation_context = f"{self.conversation_context}{f'Bot: {bot_response}\n'}"
125+
126+
self.save(update_fields=["conversation_context"])
127+
128+
def get_context(self, conversation_context_limit: int | None = None) -> str:
129+
"""Get the conversation context.
130+
131+
Args:
132+
conversation_context_limit: Optional limit on number of exchanges to return.
133+
134+
Returns:
135+
The conversation context, potentially limited to recent exchanges.
136+
137+
"""
138+
if not self.conversation_context:
139+
return ""
140+
141+
if conversation_context_limit is None:
142+
return self.conversation_context
143+
144+
lines = self.conversation_context.strip().split("\n")
145+
if len(lines) <= conversation_context_limit * 2:
146+
return self.conversation_context
147+
148+
return "\n".join(lines[-(conversation_context_limit * 2) :])

0 commit comments

Comments
 (0)