You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/CLAUDE.md
+36-11Lines changed: 36 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,10 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
5
5
## What This Is
6
6
7
-
Casey is an AI-powered IT helpdesk agent for Slack, built with Bolt for Python and Pydantic AI. It uses simulated tools (knowledge base, ticket creation, password reset, system status, permissions lookup) to demonstrate an agentic IT support workflow. All tool data is hardcoded for demo purposes.
7
+
A monorepo containing two parallel implementations of **Casey**, an AI-powered IT helpdesk agent for Slack built with Bolt for Python. Both implementations are functionally identical from the Slack user's perspective but use different AI agent frameworks:
8
+
9
+
-`pydantic-ai/` — Built with **Pydantic AI**
10
+
-`openai-agents-sdk/` — Built with **OpenAI Agents SDK**
11
+
12
+
All tool data (knowledge base, tickets, password resets, system status, permissions) is hardcoded for demo purposes.
8
13
9
14
## Commands
10
15
16
+
All commands must be run from within the respective project directory (`pydantic-ai/` or `openai-agents-sdk/`).
17
+
11
18
```sh
12
19
# Run the app (requires .env with OPENAI_API_KEY; Slack tokens optional with CLI)
13
20
slack run # via Slack CLI
@@ -21,28 +28,46 @@ ruff format --check .
21
28
pytest
22
29
```
23
30
24
-
## Architecture
31
+
## Monorepo Structure
32
+
33
+
```
34
+
.github/ # Shared CI workflows and dependabot config
CI runs ruff lint/format checks against both directories via a matrix strategy in `.github/workflows/ruff.yml`. Dependabot monitors `requirements.txt` in both directories independently.
40
+
41
+
## Architecture (shared across both implementations)
Each sub-package has a `register(app)` function called from `listeners/__init__.py`.
36
53
37
-
**Agent (`agent/casey.py`)** is a Pydantic AI `Agent` with `deps_type=CaseyDeps`. The model is **not** set on the agent (to avoid import-time OpenAI client creation); instead `DEFAULT_MODEL` (`openai:gpt-4o-mini`) is passed at each `run_sync()` call site. Tools are passed via the `tools=[]` constructor parameter (not decorators) so each tool lives in its own file under `agent/tools/`.
54
+
**CaseyDeps** (`agent/deps.py`) is a dataclass carrying `client`, `user_id`, `channel_id`, `thread_ts`. Constructed in each listener handler and passed to the agent at runtime.
38
55
39
-
**CaseyDeps** (`agent/deps.py`) is a dataclass carrying `client`, `user_id`, `channel_id`, `thread_ts`. It's constructed in each listener handler and passed as `deps=` to `run_sync()`.
56
+
**Conversation history** (`conversation/store.py`) is a thread-safe in-memory dict keyed by `(channel_id, thread_ts)` with TTL-based cleanup. This enables multi-turn context.
40
57
41
-
**Conversation history** (`conversation/store.py`) is an in-memory dict keyed by `(channel_id, thread_ts)` storing `list[ModelMessage]`from Pydantic AI. This is what enables multi-turn context. The singleton `conversation_store` is imported from `conversation/`.
58
+
**Handler flow** (DM, mention, modal submit): add `:eyes:` reaction → get history from store → run agent → post response in thread with feedback blocks → store updated messages.
42
59
43
-
## Key Patterns
60
+
## Key Differences Between Implementations
44
61
45
-
- All three message handlers (DM, mention, modal submit) follow the same flow: add :eyes: reaction → get history from store → `casey_agent.run_sync(text, model=DEFAULT_MODEL, deps=deps, message_history=history)` → post `result.output` in thread with feedback blocks → store `result.all_messages()`.
46
-
- Emoji/reaction logic is in the handlers, not the agent. Resolution detection checks `result.output` against a hardcoded phrase list.
47
-
- View builders (`app_home_builder.py`, `modal_builder.py`, `feedback_block.py`) return raw dicts or Block Kit objects, not views themselves. The handlers call `client.views_publish()` or `client.views_open()`.
48
-
- The `message_im` handler filters out bot messages (`event.bot_id`) and subtypes to avoid self-reply loops.
0 commit comments