python-slack-agents 0.6.3__tar.gz → 0.8.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 (136) hide show
  1. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/.gitignore +5 -0
  2. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/AGENTS.md +8 -6
  3. python_slack_agents-0.8.0/CHANGELOG.md +140 -0
  4. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/CONTRIBUTING.md +6 -0
  5. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/PKG-INFO +39 -12
  6. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/README.md +37 -11
  7. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/cli.md +1 -1
  8. python_slack_agents-0.8.0/docs/oauth.md +292 -0
  9. python_slack_agents-0.8.0/docs/private-repo.md +81 -0
  10. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/setup.md +6 -14
  11. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/tools.md +91 -2
  12. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/llms-full.txt +125 -28
  13. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/pyproject.toml +2 -1
  14. python_slack_agents-0.8.0/src/slack_agents/Dockerfile +38 -0
  15. python_slack_agents-0.8.0/src/slack_agents/__init__.py +78 -0
  16. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/agent_loop.py +17 -2
  17. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/build_docker.py +0 -12
  18. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/init.py +18 -37
  19. python_slack_agents-0.8.0/src/slack_agents/config.py +225 -0
  20. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/main.py +5 -1
  21. python_slack_agents-0.8.0/src/slack_agents/oauth/__init__.py +6 -0
  22. python_slack_agents-0.8.0/src/slack_agents/oauth/crypto.py +47 -0
  23. python_slack_agents-0.8.0/src/slack_agents/oauth/prompts.py +67 -0
  24. python_slack_agents-0.8.0/src/slack_agents/oauth/server.py +124 -0
  25. python_slack_agents-0.8.0/src/slack_agents/oauth/state.py +106 -0
  26. python_slack_agents-0.8.0/src/slack_agents/oauth/storage.py +122 -0
  27. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/agent.py +191 -25
  28. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/storage/base.py +51 -0
  29. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/storage/postgres.py +101 -1
  30. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/storage/postgres.sql +23 -0
  31. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/storage/sqlite.py +88 -1
  32. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/storage/sqlite.sql +23 -0
  33. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/base.py +69 -1
  34. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/canvas.py +40 -21
  35. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/file_exporter.py +23 -3
  36. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/mcp_http.py +25 -3
  37. python_slack_agents-0.8.0/src/slack_agents/tools/mcp_http_oauth.py +1044 -0
  38. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/user_context.py +45 -18
  39. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_cli.py +39 -0
  40. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_config.py +65 -0
  41. python_slack_agents-0.8.0/tests/test_init.py +88 -0
  42. python_slack_agents-0.8.0/tests/test_llm_error_classification.py +72 -0
  43. python_slack_agents-0.8.0/tests/test_load_plugin.py +47 -0
  44. python_slack_agents-0.8.0/tests/test_mcp_http_oauth.py +471 -0
  45. python_slack_agents-0.8.0/tests/test_oauth_crypto.py +72 -0
  46. python_slack_agents-0.8.0/tests/test_oauth_integration.py +165 -0
  47. python_slack_agents-0.8.0/tests/test_oauth_prompts.py +68 -0
  48. python_slack_agents-0.8.0/tests/test_oauth_server.py +105 -0
  49. python_slack_agents-0.8.0/tests/test_oauth_state.py +78 -0
  50. python_slack_agents-0.8.0/tests/test_oauth_storage.py +121 -0
  51. python_slack_agents-0.8.0/tests/test_oauth_validation.py +77 -0
  52. python_slack_agents-0.8.0/tests/test_overlay_integration.py +64 -0
  53. python_slack_agents-0.8.0/tests/test_storage_oauth.py +98 -0
  54. python_slack_agents-0.8.0/tests/test_tool_errors.py +92 -0
  55. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/uv.lock +30 -46
  56. python_slack_agents-0.6.3/CHANGELOG.md +0 -80
  57. python_slack_agents-0.6.3/docs/private-repo.md +0 -65
  58. python_slack_agents-0.6.3/src/slack_agents/Dockerfile +0 -28
  59. python_slack_agents-0.6.3/src/slack_agents/__init__.py +0 -26
  60. python_slack_agents-0.6.3/src/slack_agents/config.py +0 -119
  61. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/.dockerignore +0 -0
  62. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/.env.example +0 -0
  63. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/.github/workflows/ci.yml +0 -0
  64. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/.github/workflows/publish.yml +0 -0
  65. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/.pre-commit-config.yaml +0 -0
  66. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/CODE_OF_CONDUCT.md +0 -0
  67. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/LICENSE +0 -0
  68. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/SECURITY.md +0 -0
  69. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/README.md +0 -0
  70. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/docs-assistant/config.yaml +0 -0
  71. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/docs-assistant/system_prompt.txt +0 -0
  72. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/hello-world/config.yaml +0 -0
  73. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/hello-world/system_prompt.txt +0 -0
  74. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/kitchen-sink/config.yaml +0 -0
  75. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/agents/kitchen-sink/system_prompt.txt +0 -0
  76. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/access-control.md +0 -0
  77. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/agents.md +0 -0
  78. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/canvas.md +0 -0
  79. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/deployment.md +0 -0
  80. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/llm.md +0 -0
  81. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/media/demo.gif +0 -0
  82. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/observability.md +0 -0
  83. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/slack-app-manifest.json +0 -0
  84. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/storage.md +0 -0
  85. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/docs/user-context.md +0 -0
  86. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/llms.txt +0 -0
  87. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/access/__init__.py +0 -0
  88. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/access/allow_all.py +0 -0
  89. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/access/allow_list.py +0 -0
  90. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/access/base.py +0 -0
  91. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/__init__.py +0 -0
  92. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/export_conversations.py +0 -0
  93. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/export_conversations_html.py +0 -0
  94. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/export_usage.py +0 -0
  95. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/export_usage_csv.py +0 -0
  96. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/healthcheck.py +0 -0
  97. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/cli/run.py +0 -0
  98. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/conversations.py +0 -0
  99. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/files.py +0 -0
  100. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/llm/__init__.py +0 -0
  101. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/llm/anthropic.py +0 -0
  102. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/llm/base.py +0 -0
  103. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/llm/openai.py +0 -0
  104. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/observability.py +0 -0
  105. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/py.typed +0 -0
  106. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/scripts/__init__.py +0 -0
  107. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/scripts/download_fonts.py +0 -0
  108. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/scripts/generate_llms_full.py +0 -0
  109. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/__init__.py +0 -0
  110. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/actions.py +0 -0
  111. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/canvas_auth.py +0 -0
  112. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/canvases.py +0 -0
  113. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/files.py +0 -0
  114. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/format.py +0 -0
  115. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/streaming.py +0 -0
  116. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/streaming_formatter.py +0 -0
  117. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/slack/tool_blocks.py +0 -0
  118. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/storage/__init__.py +0 -0
  119. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/__init__.py +0 -0
  120. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/canvas_importer.py +0 -0
  121. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/src/slack_agents/tools/file_importer.py +0 -0
  122. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/__init__.py +0 -0
  123. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_access.py +0 -0
  124. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_agent_loop.py +0 -0
  125. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_canvas_auth.py +0 -0
  126. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_canvas_importer.py +0 -0
  127. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_conversations.py +0 -0
  128. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_cost.py +0 -0
  129. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_export_documents.py +0 -0
  130. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_export_usage.py +0 -0
  131. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_file_extractors.py +0 -0
  132. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_format.py +0 -0
  133. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_llm_factory.py +0 -0
  134. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_mcp_client.py +0 -0
  135. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_openai_convert.py +0 -0
  136. {python_slack_agents-0.6.3 → python_slack_agents-0.8.0}/tests/test_tool_blocks.py +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]
