python-slack-agents 0.6.2__tar.gz → 0.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/.gitignore +3 -0
  2. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/AGENTS.md +8 -6
  3. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/CHANGELOG.md +39 -0
  4. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/CONTRIBUTING.md +6 -0
  5. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/PKG-INFO +24 -11
  6. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/README.md +23 -10
  7. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/cli.md +1 -1
  8. python_slack_agents-0.7.0/docs/private-repo.md +81 -0
  9. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/setup.md +6 -14
  10. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/llms-full.txt +34 -26
  11. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/pyproject.toml +1 -1
  12. python_slack_agents-0.7.0/src/slack_agents/Dockerfile +38 -0
  13. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/build_docker.py +2 -12
  14. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/init.py +18 -37
  15. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/config.py +23 -0
  16. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_cli.py +39 -0
  17. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_config.py +65 -0
  18. python_slack_agents-0.7.0/tests/test_init.py +88 -0
  19. python_slack_agents-0.7.0/tests/test_overlay_integration.py +64 -0
  20. python_slack_agents-0.6.2/docs/private-repo.md +0 -65
  21. python_slack_agents-0.6.2/src/slack_agents/Dockerfile +0 -26
  22. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/.dockerignore +0 -0
  23. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/.env.example +0 -0
  24. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/.github/workflows/ci.yml +0 -0
  25. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/.github/workflows/publish.yml +0 -0
  26. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/.pre-commit-config.yaml +0 -0
  27. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/CODE_OF_CONDUCT.md +0 -0
  28. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/LICENSE +0 -0
  29. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/SECURITY.md +0 -0
  30. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/README.md +0 -0
  31. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/docs-assistant/config.yaml +0 -0
  32. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/docs-assistant/system_prompt.txt +0 -0
  33. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/hello-world/config.yaml +0 -0
  34. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/hello-world/system_prompt.txt +0 -0
  35. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/kitchen-sink/config.yaml +0 -0
  36. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/agents/kitchen-sink/system_prompt.txt +0 -0
  37. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/access-control.md +0 -0
  38. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/agents.md +0 -0
  39. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/canvas.md +0 -0
  40. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/deployment.md +0 -0
  41. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/llm.md +0 -0
  42. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/media/demo.gif +0 -0
  43. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/observability.md +0 -0
  44. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/slack-app-manifest.json +0 -0
  45. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/storage.md +0 -0
  46. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/tools.md +0 -0
  47. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/docs/user-context.md +0 -0
  48. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/llms.txt +0 -0
  49. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/__init__.py +0 -0
  50. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/access/__init__.py +0 -0
  51. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/access/allow_all.py +0 -0
  52. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/access/allow_list.py +0 -0
  53. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/access/base.py +0 -0
  54. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/agent_loop.py +0 -0
  55. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/__init__.py +0 -0
  56. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/export_conversations.py +0 -0
  57. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/export_conversations_html.py +0 -0
  58. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/export_usage.py +0 -0
  59. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/export_usage_csv.py +0 -0
  60. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/healthcheck.py +0 -0
  61. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/cli/run.py +0 -0
  62. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/conversations.py +0 -0
  63. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/files.py +0 -0
  64. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/llm/__init__.py +0 -0
  65. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/llm/anthropic.py +0 -0
  66. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/llm/base.py +0 -0
  67. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/llm/openai.py +0 -0
  68. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/main.py +0 -0
  69. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/observability.py +0 -0
  70. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/py.typed +0 -0
  71. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/scripts/__init__.py +0 -0
  72. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/scripts/download_fonts.py +0 -0
  73. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/scripts/generate_llms_full.py +0 -0
  74. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/__init__.py +0 -0
  75. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/actions.py +0 -0
  76. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/agent.py +0 -0
  77. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/canvas_auth.py +0 -0
  78. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/canvases.py +0 -0
  79. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/files.py +0 -0
  80. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/format.py +0 -0
  81. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/streaming.py +0 -0
  82. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/streaming_formatter.py +0 -0
  83. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/slack/tool_blocks.py +0 -0
  84. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/storage/__init__.py +0 -0
  85. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/storage/base.py +0 -0
  86. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/storage/postgres.py +0 -0
  87. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/storage/postgres.sql +0 -0
  88. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/storage/sqlite.py +0 -0
  89. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/storage/sqlite.sql +0 -0
  90. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/__init__.py +0 -0
  91. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/base.py +0 -0
  92. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/canvas.py +0 -0
  93. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/canvas_importer.py +0 -0
  94. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/file_exporter.py +0 -0
  95. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/file_importer.py +0 -0
  96. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/mcp_http.py +0 -0
  97. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/src/slack_agents/tools/user_context.py +0 -0
  98. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/__init__.py +0 -0
  99. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_access.py +0 -0
  100. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_agent_loop.py +0 -0
  101. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_canvas_auth.py +0 -0
  102. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_canvas_importer.py +0 -0
  103. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_conversations.py +0 -0
  104. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_cost.py +0 -0
  105. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_export_documents.py +0 -0
  106. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_export_usage.py +0 -0
  107. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_file_extractors.py +0 -0
  108. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_format.py +0 -0
  109. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_llm_factory.py +0 -0
  110. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_mcp_client.py +0 -0
  111. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_openai_convert.py +0 -0
  112. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/tests/test_tool_blocks.py +0 -0
  113. {python_slack_agents-0.6.2 → python_slack_agents-0.7.0}/uv.lock +0 -0
