Skip to content

Commit

Permalink
Initial work on retryable errors (iteration)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbarbettini committed Aug 22, 2024
1 parent 5e43528 commit b600616
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
2 changes: 1 addition & 1 deletion arcade/arcade/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def run(
def chat(
model: str = typer.Option("gpt-4o", "-m", help="The model to use for prediction."),
stream: bool = typer.Option(
False, "-s", "--stream", is_flag=True, help="Stream the tool output."
True, "-s", "--stream", is_flag=True, help="Stream the tool output."
),
) -> None:
"""
Expand Down
2 changes: 2 additions & 0 deletions examples/fastapi/arcade_example_fastapi/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
actor.register_tool(repo.search_issues)
actor.register_tool(user.set_starred)
actor.register_tool(chat.send_dm_to_user)
actor.register_tool(chat.send_message_to_channel)


class ChatRequest(BaseModel):
Expand All @@ -47,6 +48,7 @@ async def postChat(request: ChatRequest, tool_choice: str = "execute"):
"SetStarred",
"SearchIssues",
"SendDmToUser",
"SendMessageToChannel",
],
tool_choice=tool_choice,
user="sam",
Expand Down
57 changes: 57 additions & 0 deletions toolkits/slack/arcade_slack/tools/chat.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
from typing import Annotated
from arcade.core.errors import ToolExecutionError, RetryableToolError
from arcade.core.schema import ToolContext
Expand Down Expand Up @@ -34,6 +35,9 @@ def send_dm_to_user(
# does this end up as a developerMessage?
# does it end up in the LLM context?
# provide the dev an Error type that controls what ends up in the LLM context

# TODO make the sleep configurable and sent to the engine
time.sleep(0.5) # Wait for half a second
raise RetryableToolError(
"User not found",
developer_message=f"User with username '{user_name}' not found.",
Expand Down Expand Up @@ -63,3 +67,56 @@ def format_users(userListResponse: dict) -> str:
real_name = user.get("profile", {}).get("real_name", "")
csv_string += f"{user_id},{name},{real_name}\n"
return csv_string.strip()


@tool(
requires_auth=SlackUser(
scope=["chat:write", "channels:read", "groups:read"],
)
)
def send_message_to_channel(
context: ToolContext,
channel_name: Annotated[
str, "The Slack channel name where you want to send the message"
],
message: Annotated[str, "The message you want to send"],
):
"""Send a message to a channel in Slack."""

slackClient = WebClient(token=context.authorization.token)

try:
# Step 1: Retrieve the list of channels
channels_response = slackClient.conversations_list()
channel_id = None
for channel in channels_response["channels"]:
if channel["name"].lower() == channel_name.lower():
channel_id = channel["id"]
break

if not channel_id:
time.sleep(0.5) # Wait for half a second
raise RetryableToolError(
"Channel not found",
developer_message=f"Channel with name '{channel_name}' not found.",
additional_prompt_content=format_channels(channels_response),
)

# Step 2: Send the message to the channel
slackClient.chat_postMessage(channel=channel_id, text=message)

except SlackApiError as e:
raise ToolExecutionError(
f"Error sending message: {e.response['error']}",
developer_message="Error sending message",
)


def format_channels(channels_response: dict) -> str:
csv_string = "All active Slack channels:\n\nid,name\n"
for channel in channels_response["channels"]:
if not channel.get("is_archived", False):
channel_id = channel.get("id", "")
name = channel.get("name", "")
csv_string += f"{channel_id},{name}\n"
return csv_string.strip()

0 comments on commit b600616

Please sign in to comment.