Skip to content

Commit 8c8dc40

Browse files
committed
revert "feat: ai app streaming and loading states"
This reverts commit 0e83c52.
1 parent 0e83c52 commit 8c8dc40

File tree

6 files changed

+71
-52
lines changed

6 files changed

+71
-52
lines changed

.slack/.gitignore

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

.slack/config.json

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

.slack/hooks.json

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

listeners/assistant/assistant.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import logging
22
from typing import List, Dict
3-
from slack_bolt import Assistant, BoltContext, Say, SetSuggestedPrompts
3+
from slack_bolt import Assistant, BoltContext, Say, SetSuggestedPrompts, SetStatus
44
from slack_bolt.context.get_thread_context import GetThreadContext
55
from slack_sdk import WebClient
6+
from slack_sdk.errors import SlackApiError
67

78
from ..llm_caller import call_llm
89

@@ -56,20 +57,39 @@ def respond_in_assistant_thread(
5657
payload: dict,
5758
logger: logging.Logger,
5859
context: BoltContext,
60+
set_status: SetStatus,
61+
get_thread_context: GetThreadContext,
5962
client: WebClient,
6063
say: Say,
6164
):
6265
try:
63-
channel_id = payload["channel"]
64-
thread_ts = payload["thread_ts"]
66+
user_message = payload["text"]
67+
set_status("is typing...")
6568

66-
loading_messages = [
67-
"Teaching the hamsters to type faster…",
68-
"Untangling the internet cables…",
69-
"Consulting the office goldfish…",
70-
"Polishing up the response just for you…",
71-
"Convincing the AI to stop overthinking…",
72-
]
69+
if user_message == "Can you generate a brief summary of the referred channel?":
70+
# the logic here requires the additional bot scopes:
71+
# channels:join, channels:history, groups:history
72+
thread_context = get_thread_context()
73+
referred_channel_id = thread_context.get("channel_id")
74+
try:
75+
channel_history = client.conversations_history(channel=referred_channel_id, limit=50)
76+
except SlackApiError as e:
77+
if e.response["error"] == "not_in_channel":
78+
# If this app's bot user is not in the public channel,
79+
# we'll try joining the channel and then calling the same API again
80+
client.conversations_join(channel=referred_channel_id)
81+
channel_history = client.conversations_history(channel=referred_channel_id, limit=50)
82+
else:
83+
raise e
84+
85+
prompt = f"Can you generate a brief summary of these messages in a Slack channel <#{referred_channel_id}>?\n\n"
86+
for message in reversed(channel_history.get("messages")):
87+
if message.get("user") is not None:
88+
prompt += f"\n<@{message['user']}> says: {message['text']}\n"
89+
messages_in_thread = [{"role": "user", "content": prompt}]
90+
returned_message = call_llm(messages_in_thread)
91+
say(returned_message)
92+
return
7393

7494
replies = client.conversations_replies(
7595
channel=context.channel_id,
@@ -81,28 +101,8 @@ def respond_in_assistant_thread(
81101
for message in replies["messages"]:
82102
role = "user" if message.get("bot_id") is None else "assistant"
83103
messages_in_thread.append({"role": role, "content": message["text"]})
84-
85104
returned_message = call_llm(messages_in_thread)
86-
client.assistant_threads_setStatus(
87-
channel_id=channel_id, thread_ts=thread_ts, status="Bolt is typing", loading_messages=loading_messages
88-
)
89-
stream_response = client.chat_startStream(
90-
channel=channel_id,
91-
thread_ts=thread_ts,
92-
)
93-
stream_ts = stream_response["ts"]
94-
# use of this for loop is specific to openai response method
95-
for event in returned_message:
96-
print(f"\n{event.type}")
97-
if event.type == "response.output_text.delta":
98-
client.chat_appendStream(channel=channel_id, ts=stream_ts, markdown_text=f"{event.delta}")
99-
else:
100-
continue
101-
102-
client.chat_stopStream(
103-
channel=channel_id,
104-
ts=stream_ts,
105-
)
105+
say(returned_message)
106106

107107
except Exception as e:
108108
logger.exception(f"Failed to handle a user message event: {e}")

listeners/llm_caller.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import os
2+
import re
23
from typing import List, Dict
34

45
import openai
5-
from openai import Stream
6-
from openai.types.responses import ResponseStreamEvent
7-
86

97
DEFAULT_SYSTEM_CONTENT = """
108
You're an assistant in a Slack workspace.
@@ -18,9 +16,44 @@
1816
def call_llm(
1917
messages_in_thread: List[Dict[str, str]],
2018
system_content: str = DEFAULT_SYSTEM_CONTENT,
21-
) -> Stream[ResponseStreamEvent]:
19+
) -> str:
2220
openai_client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
2321
messages = [{"role": "system", "content": system_content}]
2422
messages.extend(messages_in_thread)
25-
response = openai_client.responses.create(model="gpt-4o-mini", input=messages, stream=True)
26-
return response
23+
response = openai_client.chat.completions.create(
24+
model="gpt-4o-mini",
25+
n=1,
26+
messages=messages,
27+
max_tokens=16384,
28+
)
29+
return markdown_to_slack(response.choices[0].message.content)
30+
31+
32+
# Conversion from OpenAI markdown to Slack mrkdwn
33+
# See also: https://api.slack.com/reference/surfaces/formatting#basics
34+
def markdown_to_slack(content: str) -> str:
35+
# Split the input string into parts based on code blocks and inline code
36+
parts = re.split(r"(?s)(```.+?```|`[^`\n]+?`)", content)
37+
38+
# Apply the bold, italic, and strikethrough formatting to text not within code
39+
result = ""
40+
for part in parts:
41+
if part.startswith("```") or part.startswith("`"):
42+
result += part
43+
else:
44+
for o, n in [
45+
(
46+
r"\*\*\*(?!\s)([^\*\n]+?)(?<!\s)\*\*\*",
47+
r"_*\1*_",
48+
), # ***bold italic*** to *_bold italic_*
49+
(
50+
r"(?<![\*_])\*(?!\s)([^\*\n]+?)(?<!\s)\*(?![\*_])",
51+
r"_\1_",
52+
), # *italic* to _italic_
53+
(r"\*\*(?!\s)([^\*\n]+?)(?<!\s)\*\*", r"*\1*"), # **bold** to *bold*
54+
(r"__(?!\s)([^_\n]+?)(?<!\s)__", r"*\1*"), # __bold__ to *bold*
55+
(r"~~(?!\s)([^~\n]+?)(?<!\s)~~", r"~\1~"), # ~~strike~~ to ~strike~
56+
]:
57+
part = re.sub(o, n, part)
58+
result += part
59+
return result

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
slack-bolt>=1.21,<2
2-
slack-cli-hooks<1.0.0
3-
slack_sdk==3.36.0.dev0
2+
slack-sdk>=3.33.1,<4
43
# If you use a different LLM vendor, replace this dependency
54
openai
65

0 commit comments

Comments
 (0)