@@ -34,4 +37,6 @@ agents-local/
34
37
 
35
38
  # Certificates
36
39
  *.pem
40
+ you c
37
41
  /ONGOING.md
42
+ /docs/superpowers/
@@ -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
 
@@ -0,0 +1,140 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.8.0] - 2026-05-06
10
+
11
+ ### Added
12
+
13
+ - `slack_agents.tools.mcp_http_oauth` — OAuth-authenticated MCP tool provider with per-Slack-user tokens. Each user authenticates separately to the upstream service; refresh tokens are AES-GCM-encrypted at rest. The provider runs an in-process aiohttp callback listener alongside Slack Bolt's WebSocket connection — no public ingress beyond a single `/oauth/callback` path. Includes Dynamic Client Registration with PRM-driven scope catalog, scope-merging on every authorize request (OIDC baseline + cached-token scopes + server-hinted scopes), and post-step-up permission-denied detection. See `docs/oauth.md`.
14
+ - `slack_agents.oauth/` package — signed-state codec, HKDF/AES-GCM crypto, callback listener, ephemeral auth-prompt builder, `DBTokenStorage` bridging the MCP SDK's `TokenStorage` Protocol to the agent's storage backend.
15
+ - `oauth_tokens` and `oauth_clients` tables on both SQLite and PostgreSQL backends (created idempotently at startup).
16
+ - `FrameworkContext` injection in `load_plugin` — providers that declare a `framework_ctx` parameter receive a shared object holding the bot token, Slack client, storage backend, and OAuth pending-flows registry. Existing providers are unaffected.
17
+ - `validate_oauth_env(tools_config)` consolidated startup check. Required env vars when at least one `mcp_http_oauth` provider is configured: `OAUTH_PUBLIC_URL`, `OAUTH_SECRET_KEY`. Optional: `OAUTH_BIND_HOST` (default `0.0.0.0`), `OAUTH_BIND_PORT` (default `8080`). Missing/malformed values produce a single, actionable error and refuse to start.
18
+ - Eager-auth pre-LLM hook in `SlackAgent` — each user's first message triggers OAuth setup before the LLM is invoked, so the LLM sees real tool lists rather than an empty/placeholder set.
19
+ - `make_tool_error(...)` helper plus `ERROR_*` and `RECOVERY_*` constants in `slack_agents.tools.base`. Uniform JSON schema for tool-error payloads in `ToolResult.content` so the LLM consuming a tool result can reason about errors (permission_denied / system_error / input_error / auth_setup_failed) uniformly. The `recovery` enum (retry / contact_admin / contact_support / abort) drives how the LLM should advise the user. See `docs/tools.md` "Tool error schema".
20
+ - LLM error classification in `slack/agent.py` — transient provider errors (`overloaded_error`, `rate_limit_error`, `api_error`, `timeout_error`) produce friendly user messages and log at WARNING (no traceback noise); configuration errors (`authentication_error`, `permission_error`, `not_found_error`, `invalid_request_error`) stay ERROR with full traceback.
21
+ - `cryptography` runtime dependency (HKDF + AES-GCM).
22
+ - `docs/oauth.md` — operator guide, scope-handling story, MCP SDK workarounds, troubleshooting (Trusted Hosts and Allowed Client Scopes policy gates, post-step-up permission denial).
23
+
24
+ ### Changed
25
+
26
+ - Every built-in tool error site (`mcp_http`, `mcp_http_oauth`, `canvas`, `user_context`, `file_exporter`, plus `agent_loop`'s unknown-tool fallback) now emits the unified structured-error JSON schema in `ToolResult.content` when `is_error=True`. Custom tools should use `make_tool_error(...)`.
27
+ - The Slack-user-facing message on unrecognized exceptions ("Sorry, I encountered an error processing your request.") is now the fallback only — known LLM-provider errors get specific messages instead.
28
+ - `docs/tools.md` — example uses `make_tool_error` for the unknown-tool branch; new "Tool error schema" section.
29
+
30
+ ## [0.7.0] - 2026-04-14
31
+
32
+ ### Changed
33
+
34
+ - **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.
35
+ - 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.
36
+ - 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.
37
+ - Scaffolder `.gitignore` drops `*.egg-info/` and `dist/` (overlays no longer build wheels).
38
+
39
+ ### Added
40
+
41
+ - `_auto_extend_sys_path()` helper in `slack_agents.config`, called from `load_agent_config()` before any plugin import.
42
+ - End-to-end overlay integration test covering scaffold → auto-sys.path → custom provider resolution, plus Dockerfile-shape assertions.
43
+
44
+ ### Removed
45
+
46
+ - `build-docker` no longer rejects overlays with `req*.txt` files — that file is now the expected input.
47
+ - `slack-agents init` no longer emits `pyproject.toml` or warns about requirements files.
48
+ - "Framework Development" section removed from `docs/setup.md` — contributors see `CONTRIBUTING.md` instead, keeping user-facing docs focused on overlay users.
49
+
50
+ ### Docs
51
+
52
+ - 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]`.
53
+ - `README.md` "Project Structure" and "Extending" sections rewritten to match.
54
+
55
+ ### Migration
56
+
57
+ - Delete your overlay's `pyproject.toml` and any `*.egg-info/` directories.
58
+ - Add a `requirements.txt` pinning `python-slack-agents==0.7.0` (or `<2`).
59
+ - Run `pip install -r requirements.txt`.
60
+ - Custom providers under `src/<pkg>/` work without `pip install -e .`.
61
+
62
+ ## [0.6.3] - 2026-03-31
63
+
64
+ ### Fixed
65
+
66
+ - Preserve agent name in Docker image for multi-agent database support (`COPY` uses `${AGENT_NAME}` so each image's agent directory keeps its identity).
67
+ - Remove `libmupdf-dev` from the Docker image — image size down to 354 MB.
68
+
69
+ ## [0.6.2] - 2026-03-19
70
+
71
+ ### Added
72
+
73
+ - Canvas user-level authorization — tools enforce requesting user's access level via `files.info` metadata
74
+ - Canvas file importer (`application/vnd.slack-docs`) — users can attach canvases to messages
75
+ - `file_id` field on `InputFile` — file import pipeline now passes Slack file IDs to handlers
76
+ - `org_access` parameter on `canvas_access_add` for workspace-wide access
77
+
78
+ ### Changed
79
+
80
+ - Canvas tool descriptions instruct the LLM to guide users to attach canvases via Slack's + button (never ask for IDs)
81
+ - Canvas tool errors now return structured JSON instead of plain text
82
+
83
+ ### Removed
84
+
85
+ - `canvas_list` tool (scaling concern with batch `files.info`; users discover canvases via Slack UI)
86
+ - `channel_id` parameter from `canvas_create` (standalone canvases only)
87
+ - `channel_ids` parameter from `canvas_access_add` and `canvas_access_remove`
88
+
89
+ ## [0.6.1] - 2026-03-19
90
+
91
+ ### Added
92
+
93
+ - `slack-agents init` now generates `.gitignore`
94
+ - `.env.example` template includes comments explaining where to get each token and links to setup guide
95
+ - `build-docker` lists required environment variables after build completes
96
+ - `build-docker` errors if `req*.txt` files are found (dependencies must be in `pyproject.toml`)
97
+ - `init` warns when `req*.txt` files are found with migration instructions
98
+
99
+ ### Changed
100
+
101
+ - `pyproject.toml` template uses `python-slack-agents<2` (no minimum pin)
102
+ - Setup flow uses venv-first approach: create venv, install package, then `slack-agents init`
103
+ - Updated README, docs/setup.md, and docs/private-repo.md with new setup flow
104
+
105
+ ### Fixed
106
+
107
+ - Config loader now strips YAML comments before env var interpolation — commented-out `{ENV_VAR}` patterns no longer cause `KeyError`
108
+ - `init` shows proposed file content when skipping existing files
109
+
110
+ ## [0.6.0] - 2026-03-18
111
+
112
+ ### Added
113
+
114
+ - `slack-agents init <project_name>` CLI command to scaffold new projects
115
+ - `llms.txt` and `llms-full.txt` for AI agent discoverability
116
+ - `llms-full.txt` bundled in PyPI wheel
117
+ - Script to generate `llms-full.txt` from docs (`src/slack_agents/scripts/generate_llms_full.py`)
118
+ - "Project Structure" section in README
119
+ - Release process documentation in AGENTS.md
120
+
121
+ ### Changed
122
+
123
+ - Simplified Dockerfile: empty placeholders for README.md and llms-full.txt so builds work for both framework and user projects
124
+ - Updated docs/private-repo.md to use `slack-agents init`
125
+ - Updated docs/cli.md with `init` command reference
126
+
127
+ ## [0.5.0] - 2025-03-13
128
+
129
+ ### Added
130
+
131
+ - Plugin architecture for LLM providers, storage backends, and tools
132
+ - Anthropic and OpenAI LLM providers
133
+ - SQLite and PostgreSQL storage providers
134
+ - MCP over HTTP tool provider
135
+ - Built-in document export tools (PDF, DOCX, XLSX, CSV, PPTX)
136
+ - Streaming output with native Slack table rendering
137
+ - Socket Mode support (no public URL required)
138
+ - OpenTelemetry observability
139
+ - `{ENV_VAR}` interpolation in agent configs
140
+ - Per-agent Docker builds via `docker-build-and-push.sh`
@@ -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.3
3
+ Version: 0.8.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
@@ -21,6 +21,7 @@ Requires-Dist: aiohttp<4,>=3.9
21
21
  Requires-Dist: aiosqlite<1,>=0.20
22
22
  Requires-Dist: anthropic<1,>=0.40
23
23
  Requires-Dist: asyncpg<1,>=0.30
24
+ Requires-Dist: cryptography<46,>=42
24
25
  Requires-Dist: fpdf2<3,>=2.8
25
26
  Requires-Dist: httpx<1,>=0.27
26
27
  Requires-Dist: mcp<2,>=1.0
@@ -63,7 +64,7 @@ Each agent is a directory with two files: a `config.yaml` and a `system_prompt.t
63
64
 
