Skip to content

Commit 2e86b5d

Browse files
authored
feat: replace the starter agent with the coding agent sample (#5)
1 parent 0aeca90 commit 2e86b5d

147 files changed

Lines changed: 4141 additions & 4198 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.claude/CLAUDE.md‎

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

‎.claude/commands/unvendor-bolt.md‎

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

‎.claude/commands/vendor-bolt.md‎

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

‎.github/MAINTAINERS_GUIDE.md‎

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

‎.github/dependabot.yml‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ updates:
44
directories:
55
- "/"
66
- "/openai-agents-sdk"
7-
- "/pydantic-ai"
8-
- "/claude-agent-sdk"
97
schedule:
10-
interval: "weekly"
8+
interval: "daily"
9+
cooldown:
10+
default-days: 7
11+
exclude:
12+
- "slack-*"
1113
labels:
1214
- "pip"
1315
- "dependencies"
1416
- package-ecosystem: "github-actions"
1517
directory: "/"
1618
schedule:
17-
interval: "weekly"
19+
interval: "daily"
20+
cooldown:
21+
default-days: 7

‎.github/workflows/ruff.yml‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches: [main]
66
pull_request:
77

8+
permissions:
9+
contents: read
10+
811
jobs:
912
lint:
1013
runs-on: ubuntu-latest
@@ -13,23 +16,23 @@ jobs:
1316
matrix:
1417
directory:
1518
- openai-agents-sdk
16-
- pydantic-ai
17-
- claude-agent-sdk
1819
defaults:
1920
run:
2021
working-directory: ${{ matrix.directory }}
2122

2223
steps:
23-
- uses: actions/checkout@v7
24+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25+
with:
26+
persist-credentials: false
2427
- name: Set up Python
25-
uses: actions/setup-python@v7
28+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2629
with:
27-
python-version: "3.13"
30+
python-version: "3.14"
2831
- name: Install dependencies
2932
run: |
3033
pip install -U pip
3134
pip install -r requirements.txt
3235
- name: Lint and check formatting with ruff
3336
run: |
3437
ruff check .
35-
ruff format --check .
38+
ruff format --check .

‎.github/workflows/tests.yml‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches: [main]
66
pull_request:
77

8+
permissions:
9+
contents: read
10+
811
jobs:
912
build:
1013
runs-on: ubuntu-latest
@@ -13,18 +16,18 @@ jobs:
1316
matrix:
1417
directory:
1518
- openai-agents-sdk
16-
- pydantic-ai
17-
- claude-agent-sdk
1819
defaults:
1920
run:
2021
working-directory: ${{ matrix.directory }}
2122

2223
steps:
23-
- uses: actions/checkout@v7
24+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25+
with:
26+
persist-credentials: false
2427
- name: Set up Python
25-
uses: actions/setup-python@v7
28+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2629
with:
27-
python-version: "3.13"
30+
python-version: "3.14"
2831
- name: Install dependencies
2932
run: |
3033
pip install -U pip

‎AGENTS.md‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# AGENTS.md
2+
3+
Guidance for coding agents working in this repository.
4+
5+
## What this is
6+
7+
A monorepo for a **Coding Agent** sample for Slack, built with Bolt for Python. Each framework lives in its own directory as a standalone sample:
8+
9+
- `openai-agents-sdk/` — built with the **OpenAI Agents SDK**
10+
11+
Implementations share a structure and user experience, not code. Keep each one obvious on its own, written in its framework's idiom, rather than adding shared helpers.
12+
13+
## Commands
14+
15+
Run these from inside an implementation directory, such as `openai-agents-sdk/`:
16+
17+
```sh
18+
# Run the app (requires .env with the framework's API key; Slack tokens are optional with the CLI)
19+
slack run # via Slack CLI
20+
python3 app.py # directly
21+
22+
# Lint and format (CI runs these on push to main and all PRs)
23+
ruff check .
24+
ruff format --check .
25+
26+
# Run tests
27+
pytest
28+
```
29+
30+
## Repository structure
31+
32+
```
33+
.github/ # Shared CI workflows and dependabot config
34+
openai-agents-sdk/ # OpenAI Agents SDK implementation
35+
```
36+
37+
CI runs ruff and pytest against each directory with a matrix in `.github/workflows/ruff.yml` and `.github/workflows/tests.yml`. Dependabot watches each directory separately. When adding an implementation, add its directory to both workflow matrices, to `.github/dependabot.yml`, and to the framework table in the root `README.md`.
38+
39+
## Architecture
40+
41+
Three layers: **app.py** -> **listeners/** -> **agent/**.
42+
43+
- **`app.py`** starts Bolt's `AsyncApp` in Socket Mode and calls `register_listeners(app)`. **`app_oauth.py`** is the alternative entry point for OAuth over HTTP, where agent slash commands arrive at the manifest's `code_channels.slash_command_url`. Everything is async, so a long turn never holds up the stop button, an approval click, or another channel.
44+
- **`listeners/`** holds Bolt handlers only, grouped by Slack feature (`actions/`, `commands/`, `events/`). Each sub-package has a `register(app)` function.
45+
- **`agent/`** holds everything else: the agents and their prompts, one file per tool under `agent/tools/`, the turn handling, the sessions and the deps each run gets, and command approvals.
46+
47+
The flow: a mention or direct message outside a code channel runs a small routing agent that either replies in place or calls `create_code_channel`. Slack seeds the new channel with the request, and that mention starts the coding agent's first turn there, along with the conversation the request came from. Every later message, slash command, and approval in the channel runs a turn of the same session. Messages sent while a turn runs wait and go into the next turn together.
48+
49+
## Keeping implementations alike
50+
51+
Implementations share structure, not code, so these parts are kept the same by copying them and changing them everywhere at once:
52+
53+
- **The seam between `listeners/` and `agent/`.** Listeners import only from the `agent` package, never from the agent framework, so `listeners/` is the same in every implementation. `agent/__init__.py` provides `answer_request`, `find_session`, `run_turn`, `resume_turn`, `stop_turn`, and `end_session`.
54+
- **Framework-free files.** `agent/turns.py`, `agent/context.py`, `agent/approvals.py`, `agent/sessions.py`, `agent/workspace.py`, `agent/outcome.py`, and `agent/prompts.py` don't import the agent framework. The framework lives in `agent/agent.py`, `agent/guardrails.py`, and `agent/tools/`. `turns.py` calls only `run_request(prompt, deps)`, which returns the reply text, and `start_run(history, text, deps)` and `resume_run(paused, approved, deps)`, which return the `RunOutcome` in `agent/outcome.py`. The paused run is a handle `turns.py` passes back without looking inside, so each framework's way of pausing fits behind it.
55+
- **What the framework side keeps true.** `turns.py` relies on these, so every implementation keeps them: `create_code_channel` sets `deps.code_channel_id`, and `archive_channel` sets `session.archived`. Every code channel tool skips its call once `session.stopped` is set. A paused run's history already records the pending command as not run, so `turns.py` can drop a paused run without resuming it. Beyond that, `turns.py` only checks whether `history` is empty, to know a turn is the first.
56+
- **Prompts.** `agent/prompts.py` is the same word for word in every implementation.
57+
- **Tools.** Every implementation offers the same tools with the same names, arguments, and descriptions, written with its framework's tool decorator. File tools stay inside the clone and can't write into `.git`.
58+
- **Command approvals.** `command_needs_approval(command)` is plain Python and the same in every implementation, wrapped in the framework's own approval hook. Read-only commands and local git changes run without asking. Anything that runs the repository's code or reaches outside the clone asks first. Commands run without a shell, so the check and the run split a command the same way. On Windows, `.cmd` and `.bat` programs like `npm` are the exception, since Windows runs them through `cmd.exe`.
59+
- **Tests.** Test files and names mirror each other, and `tests/test_runs.py` drives real agent runs with a scripted model to cover pausing, resuming, stopping, and running out of turns.
60+
61+
Refer to each implementation's README for its specifics.

0 commit comments

Comments
 (0)