Skip to content

Commit a8404d3

Browse files
committed
feat: add basic working app using pydantic
1 parent 3c286af commit a8404d3

35 files changed

Lines changed: 1371 additions & 0 deletions

.env.sample

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Optional, uncomment and set when running without the Slack CLI (python3 app.py).
2+
# SLACK_APP_TOKEN=YOUR_SLACK_APP_TOKEN
3+
# SLACK_BOT_TOKEN=YOUR_SLACK_BOT_TOKEN
4+
5+
# Optional, uncomment and set when using a custom Slack instance.
6+
# SLACK_API_URL=YOUR_SLACK_API_URL
7+
8+
# Required, set your OpenAI API key.
9+
OPENAI_API_KEY=YOUR_OPENAI_API_KEY

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ logs/
3838
*.db
3939
.pytype/
4040
.idea/
41+
42+
# claude
43+
.claude/*.local.json

.slack/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
apps.dev.json
2+
cache/

.slack/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"manifest": {
3+
"source": "remote"
4+
}
5+
}

.slack/hooks.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"hooks": {
3+
"get-hooks": "python3 -m slack_cli_hooks.hooks.get_hooks"
4+
}
5+
}

README.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Casey: IT Helpdesk Agent (Bolt for Python and Pydantic)
2+
3+
Meet Casey — an AI-powered IT helpdesk agent that lives in Slack. Casey can troubleshoot common issues, search knowledge base articles, reset passwords, check system status, and create support tickets, all without leaving the conversation.
4+
5+
Built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [Pydantic AI](https://ai.pydantic.dev/) using models from [OpenAI](https://openai.com).
6+
7+
## App Overview
8+
9+
Casey gives your team instant IT support through three entry points:
10+
11+
* **App Home** — Users open Casey's Home tab and choose from common issue categories (Password Reset, Access Request, Software Help, Network Issues, Something Else). A modal collects details, then Casey starts a DM thread with a resolution.
12+
* **Direct Messages** — Users message Casey directly to describe any IT issue. Casey responds in-thread, maintaining context across follow-ups.
13+
* **Channel @mentions** — Users mention `@Casey` in any channel to get help without leaving the conversation.
14+
15+
Casey uses five simulated tools to assist users:
16+
17+
* **Knowledge Base Search** — Finds relevant articles for common topics like VPN, email, Wi-Fi, printers, and more.
18+
* **Support Ticket Creation** — Creates a tracked ticket when issues need human follow-up.
19+
* **Password Reset** — Triggers a password reset and confirms the action.
20+
* **System Status Check** — Reports the operational status of company systems.
21+
* **User Permissions Lookup** — Shows access levels and group memberships.
22+
23+
> **Note:** All tools return simulated data for demonstration purposes. In a production app, these would connect to your actual IT systems.
24+
25+
## Setup
26+
27+
Before getting started, make sure you have a development workspace where you have permissions to install apps.
28+
29+
### Developer Program
30+
31+
Join the [Slack Developer Program](https://api.slack.com/developer-program) for exclusive access to sandbox environments for building and testing your apps, tooling, and resources created to help you build and grow.
32+
33+
### Create the Slack app
34+
35+
<details><summary><strong>Using Slack CLI</strong></summary>
36+
37+
Install the latest version of the Slack CLI for your operating system:
38+
39+
- [Slack CLI for macOS & Linux](https://docs.slack.dev/tools/slack-cli/guides/installing-the-slack-cli-for-mac-and-linux/)
40+
- [Slack CLI for Windows](https://docs.slack.dev/tools/slack-cli/guides/installing-the-slack-cli-for-windows/)
41+
42+
You'll also need to log in if this is your first time using the Slack CLI.
43+
44+
```sh
45+
slack login
46+
```
47+
48+
#### Initializing the project
49+
50+
```sh
51+
slack create my-casey-agent --template slack-samples/bolt-python-support-agent
52+
cd my-casey-agent
53+
```
54+
55+
</details>
56+
57+
<details><summary><strong>Using App Settings</strong></summary>
58+
59+
#### Create Your Slack App
60+
61+
1. Open [https://api.slack.com/apps/new](https://api.slack.com/apps/new) and choose "From an app manifest"
62+
2. Choose the workspace you want to install the application to
63+
3. Copy the contents of [manifest.json](./manifest.json) into the text box that says `*Paste your manifest code here*` (within the JSON tab) and click _Next_
64+
4. Review the configuration and click _Create_
65+
5. Click _Install to Workspace_ and _Allow_ on the screen that follows. You'll then be redirected to the App Configuration dashboard.
66+
67+
#### Environment Variables
68+
69+
Before you can run the app, you'll need to store some environment variables.
70+
71+
1. Rename `.env.sample` to `.env`.
72+
2. Open your apps setting page from [this list](https://api.slack.com/apps), click _OAuth & Permissions_ in the left hand menu, then copy the _Bot User OAuth Token_ into your `.env` file under `SLACK_BOT_TOKEN`.
73+
74+
```sh
75+
SLACK_BOT_TOKEN=YOUR_SLACK_BOT_TOKEN
76+
```
77+
78+
3. Click _Basic Information_ from the left hand menu and follow the steps in the _App-Level Tokens_ section to create an app-level token with the `connections:write` scope. Copy that token into your `.env` as `SLACK_APP_TOKEN`.
79+
80+
```sh
81+
SLACK_APP_TOKEN=YOUR_SLACK_APP_TOKEN
82+
```
83+
84+
#### Initializing the project
85+
86+
```sh
87+
git clone https://github.com/slack-samples/bolt-python-support-agent.git my-casey-agent
88+
cd my-casey-agent
89+
```
90+
91+
</details>
92+
93+
### Setup your python virtual environment
94+
95+
```sh
96+
python3 -m venv .venv
97+
source .venv/bin/activate # for Windows OS, .\.venv\Scripts\Activate instead should work
98+
```
99+
100+
#### Install dependencies
101+
102+
```sh
103+
pip install -r requirements.txt
104+
# or pip install -e .
105+
```
106+
107+
## Providers
108+
109+
### OpenAI Setup
110+
111+
This app uses OpenAI's `gpt-4o-mini` model through Pydantic AI.
112+
113+
1. Create an API key from your [OpenAI dashboard](https://platform.openai.com/api-keys).
114+
1. Rename `.env.sample` to `.env`.
115+
3. Save the OpenAI API key to `.env`:
116+
117+
```sh
118+
OPENAI_API_KEY=YOUR_OPENAI_API_KEY
119+
```
120+
121+
## Development
122+
123+
### Starting the app
124+
125+
<details><summary><strong>Using the Slack CLI</strong></summary>
126+
127+
#### Slack CLI
128+
129+
```sh
130+
slack run
131+
```
132+
</details>
133+
134+
<details><summary><strong>Using the Terminal</strong></summary>
135+
136+
#### Terminal
137+
138+
```sh
139+
python3 app.py
140+
```
141+
142+
</details>
143+
144+
### Using the App
145+
146+
Once Casey is running, there are three ways to interact:
147+
148+
**App Home** — Open Casey in Slack and click the _Home_ tab. You'll see five category buttons. Click one to open a modal, describe your issue, and submit. Casey will start a DM thread with you containing a diagnosis and next steps.
149+
150+
**Direct Messages** — Open a DM with Casey and describe your issue. Casey will react with :eyes: while processing, then reply in a thread. Send follow-up messages in the same thread and Casey will maintain the full conversation context.
151+
152+
**Channel @mentions** — In any channel where Casey has been added, type `@Casey` followed by your issue. Casey responds in a thread so the channel stays clean.
153+
154+
Casey will add a :white_check_mark: reaction when it believes an issue has been resolved, and occasionally adds a contextual emoji reaction to keep things friendly.
155+
156+
### Linting
157+
158+
```sh
159+
# Run ruff check from root directory for linting
160+
ruff check
161+
162+
# Run ruff format from root directory for code formatting
163+
ruff format
164+
```
165+
166+
## Project Structure
167+
168+
### `manifest.json`
169+
170+
`manifest.json` is a configuration for Slack apps. With a manifest, you can create an app with a pre-defined configuration, or adjust the configuration of an existing app.
171+
172+
### `app.py`
173+
174+
`app.py` is the entry point for the application and is the file you'll run to start the server. This project aims to keep this file as thin as possible, primarily using it as a way to route inbound requests.
175+
176+
### `/listeners`
177+
178+
Every incoming request is routed to a "listener". This directory groups each listener based on the Slack Platform feature used.
179+
180+
**`/listeners/events`** — Handles incoming events:
181+
182+
- `app_home_opened.py` — Publishes the App Home view with category buttons.
183+
- `app_mentioned.py` — Responds to `@Casey` mentions in channels.
184+
- `message_im.py` — Responds to direct messages from users.
185+
186+
**`/listeners/actions`** — Handles interactive components:
187+
188+
- `category_buttons.py` — Opens the issue submission modal when a category button is clicked.
189+
- `feedback.py` — Handles thumbs up/down feedback on Casey's responses.
190+
191+
**`/listeners/views`** — Handles view submissions and builds Block Kit views:
192+
193+
- `issue_modal.py` — Processes modal submissions, starts a DM thread, and runs the agent.
194+
- `app_home_builder.py` — Constructs the App Home Block Kit view.
195+
- `modal_builder.py` — Constructs the issue submission modal.
196+
- `feedback_block.py` — Creates the feedback button block attached to responses.
197+
198+
### `/agent`
199+
200+
The `casey.py` file defines the Pydantic AI Agent with a system prompt, personality, and tool configuration.
201+
202+
The `deps.py` file defines the `CaseyDeps` dataclass passed to the agent at runtime, providing access to the Slack client and conversation context.
203+
204+
The `tools` directory contains five IT helpdesk tools that the agent can call during a conversation.
205+
206+
### `/conversation`
207+
208+
The `store.py` file implements a thread-safe in-memory conversation history store, keyed by channel and thread. This enables multi-turn conversations where Casey remembers previous context within a thread.

agent/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .casey import DEFAULT_MODEL, casey_agent
2+
from .deps import CaseyDeps
3+
4+
__all__ = ["casey_agent", "CaseyDeps", "DEFAULT_MODEL"]

agent/casey.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from pydantic_ai import Agent
2+
3+
from agent.deps import CaseyDeps
4+
from agent.tools import (
5+
check_system_status,
6+
create_support_ticket,
7+
lookup_user_permissions,
8+
search_knowledge_base,
9+
trigger_password_reset,
10+
)
11+
12+
CASEY_SYSTEM_PROMPT = """\
13+
You are Casey, an IT helpdesk agent for a company. You help employees troubleshoot \
14+
technical issues, answer IT questions, and manage support requests through Slack.
15+
16+
## Personality
17+
- Calm, competent, and efficient
18+
- Lightly witty — a touch of dry humor when appropriate, but never at the user's expense
19+
- Empathetic to frustration ("I know VPN issues are the worst, let's get you sorted")
20+
- Confident but honest when you don't know something
21+
22+
## Formatting Rules
23+
- Use Slack mrkdwn syntax: *bold*, _italic_, `code`, ```code blocks```, > blockquotes
24+
- Use bullet points for multi-step instructions
25+
- Keep responses concise — aim for helpful, not verbose
26+
- When referencing ticket IDs or system names, use `inline code`
27+
28+
## Workflow
29+
1. Acknowledge the user's issue
30+
2. Search the knowledge base for relevant articles
31+
3. If the KB has a solution, walk the user through it step by step
32+
4. If the issue requires action (password reset, ticket creation), use the appropriate tool
33+
5. After taking action, confirm what was done and what the user should expect next
34+
6. If you cannot resolve the issue, create a support ticket and let the user know
35+
36+
## Escalation Rules
37+
- Always create a ticket for hardware failures, account compromises, or data loss
38+
- Create a ticket when the user has already tried the KB steps and they didn't work
39+
- For access requests, verify the system name and create a ticket with the details
40+
41+
## Boundaries
42+
- You are an IT helpdesk agent only — politely redirect non-IT questions
43+
- Do not make up system statuses or ticket numbers — always use the provided tools
44+
- Do not promise specific resolution times unless the tool response includes them
45+
- If unsure about a user's issue, ask clarifying questions before taking action
46+
"""
47+
48+
DEFAULT_MODEL = "openai:gpt-4o-mini"
49+
50+
casey_agent = Agent(
51+
deps_type=CaseyDeps,
52+
system_prompt=CASEY_SYSTEM_PROMPT,
53+
tools=[
54+
search_knowledge_base,
55+
create_support_ticket,
56+
trigger_password_reset,
57+
check_system_status,
58+
lookup_user_permissions,
59+
],
60+
)

agent/deps.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from dataclasses import dataclass
2+
3+
from slack_sdk import WebClient
4+
5+
6+
@dataclass
7+
class CaseyDeps:
8+
client: WebClient
9+
user_id: str
10+
channel_id: str
11+
thread_ts: str

agent/tools/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from .knowledge_base import search_knowledge_base
2+
from .password_reset import trigger_password_reset
3+
from .system_status import check_system_status
4+
from .ticket import create_support_ticket
5+
from .user_permissions import lookup_user_permissions
6+
7+
__all__ = [
8+
"search_knowledge_base",
9+
"create_support_ticket",
10+
"trigger_password_reset",
11+
"check_system_status",
12+
"lookup_user_permissions",
13+
]

0 commit comments

Comments
 (0)