64
65
  **LLM providers** — Anthropic and OpenAI built in, plus any OpenAI-compatible API (Mistral, Groq, Together, Ollama, vLLM). Extend to any other provider by implementing a simple base class.
65
66
 
66
- **Tool calling with MCP** — Connect any [MCP server](https://modelcontextprotocol.io/) over HTTP. Tools are discovered automatically, executed in parallel, and filtered with regex patterns. No tool registration boilerplate.
67
+ **Tool calling with MCP** — Connect any [MCP server](https://modelcontextprotocol.io/) over HTTP. Tools are discovered automatically, executed in parallel, and filtered with regex patterns. No tool registration boilerplate. **OAuth-protected MCP servers are supported with per-Slack-user tokens** — see [docs/oauth.md](docs/oauth.md).
67
68
 
68
69
  **File handling** — Agents can read files your users upload (PDF, DOCX, XLSX, PPTX, CSV, images) and generate documents back (PDF, DOCX, XLSX, CSV, PPTX). All built in, no extra setup.
69
70
 
@@ -90,9 +91,9 @@ pip install python-slack-agents
90
91
  # Scaffold the project
91
92
  slack-agents init my-agents
92
93
 
93
- # Add your tokens and install for development
94
- cp .env.example .env # add your Slack and LLM tokens
95
- pip install -e .
94
+ # Add your tokens and install framework + deps
95
+ cp .env.example .env # add your Slack and LLM tokens
96
+ pip install -r requirements.txt
96
97
 
97
98
  # Run the hello-world agent
98
99
  slack-agents run agents/hello-world
@@ -241,23 +242,45 @@ tools:
241
242
  - "get_document" # exact match works too
242
243
  ```
243
244
 
245
+ For MCP servers that require OAuth 2.1 (per-user authentication), use `mcp_http_oauth` — same auto-discovery, with each Slack user authenticating separately to the upstream service:
246
+
247
+ ```yaml
248
+ tools:
249
+ my-oauth-mcp:
250
+ type: slack_agents.tools.mcp_http_oauth
251
+ url: "https://my-server.example.com/mcp"
252
+ allowed_functions: [".*"]
253
+ ```
254
+
255
+ Tokens are persisted per Slack user, refresh tokens are AES-GCM-encrypted at rest, and an in-process callback listener handles the OAuth dance alongside the Slack Bolt connection. See [docs/oauth.md](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/oauth.md) for setup (env vars, tunnel for local dev, scope handling, troubleshooting).
256
+
244
257
  ## Project Structure
245
258
 
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:
259
+ Your overlay is a plain git repo not a Python package. You edit configs, commit, and run; there's no
260
+ install-the-overlay-as-a-package step. A typical layout looks like:
247
261
 
248
262
  ```
249
263
  my-agents/
250
- ├── pyproject.toml # declares python-slack-agents as dependency
251
- ├── src/
252
- │ └── my_agents/ # your custom providers go here
253
- │ └── __init__.py
264
+ ├── requirements.txt # pins python-slack-agents (and any extra deps)
265
+ ├── .env.example
266
+ ├── .gitignore
254
267
  ├── agents/
255
268
  │ └── my-agent/
256
269
  │ ├── config.yaml
257
270
  │ └── system_prompt.txt
258
- └── .env
271
+ └── src/ # optional — only if you add custom providers
272
+ └── my_agents/
273
+ └── __init__.py
259
274
  ```
260
275
 
276
+ Two conventions to know:
277
+
278
+ - **`src/` holds custom Python.** On `slack-agents run`, the framework walks up from the agent directory,
279
+ finds the nearest `src/` sibling, and prepends it to `sys.path`. Anything under `src/<pkg>/...` is
280
+ importable as `<pkg>.…` with no install step.
281
+ - **`requirements.txt` pins your framework version and any extra Python deps.** `pip install -r requirements.txt`
282
+ is the only install command you ever run.
283
+
261
284
  `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
285
 
263
286
  ## Extending
@@ -281,7 +304,10 @@ class Provider(BaseLLMProvider):
281
304
  ...
282
305
  ```
283
306
 
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.
307
+ After you drop a module under `src/`, it's picked up automatically on the next `slack-agents run` —
308
+ the framework prepends `./src` to `sys.path` at startup. The same mechanism works inside Docker:
309
+ the bundled Dockerfile installs dependencies from `requirements.txt` and copies your `src/` into the
310
+ image, so custom providers resolve in production too.
285
311
 
286
312
  See the docs for the full interface for each component:
287
313
 
@@ -313,6 +339,7 @@ To create a Slack app, use the manifest in [`docs/slack-app-manifest.json`](http
313
339
  - [Setup](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/setup.md) — installation and Slack app creation
314
340
  - [Agents](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/agents.md) — creating and configuring agents
315
341
  - [Tools](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/tools.md) — MCP servers and custom tool providers
342
+ - [OAuth-protected MCP servers](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/oauth.md) — per-Slack-user OAuth for MCP servers requiring authentication
316
343
  - [LLM](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/llm.md) — supported providers and adding your own
317
344
  - [Storage](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/storage.md) — SQLite, PostgreSQL, and custom backends
318
345
  - [Access control](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/access-control.md) — controlling who can use an agent
@@ -17,7 +17,7 @@ Each agent is a directory with two files: a `config.yaml` and a `system_prompt.t
17
17
 
18
18
  **LLM providers** — Anthropic and OpenAI built in, plus any OpenAI-compatible API (Mistral, Groq, Together, Ollama, vLLM). Extend to any other provider by implementing a simple base class.
19
19
 
20
- **Tool calling with MCP** — Connect any [MCP server](https://modelcontextprotocol.io/) over HTTP. Tools are discovered automatically, executed in parallel, and filtered with regex patterns. No tool registration boilerplate.
20
+ **Tool calling with MCP** — Connect any [MCP server](https://modelcontextprotocol.io/) over HTTP. Tools are discovered automatically, executed in parallel, and filtered with regex patterns. No tool registration boilerplate. **OAuth-protected MCP servers are supported with per-Slack-user tokens** — see [docs/oauth.md](docs/oauth.md).
21
21
 
22
22
  **File handling** — Agents can read files your users upload (PDF, DOCX, XLSX, PPTX, CSV, images) and generate documents back (PDF, DOCX, XLSX, CSV, PPTX). All built in, no extra setup.
23
23
 
@@ -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
@@ -195,23 +195,45 @@ tools:
195
195
  - "get_document" # exact match works too
196
196
  ```
197
197
 
198
+ For MCP servers that require OAuth 2.1 (per-user authentication), use `mcp_http_oauth` — same auto-discovery, with each Slack user authenticating separately to the upstream service:
199
+
200
+ ```yaml
201
+ tools:
202
+ my-oauth-mcp:
203
+ type: slack_agents.tools.mcp_http_oauth
204
+ url: "https://my-server.example.com/mcp"
205
+ allowed_functions: [".*"]
206
+ ```
207
+
208
+ Tokens are persisted per Slack user, refresh tokens are AES-GCM-encrypted at rest, and an in-process callback listener handles the OAuth dance alongside the Slack Bolt connection. See [docs/oauth.md](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/oauth.md) for setup (env vars, tunnel for local dev, scope handling, troubleshooting).
209
+
198
210
  ## Project Structure
199
211
 
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:
212
+ Your overlay is a plain git repo not a Python package. You edit configs, commit, and run; there's no
213
+ install-the-overlay-as-a-package step. A typical layout looks like:
201
214
 
202
215
  ```
203
216
  my-agents/
204
- ├── pyproject.toml # declares python-slack-agents as dependency
205
- ├── src/
206
- │ └── my_agents/ # your custom providers go here
207
- │ └── __init__.py
217
+ ├── requirements.txt # pins python-slack-agents (and any extra deps)
218
+ ├── .env.example
219
+ ├── .gitignore
208
220
  ├── agents/
209
221
  │ └── my-agent/
210
222
  │ ├── config.yaml
211
223
  │ └── system_prompt.txt
212
- └── .env
224
+ └── src/ # optional — only if you add custom providers
225
+ └── my_agents/
226
+ └── __init__.py
213
227
  ```
214
228
 
229
+ Two conventions to know:
230
+
231
+ - **`src/` holds custom Python.** On `slack-agents run`, the framework walks up from the agent directory,
232
+ finds the nearest `src/` sibling, and prepends it to `sys.path`. Anything under `src/<pkg>/...` is
233
+ importable as `<pkg>.…` with no install step.
234
+ - **`requirements.txt` pins your framework version and any extra Python deps.** `pip install -r requirements.txt`
235
+ is the only install command you ever run.
236
+
215
237
  `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
238
 
217
239
  ## Extending
@@ -235,7 +257,10 @@ class Provider(BaseLLMProvider):
235
257
  ...
236
258
  ```
237
259
 
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.
260
+ After you drop a module under `src/`, it's picked up automatically on the next `slack-agents run` —
261
+ the framework prepends `./src` to `sys.path` at startup. The same mechanism works inside Docker:
262
+ the bundled Dockerfile installs dependencies from `requirements.txt` and copies your `src/` into the
263
+ image, so custom providers resolve in production too.
239
264
 
240
265
  See the docs for the full interface for each component:
241
266
 
@@ -267,6 +292,7 @@ To create a Slack app, use the manifest in [`docs/slack-app-manifest.json`](http
267
292
  - [Setup](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/setup.md) — installation and Slack app creation
268
293
  - [Agents](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/agents.md) — creating and configuring agents
269
294
  - [Tools](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/tools.md) — MCP servers and custom tool providers
295
+ - [OAuth-protected MCP servers](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/oauth.md) — per-Slack-user OAuth for MCP servers requiring authentication
270
296
  - [LLM](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/llm.md) — supported providers and adding your own
271
297
  - [Storage](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/storage.md) — SQLite, PostgreSQL, and custom backends
272
298
  - [Access control](https://github.com/CompareNetworks/python-slack-agents/blob/main/docs/access-control.md) — controlling who can use an agent
@@ -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