@@ -1,6 +1,9 @@
1
1
  # Worktrees
2
2
  .worktrees/
3
3
 
4
+ # Local implementation plans (working docs)
5
+ .plans/
6
+
4
7
  # Python
5
8
  __pycache__/
6
9
  *.py[cod]
@@ -102,12 +102,14 @@ The project includes AI-agent-friendly documentation following the llms.txt conv
102
102
 
103
103
  ## Releasing
104
104
 
105
- 1. Update `version` in `pyproject.toml`
106
- 2. Update `CHANGELOG.md` with the new version and changes
107
- 3. Run `python3 src/slack_agents/scripts/generate_llms_full.py` to regenerate `llms-full.txt`
108
- 4. Commit and push to `main`
109
- 5. Create a GitHub Release (which creates a git tag)
110
- 6. The `publish.yml` workflow automatically builds and publishes to PyPI via trusted publishing
105
+ `CHANGELOG.md` is the gate. Entries accumulate under `## [Unreleased]` as PRs land; releasing just renames that heading to the new version. If prior releases skipped this step (as 0.6.3 did), backfill those versions first so the changelog is honest about history.
106
+
107
+ 1. **CHANGELOG.md** — rename `## [Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD` with today's date, and add a fresh empty `## [Unreleased]` above it.
108
+ 2. **pyproject.toml** bump `version` to `X.Y.Z`.
109
+ 3. **llms-full.txt** regenerate: `python3 src/slack_agents/scripts/generate_llms_full.py`.
110
+ 4. Commit and push to `main`.
111
+ 5. Create a GitHub Release (which creates a git tag).
112
+ 6. The `publish.yml` workflow automatically builds and publishes to PyPI via trusted publishing.
111
113
 
112
114
  The PyPI deployment requires manual approval in the GitHub Actions UI. Do NOT publish to PyPI manually — the GitHub Release trigger handles it.
113
115
 
@@ -6,6 +6,45 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.7.0] - 2026-04-14
10
+
11
+ ### Changed
12
+
13
+ - **Overlays are no longer Python packages.** `slack-agents init` scaffolds a plain git repo with `requirements.txt` (pinning the currently-installed framework version) instead of `pyproject.toml`. No more `pip install -e .` step for overlays — users run `pip install -r requirements.txt` and are done.
14
+ - The framework CLI now walks up from the agent directory on startup, finds the nearest `src/` sibling, and prepends it to `sys.path`. Custom providers under `src/<pkg>/` resolve without installing the overlay as a pip package.
15
+ - Bundled Dockerfile installs overlay dependencies from `requirements.txt` (or PEP 735 `[dependency-groups]` as an alternative) instead of running `pip install .`. The `README.md` / `llms-full.txt` placeholder workaround is gone.
16
+ - Scaffolder `.gitignore` drops `*.egg-info/` and `dist/` (overlays no longer build wheels).
17
+
18
+ ### Added
19
+
20
+ - `_auto_extend_sys_path()` helper in `slack_agents.config`, called from `load_agent_config()` before any plugin import.
21
+ - End-to-end overlay integration test covering scaffold → auto-sys.path → custom provider resolution, plus Dockerfile-shape assertions.
22
+
23
+ ### Removed
24
+
25
+ - `build-docker` no longer rejects overlays with `req*.txt` files — that file is now the expected input.
26
+ - `slack-agents init` no longer emits `pyproject.toml` or warns about requirements files.
27
+ - "Framework Development" section removed from `docs/setup.md` — contributors see `CONTRIBUTING.md` instead, keeping user-facing docs focused on overlay users.
28
+
29
+ ### Docs
30
+
31
+ - Full rewrite of `docs/private-repo.md` around a single-path overlay model. PEP 735 `[dependency-groups]` documented as an alternative for teams who want `pyproject.toml` without `[project]`.
32
+ - `README.md` "Project Structure" and "Extending" sections rewritten to match.
33
+
34
+ ### Migration
35
+
36
+ - Delete your overlay's `pyproject.toml` and any `*.egg-info/` directories.
37
+ - Add a `requirements.txt` pinning `python-slack-agents==0.7.0` (or `<2`).
38
+ - Run `pip install -r requirements.txt`.
39
+ - Custom providers under `src/<pkg>/` work without `pip install -e .`.
40
+
41
+ ## [0.6.3] - 2026-03-31
42
+
43
+ ### Fixed
44
+
45
+ - Preserve agent name in Docker image for multi-agent database support (`COPY` uses `${AGENT_NAME}` so each image's agent directory keeps its identity).
46
+ - Remove `libmupdf-dev` from the Docker image — image size down to 354 MB.
47
+
9
48
  ## [0.6.2] - 2026-03-19
10
49
 
11
50
  ### Added
@@ -46,6 +46,12 @@ refactor: simplify streaming formatter table detection
46
46
 
47
47
  Prefixes: `feat:`, `fix:`, `docs:`, `chore:`, `test:`, `refactor:`. First line under 72 characters. Add a body after a blank line if context is needed.
48
48
 
49
+ ## CHANGELOG
50
+
51
+ When your change is user-visible (a new feature, a behavior change, a removed option, a fix with user-visible symptoms), add a bullet to `CHANGELOG.md` under `## [Unreleased]`. Group by Keep-a-Changelog categories (`### Added`, `### Changed`, `### Fixed`, `### Removed`). Internal refactors and test-only changes don't need an entry.
52
+
53
+ Releasing is just renaming `[Unreleased]` — so if every PR touches it, releases stay cheap and honest.
54
+
49
55
  ## Pull Requests
50
56
 
51
57
  1. Fork the repo and create a branch
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-slack-agents
3
- Version: 0.6.2
3
+ Version: 0.7.0
4
4
  Summary: A Python framework for deploying AI agents as Slack bots
5
5
  Project-URL: Homepage, https://github.com/CompareNetworks/python-slack-agents
6
6
  Project-URL: Repository, https://github.com/CompareNetworks/python-slack-agents
@@ -90,9 +90,9 @@ pip install python-slack-agents
90
90
  # Scaffold the project
91
91
  slack-agents init my-agents
92
92
 
93
- # Add your tokens and install for development
94
- cp .env.example .env # add your Slack and LLM tokens
95
- pip install -e .
93
+ # Add your tokens and install framework + deps
94
+ cp .env.example .env # add your Slack and LLM tokens
95
+ pip install -r requirements.txt
96
96
 
97
97
  # Run the hello-world agent
98
98
  slack-agents run agents/hello-world
@@ -243,21 +243,31 @@ tools:
243
243
 
244
244
  ## Project Structure
245
245
 
246
- When you add custom providers (tools, LLM, storage, or access control), your project needs a `pyproject.toml` and a `src/` directory so that `pip install -e .` makes your code importable and `slack-agents build-docker` works:
246
+ Your overlay is a plain git repo not a Python package. You edit configs, commit, and run; there's no
247
+ install-the-overlay-as-a-package step. A typical layout looks like:
247
248
 
248
249
  ```
249
250
  my-agents/
250
- ├── pyproject.toml # declares python-slack-agents as dependency
251
- ├── src/
252
- │ └── my_agents/ # your custom providers go here
253
- │ └── __init__.py
251
+ ├── requirements.txt # pins python-slack-agents (and any extra deps)
252
+ ├── .env.example
253
+ ├── .gitignore
254
254
  ├── agents/
255
255
  │ └── my-agent/
256
256
  │ ├── config.yaml
257
257
  │ └── system_prompt.txt
258
- └── .env
258
+ └── src/ # optional — only if you add custom providers
259
+ └── my_agents/
260
+ └── __init__.py
259
261
  ```
260
262
 
263
+ Two conventions to know:
264
+
265
+ - **`src/` holds custom Python.** On `slack-agents run`, the framework walks up from the agent directory,
266
+ finds the nearest `src/` sibling, and prepends it to `sys.path`. Anything under `src/<pkg>/...` is
267
+ importable as `<pkg>.…` with no install step.
268
+ - **`requirements.txt` pins your framework version and any extra Python deps.** `pip install -r requirements.txt`
269
+ is the only install command you ever run.
270
+
261
271
  `slack-agents init` scaffolds this for you. See [Organizing agents](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/private-repo.md) for details.
262
272
 
263
273
  ## Extending
@@ -281,7 +291,10 @@ class Provider(BaseLLMProvider):
281
291
  ...
282
292
  ```
283
293
 
284
- After `pip install -e .`, your providers are importable and the `type` field in config resolves them. This also works with `slack-agents build-docker` — the bundled Dockerfile runs `pip install .` automatically.
294
+ After you drop a module under `src/`, it's picked up automatically on the next `slack-agents run` —
295
+ the framework prepends `./src` to `sys.path` at startup. The same mechanism works inside Docker:
296
+ the bundled Dockerfile installs dependencies from `requirements.txt` and copies your `src/` into the
297
+ image, so custom providers resolve in production too.
285
298
 
286
299
  See the docs for the full interface for each component:
287
300
 
@@ -44,9 +44,9 @@ pip install python-slack-agents
44
44
  # Scaffold the project
45
45
  slack-agents init my-agents
46
46
 
47
- # Add your tokens and install for development
48
- cp .env.example .env # add your Slack and LLM tokens
49
- pip install -e .
47
+ # Add your tokens and install framework + deps
48
+ cp .env.example .env # add your Slack and LLM tokens
49
+ pip install -r requirements.txt
50
50
 
51
51
  # Run the hello-world agent
52
52
  slack-agents run agents/hello-world
@@ -197,21 +197,31 @@ tools:
197
197
 
198
198
  ## Project Structure
199
199
 
200
- When you add custom providers (tools, LLM, storage, or access control), your project needs a `pyproject.toml` and a `src/` directory so that `pip install -e .` makes your code importable and `slack-agents build-docker` works:
200
+ Your overlay is a plain git repo not a Python package. You edit configs, commit, and run; there's no
201
+ install-the-overlay-as-a-package step. A typical layout looks like:
201
202
 
202
203
  ```
203
204
  my-agents/
204
- ├── pyproject.toml # declares python-slack-agents as dependency
205
- ├── src/
206
- │ └── my_agents/ # your custom providers go here
207
- │ └── __init__.py
205
+ ├── requirements.txt # pins python-slack-agents (and any extra deps)
206
+ ├── .env.example
207
+ ├── .gitignore
208
208
  ├── agents/
209
209
  │ └── my-agent/
210
210
  │ ├── config.yaml
211
211
  │ └── system_prompt.txt
212
- └── .env
212
+ └── src/ # optional — only if you add custom providers
213
+ └── my_agents/
214
+ └── __init__.py
213
215
  ```
214
216
 
217
+ Two conventions to know:
218
+
219
+ - **`src/` holds custom Python.** On `slack-agents run`, the framework walks up from the agent directory,
220
+ finds the nearest `src/` sibling, and prepends it to `sys.path`. Anything under `src/<pkg>/...` is
221
+ importable as `<pkg>.…` with no install step.
222
+ - **`requirements.txt` pins your framework version and any extra Python deps.** `pip install -r requirements.txt`
223
+ is the only install command you ever run.
224
+
215
225
  `slack-agents init` scaffolds this for you. See [Organizing agents](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/private-repo.md) for details.
216
226
 
217
227
  ## Extending
@@ -235,7 +245,10 @@ class Provider(BaseLLMProvider):
235
245
  ...
236
246
  ```
237
247
 
238
- After `pip install -e .`, your providers are importable and the `type` field in config resolves them. This also works with `slack-agents build-docker` — the bundled Dockerfile runs `pip install .` automatically.
248
+ After you drop a module under `src/`, it's picked up automatically on the next `slack-agents run` —
249
+ the framework prepends `./src` to `sys.path` at startup. The same mechanism works inside Docker:
250
+ the bundled Dockerfile installs dependencies from `requirements.txt` and copies your `src/` into the
251
+ image, so custom providers resolve in production too.
239
252
 
240
253
  See the docs for the full interface for each component:
241
254
 
@@ -10,7 +10,7 @@ Scaffold a new project in the current directory.
10
10
  slack-agents init <project_name>
11
11
  ```
12
12
 
13
- Creates `pyproject.toml`, `src/<package>/`, `.env.example`, and a `hello-world` agent. Existing files are skipped with a warning.
13
+ Creates `requirements.txt`, `src/<package>/`, `.env.example`, `.gitignore`, and a `hello-world` agent. Existing files are skipped with a warning.
14
14
 
15
15
  ## run
16
16
 
@@ -0,0 +1,81 @@
1
+ # Organizing Your Agents
2
+
3
+ Agents are just directories with `config.yaml` and `system_prompt.txt`. Where you put them depends on your situation.
4
+
5
+ ## Option 1: In the framework repo
6
+
7
+ If you're developing the framework itself, add agents directly to `agents/`. To keep private agents out of version control, use a gitignored directory instead:
8
+
9
+ ```bash
10
+ slack-agents run agents-local/my-agent
11
+ ```
12
+
13
+ ## Option 2: Separate repository
14
+
15
+ For production agents with company-specific prompts, tools, and configs, create a standalone repository:
16
+
17
+ ```bash
18
+ mkdir my-agents && cd my-agents
19
+ python3 -m venv .venv
20
+ source .venv/bin/activate
21
+ pip install python-slack-agents
22
+ slack-agents init my-agents
23
+ pip install -r requirements.txt
24
+ ```
25
+
26
+ This scaffolds:
27
+
28
+ ```
29
+ my-agents/
30
+ ├── requirements.txt # pins python-slack-agents
31
+ ├── .env.example
32
+ ├── .gitignore
33
+ ├── agents/
34
+ │ └── hello-world/
35
+ │ ├── config.yaml
36
+ │ └── system_prompt.txt
37
+ └── src/
38
+ └── my_agents/
39
+ └── __init__.py # add custom providers here
40
+ ```
41
+
42
+ Your overlay is a **plain git repo** — not a Python package. You edit configs, commit, and run. There is no `pip install .` / `pip install -e .` step.
43
+
44
+ ### Two conventions to know
45
+
46
+ - **`src/` holds custom Python.** On `slack-agents run`, the framework walks up from the agent directory looking for a `src/` sibling and prepends it to `sys.path`. Anything you put under `src/my_agents/...` becomes importable as `my_agents.…` — no install step.
47
+ - **`requirements.txt` pins your framework and any extra Python deps.** `pip install -r requirements.txt` is the only install command you ever run.
48
+
49
+ ### Custom providers
50
+
51
+ Drop a module under `src/` and reference it in config:
52
+
53
+ ```yaml
54
+ tools:
55
+ internal-api:
56
+ type: my_agents.tools.internal_api
57
+ allowed_functions: [".*"]
58
+ base_url: "{INTERNAL_API_URL}"
59
+ ```
60
+
61
+ Create `src/my_agents/tools/internal_api.py` with a `Provider` class; the framework will find it on the next `slack-agents run`. No reinstall needed.
62
+
63
+ ### Prefer pyproject.toml?
64
+
65
+ You can use a `pyproject.toml` instead of `requirements.txt` — but **do not add a `[project]` table**, or your overlay becomes an installable package again (the thing this design deliberately avoids). Use PEP 735 `[dependency-groups]`:
66
+
67
+ ```toml
68
+ [dependency-groups]
69
+ default = ["python-slack-agents==X.Y.Z"]
70
+ ```
71
+
72
+ Install with `pip install --group default` (pip ≥ 24.1) or `uv sync`.
73
+
74
+ ### Docker
75
+
76
+ No custom Dockerfile needed — `python-slack-agents` bundles one that auto-detects your dependency file:
77
+
78
+ ```bash
79
+ slack-agents build-docker agents/my-agent
80
+ slack-agents build-docker agents/my-agent --push registry.example.com
81
+ ```
@@ -17,25 +17,17 @@ pip install python-slack-agents
17
17
  # Scaffold the project
18
18
  slack-agents init my-agents
19
19
 
20
- # Add your tokens and install for development
21
- cp .env.example .env # add your Slack and LLM tokens (see below)
22
- pip install -e .
20
+ # Install framework (and any deps) from requirements.txt
21
+ pip install -r requirements.txt
22
+
23
+ # Add your tokens
24
+ cp .env.example .env
23
25
 
24
26
  # Run the hello-world agent
25
27
  slack-agents run agents/hello-world
26
28
  ```
27
29
 
28
- ## Framework Development
29
-
30
- If you're working on the framework itself:
31
-
32
- ```bash
33
- git clone https://github.com/CompareNetworks/python-slack-agents.git
34
- cd python-slack-agents
35
- python3 -m venv .venv
36
- source .venv/bin/activate
37
- pip install -e ".[dev]"
38
- ```
30
+ *Working on the framework itself? See [CONTRIBUTING.md](../CONTRIBUTING.md).*
39
31
 
40
32
  ## Environment Variables
41
33
 
@@ -54,25 +54,17 @@ pip install python-slack-agents
54
54
  # Scaffold the project
55
55
  slack-agents init my-agents
56
56
 
57
- # Add your tokens and install for development
58
- cp .env.example .env # add your Slack and LLM tokens (see below)
59
- pip install -e .
57
+ # Install framework (and any deps) from requirements.txt
58
+ pip install -r requirements.txt
59
+
60
+ # Add your tokens
61
+ cp .env.example .env
60
62
 
61
63
  # Run the hello-world agent
62
64
  slack-agents run agents/hello-world
63
65
  ```
64
66
 
65
- ## Framework Development
66
-
67
- If you're working on the framework itself:
68
-
69
- ```bash
70
- git clone https://github.com/CompareNetworks/python-slack-agents.git
71
- cd python-slack-agents
72
- python3 -m venv .venv
73
- source .venv/bin/activate
74
- pip install -e ".[dev]"
75
- ```
67
+ *Working on the framework itself? See [CONTRIBUTING.md](../CONTRIBUTING.md).*
76
68
 
77
69
  ## Environment Variables
78
70
 
@@ -803,7 +795,7 @@ Scaffold a new project in the current directory.
803
795
  slack-agents init <project_name>
804
796
  ```
805
797
 
806
- Creates `pyproject.toml`, `src/<package>/`, `.env.example`, and a `hello-world` agent. Existing files are skipped with a warning.
798
+ Creates `requirements.txt`, `src/<package>/`, `.env.example`, `.gitignore`, and a `hello-world` agent. Existing files are skipped with a warning.
807
799
 
808
800
  ## run
809
801
 
@@ -1169,32 +1161,35 @@ python3 -m venv .venv
1169
1161
  source .venv/bin/activate
1170
1162
  pip install python-slack-agents
1171
1163
  slack-agents init my-agents
1172
- pip install -e .
1164
+ pip install -r requirements.txt
1173
1165
  ```
1174
1166
 
1175
1167
  This scaffolds:
1176
1168
 
1177
1169
  ```
1178
1170
  my-agents/
1179
- ├── pyproject.toml
1180
- ├── src/
1181
- │ └── my_agents/
1182
- │ └── __init__.py
1171
+ ├── requirements.txt # pins python-slack-agents
1172
+ ├── .env.example
1173
+ ├── .gitignore
1183
1174
  ├── agents/
1184
1175
  │ └── hello-world/
1185
1176
  │ ├── config.yaml
1186
1177
  │ └── system_prompt.txt
1187
- └── .env.example
1178
+ └── src/
1179
+ └── my_agents/
1180
+ └── __init__.py # add custom providers here
1188
1181
  ```
1189
1182
 
1190
- The `pyproject.toml` and `src/` directory are required so that:
1183
+ Your overlay is a **plain git repo** — not a Python package. You edit configs, commit, and run. There is no `pip install .` / `pip install -e .` step.
1191
1184
 
1192
- - **`slack-agents run`** can import custom providers under `src/` (via `pip install -e .`)
1193
- - **`slack-agents build-docker`** works (the bundled Dockerfile runs `pip install .`)
1185
+ ### Two conventions to know
1186
+
1187
+ - **`src/` holds custom Python.** On `slack-agents run`, the framework walks up from the agent directory looking for a `src/` sibling and prepends it to `sys.path`. Anything you put under `src/my_agents/...` becomes importable as `my_agents.…` — no install step.
1188
+ - **`requirements.txt` pins your framework and any extra Python deps.** `pip install -r requirements.txt` is the only install command you ever run.
1194
1189
 
1195
1190
  ### Custom providers
1196
1191
 
1197
- Add custom providers to `src/` and reference them in config:
1192
+ Drop a module under `src/` and reference it in config:
1198
1193
 
1199
1194
  ```yaml
1200
1195
  tools:
@@ -1204,9 +1199,22 @@ tools:
1204
1199
  base_url: "{INTERNAL_API_URL}"
1205
1200
  ```
1206
1201
 
1202
+ Create `src/my_agents/tools/internal_api.py` with a `Provider` class; the framework will find it on the next `slack-agents run`. No reinstall needed.
1203
+
1204
+ ### Prefer pyproject.toml?
1205
+
1206
+ You can use a `pyproject.toml` instead of `requirements.txt` — but **do not add a `[project]` table**, or your overlay becomes an installable package again (the thing this design deliberately avoids). Use PEP 735 `[dependency-groups]`:
1207
+
1208
+ ```toml
1209
+ [dependency-groups]
1210
+ default = ["python-slack-agents==X.Y.Z"]
1211
+ ```
1212
+
1213
+ Install with `pip install --group default` (pip ≥ 24.1) or `uv sync`.
1214
+
1207
1215
  ### Docker
1208
1216
 
1209
- No custom Dockerfile needed — `python-slack-agents` bundles one:
1217
+ No custom Dockerfile needed — `python-slack-agents` bundles one that auto-detects your dependency file:
1210
1218
 
1211
1219
  ```bash
1212
1220
  slack-agents build-docker agents/my-agent
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "python-slack-agents"
7
- version = "0.6.2"
7
+ version = "0.7.0"
8
8
  description = "A Python framework for deploying AI agents as Slack bots"
9
9
  authors = [{name = "Eric Pichon", email = "epichon@comparenetworks.com"}]
10
10
  readme = "README.md"
@@ -0,0 +1,38 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install dependencies first so this layer caches well.
6
+ # Supports either requirements.txt (default from `slack-agents init`)
7
+ # or a pyproject.toml with PEP 735 [dependency-groups] (no [project]).
8
+ COPY requirements.txt* pyproject.toml* ./
9
+ RUN if [ -f requirements.txt ]; then \
10
+ pip install --no-cache-dir -r requirements.txt ; \
11
+ elif [ -f pyproject.toml ]; then \
12
+ pip install --no-cache-dir --group default ; \
13
+ else \
14
+ echo "Error: overlay must have requirements.txt or a pyproject.toml with [dependency-groups]" >&2 ; \
15
+ exit 1 ; \
16
+ fi
17
+
18
+ # Download DejaVu fonts for PDF export with Unicode support
19
+ RUN python -m slack_agents.scripts.download_fonts
20
+
21
+ # Copy the overlay's custom providers (if any). The framework's CLI
22
+ # prepends ./src to sys.path at runtime so imports like
23
+ # `my_agents.tools.foo` resolve without installing the overlay.
24
+ COPY src/ /app/src/
25
+
26
+ # Copy only the selected agent into /app/agent/<name>/ so the framework
27
+ # derives agent_name from the directory name. Multiple agents sharing a
28
+ # database remain distinguishable. The glob agent/* resolves to the
29
+ # single subdirectory. `exec` replaces the shell so slack-agents
30
+ # receives signals directly.
31
+ ARG AGENT_PATH
32
+ ARG AGENT_NAME
33
+ COPY ${AGENT_PATH}/ /app/agent/${AGENT_NAME}/
34
+
35
+ RUN useradd -r -s /bin/false agent
36
+ USER agent
37
+
38
+ CMD ["sh", "-c", "exec slack-agents run agent/*"]
@@ -67,18 +67,6 @@ def execute(args):
67
67
  else:
68
68
  image_tag = f"{image_name}:{version}"
69
69
 
70
- req_files = sorted(Path(".").glob("req*.txt"))
71
- if req_files:
72
- names = ", ".join(f.name for f in req_files)
73
- print(
74
- f"Error: found {names} in the project root.\n"
75
- "Docker builds install dependencies from pyproject.toml, not\n"
76
- "requirements files. Move your dependencies into pyproject.toml\n"
77
- "under [project] dependencies, then remove the requirements file(s).",
78
- file=sys.stderr,
79
- )
80
- sys.exit(1)
81
-
82
70
  print(f"Building {image_tag} ...")
83
71
  result = subprocess.run(
84
72
  [
@@ -88,6 +76,8 @@ def execute(args):
88
76
  args.platform,
89
77
  "--build-arg",
90
78
  f"AGENT_PATH={agent_dir}",
79
+ "--build-arg",
80
+ f"AGENT_NAME={agent_name}",
91
81
  "-f",
92
82
  str(dockerfile),
93
83
  "-t",
@@ -1,22 +1,6 @@
1
1
  """CLI subcommand: init — scaffold a new project."""
2
2
 
3
- PYPROJECT_TEMPLATE = """\
4
- [build-system]
5
- requires = ["setuptools"]
6
- build-backend = "setuptools.build_meta"
7
-
8
- [project]
9
- name = "{project_name}"
10
- version = "0.1.0"
11
- requires-python = ">=3.12"
12
- dependencies = [
13
- "python-slack-agents<2",
14
- # add packages required by your plugins here
15
- ]
16
-
17
- [tool.setuptools.packages.find]
18
- where = ["src"] # required to import plugins and to build docker images
19
- """
3
+ REQUIREMENTS_TEMPLATE = "python-slack-agents{pin}\n"
20
4
 
21
5
  ENV_EXAMPLE = """\
22
6
  # Full setup guide:
@@ -35,12 +19,10 @@ GITIGNORE = """\
35
19
  .venv/
36
20
  __pycache__/
37
21
  *.pyc
38
- *.egg-info/
39
22
  *.db
40
23
  .DS_Store
41
24
  .idea/
42
25
  .vscode/
43
- dist/
44
26
  """
45
27
 
46
28
  HELLO_WORLD_CONFIG = """\
@@ -76,10 +58,22 @@ def register(subparsers):
76
58
  "init",
77
59
  help="Scaffold a new project in the current directory",
78
60
  )
79
- p.add_argument("project_name", help="Project name (used in pyproject.toml)")
61
+ p.add_argument("project_name", help="Project name (used to derive the src/ package name)")
80
62
  p.set_defaults(handler=execute)
81
63
 
82
64
 
65
+ def _framework_pin() -> str:
66
+ """Return a pip version specifier pinning the current framework version.
67
+
68
+ Falls back to '<2' if the installed version can't be determined."""
69
+ try:
70
+ from importlib.metadata import PackageNotFoundError, version
71
+
72
+ return f"=={version('python-slack-agents')}"
73
+ except (PackageNotFoundError, ImportError):
74
+ return "<2"
75
+
76
+
83
77
  def execute(args):
84
78
  import re
85
79
  from pathlib import Path
@@ -88,9 +82,7 @@ def execute(args):
88
82
  package_name = re.sub(r"[^a-z0-9]+", "_", project_name.lower()).strip("_") or "my_agents"
89
83
 
90
84
  files = {
91
- "pyproject.toml": PYPROJECT_TEMPLATE.format(
92
- project_name=project_name, package_name=package_name
93
- ),
85
+ "requirements.txt": REQUIREMENTS_TEMPLATE.format(pin=_framework_pin()),
94
86
  f"src/{package_name}/__init__.py": "",
95
87
  ".env.example": ENV_EXAMPLE,
96
88
  ".gitignore": GITIGNORE,
@@ -111,18 +103,7 @@ def execute(args):
111
103
  path.write_text(content)
112
104
  print(f"Created {rel_path}")
113
105
 
114
- # Warn about requirements files that won't be picked up by Docker builds
115
- req_files = sorted(Path(".").glob("req*.txt"))
116
- if req_files:
117
- names = ", ".join(f.name for f in req_files)
118
- print(f"WARNING: found {names}")
119
- print(" Docker builds install dependencies from pyproject.toml, not")
120
- print(" requirements files. Move your dependencies into pyproject.toml")
121
- print(" under [project] dependencies or your Docker images will be")
122
- print(" missing packages.")
123
- print()
124
-
125
106
  print("Next steps:")
126
- print(" cp .env.example .env # add your tokens")
127
- print(" pip install -e . # install for development")
128
- print(" slack-agents run agents/hello-world # run the example agent")
107
+ print(" cp .env.example .env # add your tokens")
108
+ print(" pip install -r requirements.txt # install the framework")
109
+ print(" slack-agents run agents/hello-world # run the example agent")