Skip to content

Releases: CompareNetworks/python-slack-agents

v0.9.2

12 Jun 19:08

Choose a tag to compare

Fixed

  • A2A file artifacts are now visible to the local LLM, so it no longer re-requests artifacts it can't see and can discuss/synthesize them. On the synchronous path the extracted artifact text is folded into the tool result; poller-delivered tasks now also deliver their files (previously dropped); push updates stream to the thread while their content (status text + extracted artifact text) accumulates into the LLM's context, and the LLM gets one turn per actionable status — terminal or needs-input — flushing the accumulated context (progress states never trigger a turn).
  • docs/oauth.md: corrected the OAUTH_SECRET_KEY generation snippet. The documented secrets.token_urlsafe(32) emits URL-safe base64 (-/_, unpadded) that the validator (base64.b64decode(..., validate=True)) rejects; use openssl rand -base64 32 or base64.b64encode(secrets.token_bytes(32)) instead.

Changed

  • Unparseable or oversized file uploads now surface to the LLM as a metadata placeholder instead of rejecting the message, so the agent can respond conversationally.

v0.9.1

10 Jun 00:58

Choose a tag to compare

Added

  • A2A per-user OAuth (auth: { type: oauth2 }). Remote A2A agents can now require per-Slack-user OAuth 2.1: each user authenticates separately and the agent calls on their behalf. Auth metadata is discovered from the Agent Card's securitySchemes.oauth2 (no client_id/scopes in YAML); the flow uses Dynamic Client Registration + authorization-code + PKCE + refresh, the same ephemeral "Authenticate" button, the shared /oauth/* ingress, and the same PUBLIC_URL / OAUTH_SECRET_KEY env contract as mcp_http_oauth. Long-running tasks polled in the background use the user's stored token non-interactively (silent refresh; a "session expired — please re-ask" notice if it can't be refreshed). When push is registered for a task, the token-dependent poller is skipped (push delivers regardless of later token state). See docs/a2a.md.
  • A2A API-key authauth: { type: apiKey, name, value } (sends the raw value as the named header, matching the Agent Card's apiKey scheme), alongside the existing bearer / header / none forms.
  • OAuth user-info logging (MCP and A2A). On first authentication the user's OIDC identity (sub / preferred_username / name / email) is fetched from the userinfo endpoint and logged. The profile scope is now requested and registered alongside openid / offline_access.

Changed

  • The provider-agnostic OAuth flow was extracted from tools/mcp_http_oauth.py into the oauth/ package (scopes, errors, discovery, flow), parameterized by a discovery strategy — RFC 9728 PRM for MCP, Agent Card for A2A. No behavior change for MCP-OAuth.
  • DCR client registration now requests the OIDC baseline (openid, offline_access, profile) explicitly, so strict authorization-server registration policies (e.g. Keycloak's "Allowed Client Scopes") grant the client those scopes rather than rejecting the later authorize with invalid_scope.
  • BREAKING (A2A): removed the name field from slack_agents.a2a.agent. The single tool is now named after the provider's key under tools: (slugified to satisfy LLM tool-name rules); rename the key to rename the tool. Keys are unique within tools:, so two agents never collide.
  • BREAKING (A2A): removed allowed_functions from slack_agents.a2a.agent — an A2A agent exposes exactly one opaque tool, so there was nothing to filter. A stray allowed_functions on an A2A config is ignored at load with a warning.

Fixed

  • The in-process OAuth ingress crashed at startup with TypeError: argument should be a bytes-like object … not 'bool' whenever OAUTH_SECRET_KEY was set — base64.b64decode(key, True) passed True as the positional altchars argument instead of the keyword validate=. This was a latent bug in the shared ingress that affected MCP-OAuth and A2A-OAuth agents alike; it had no test coverage and is now exercised by tests/test_ingress_startup.py.
  • A2A call_tool now maps OAuth-specific failures to actionable results — a user-level authorization denial becomes a permission-denied error naming the missing scope, and an IdP redirect_uri rejection clears the stale client registration so the next attempt self-heals — instead of a generic "contact support".
  • The per-user A2A httpx client is closed if Agent Card resolution fails after construction, avoiding a connection-pool leak on the background poller's out-of-band re-auth path.

v0.9.0

08 Jun 02:16

Choose a tag to compare

Added

  • A2A push notifications (receiving). A push-capable agent (capabilities.pushNotifications) can deliver task updates — status messages and file artifacts — to the Slack thread out-of-band, including reports that arrive after a synchronous reply. Opt in per agent with push_notifications: true. The framework registers the webhook inline on the first send with a random per-task token, validates the X-A2A-Notification-Token header, correlates by taskId, and de-duplicates by message/artifact id (the server re-pushes the immediate reply). The OAuth HTTP sidecar is generalized into a shared ingress (one listener starting for OAuth or push), configured by the new PUBLIC_URL / HTTP_BIND_HOST / HTTP_BIND_PORT env vars (see Changed). Verified end-to-end against a live agent. See docs/a2a.md.
  • Agent2Agent (A2A) protocol integration over the official a2a-sdk (1.x, protobuf), isolated behind slack_agents.a2a.client. Two topologies: slack_agents.a2a.agent exposes a remote A2A agent as a single free-text tool a real LLM delegates to (Option A, smart routing), and slack_agents.a2a.proxy turns Slack into a dumb frontend for one agent (Option B, dev/debugging). Features: per-thread contextId + taskId threading for correct multi-turn (input-required) conversations; synchronous replies plus detached background polling with out-of-band delivery for long-running (working) tasks (real LLMs re-process the result, the proxy posts it raw); bidirectional file attachments (Slack upload → A2A raw part, file artifact → Slack upload); static bearer/header auth. Includes an env-gated live integration test (A2A_TEST_URL). See docs/a2a.md.
  • docs/private-repo.md — "Protecting secrets in your overlay" section covering GitHub push protection (server-side block that survives --no-verify), a gitleaks pre-commit hook, and a one-time trufflehog history sweep. Aimed at overlay maintainers whose configs reference Slack tokens, LLM API keys, and OAuth client secrets via {ENV_VAR} placeholders.
  • slack-agents init now prints a visible "SECURITY: protect your secrets before pushing" banner at the end of scaffolding, linking to the new docs section.
  • SECURITY.md — pointer for overlay maintainers to the overlay security guidance.

Changed

  • BREAKING (OAuth): the in-process HTTP listener is now a shared ingress for OAuth callbacks and A2A push. Its env vars were renamed — OAUTH_PUBLIC_URLPUBLIC_URL, OAUTH_BIND_HOSTHTTP_BIND_HOST, OAUTH_BIND_PORTHTTP_BIND_PORT — with no aliases. (OAUTH_SECRET_KEY is unchanged.) Agents using OAuth must rename these in their environment. The startup validator fails fast with a clear message naming PUBLIC_URL when OAuth or push is configured but the var is missing.

Security

  • Dependency security updates clearing all open advisories. Lifted the speculative cryptography upper cap (<46) that had blocked the patch (the fix shipped in the next major) and raised the floor to >=46.0.7; refreshed the lockfile to current releases: cryptography 48, aiohttp 3.14.1, pillow 12.2.0, lxml 6.1.1, urllib3 2.7.0, python-multipart 0.0.32, starlette 1.2.1, anthropic 0.107.1, pygments 2.20.0.

0.8.1 — fix oauth_clients cache key collision

07 May 18:33

Choose a tag to compare

Fixed

  • oauth_clients cache is now keyed by (server_id, redirect_uri) instead of server_id alone. Two mcp_http_oauth providers pointing at the same MCP server but with different OAUTH_PUBLIC_URL values (e.g. agents sharing a database, or a single agent whose tunnel hostname rotates) used to collide on the cached client registration; the second one would reuse a row whose redirect_uri the IdP no longer accepted, producing Invalid parameter: redirect_uri from the IdP.
  • mcp_http_oauth.Provider.call_tool now detects an IdP Invalid parameter: redirect_uri (or redirect_uri_mismatch) rejection, deletes the stale cached client registration and the user's cached tokens, and surfaces a structured system_error with code="redirect_uri_mismatch" so the LLM can explain the situation. The next call re-registers a fresh client and prompts for re-auth.

Migration

The oauth_clients table primary key changed from (server_id) to (server_id, redirect_uri). There is no automatic migration: any rows from 0.8.0 will be re-created on demand the first time each (server_id, redirect_uri) pair is used, leaving harmless orphan rows behind. Operators who want a clean slate can DELETE FROM oauth_clients; before upgrading.

Full Changelog: 0.8.0...0.8.1

0.8.0 — OAuth-authenticated MCP servers

06 May 16:37

Choose a tag to compare

Highlights

  • Per-Slack-user OAuth for MCP servers via the new slack_agents.tools.mcp_http_oauth provider. Each Slack user authenticates separately; refresh tokens are AES-GCM-encrypted at rest. An in-process aiohttp callback listener runs alongside the Slack Bolt connection — no public ingress beyond a single /oauth/callback path. See docs/oauth.md.
  • Unified tool-error schema (make_tool_error in slack_agents.tools.base). Every built-in tool now emits structured JSON errors that the LLM can interpret consistently — with error, code, recovery, and details fields. See docs/tools.md#tool-error-schema.
  • LLM provider error classification. Transient errors (overloaded_error, rate_limit_error, etc.) get user-friendly messages and log at WARNING; configuration errors stay ERROR with traceback.

Migration

No breaking changes. Existing agents run unchanged. To use OAuth-protected MCP servers, set OAUTH_PUBLIC_URL and OAUTH_SECRET_KEY env vars and configure an mcp_http_oauth provider in your agent's config.yaml.

Custom tool providers continue to work with the existing ToolResult shape, but should adopt make_tool_error for error returns to give the LLM uniform structured errors.

See CHANGELOG.md for the full list.

0.7.0

14 Apr 16:57

Choose a tag to compare

Changed

  • 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.
  • 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.
  • 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.
  • Scaffolder .gitignore drops *.egg-info/ and dist/ (overlays no longer build wheels).

Added

  • _auto_extend_sys_path() helper in slack_agents.config, called from load_agent_config() before any plugin import.
  • End-to-end overlay integration test covering scaffold → auto-sys.path → custom provider resolution, plus Dockerfile-shape assertions.

Removed

  • build-docker no longer rejects overlays with req*.txt files — that file is now the expected input.
  • slack-agents init no longer emits pyproject.toml or warns about requirements files.
  • "Framework Development" section removed from docs/setup.md — contributors see CONTRIBUTING.md instead, keeping user-facing docs focused on overlay users.

Docs

  • 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].
  • README.md "Project Structure" and "Extending" sections rewritten to match.

Migration

  • Delete your overlay's pyproject.toml and any *.egg-info/ directories.
  • Add a requirements.txt pinning python-slack-agents==0.7.0 (or <2).
  • Run pip install -r requirements.txt.
  • Custom providers under src/<pkg>/ work without pip install -e ..

v0.6.3

31 Mar 16:51

Choose a tag to compare

What's Changed

  • fix: Preserve agent name in Docker image so multiple agents sharing a database are distinguishable. Previously all Docker-built agents used agent_name = "agent".

v0.6.2

20 Mar 00:59

Choose a tag to compare

What's New

Added

  • Canvas user-level authorization — tools enforce requesting user's access level via files.info metadata
  • Canvas file importer (application/vnd.slack-docs) — users can attach canvases to messages
  • file_id field on InputFile — file import pipeline now passes Slack file IDs to handlers
  • org_access parameter on canvas_access_add for workspace-wide access

Changed

  • Canvas tool descriptions instruct the LLM to guide users to attach canvases via Slack's + button (never ask for IDs)
  • Canvas tool errors now return structured JSON instead of plain text

Removed

  • canvas_list tool (scaling concern with batch files.info; users discover canvases via Slack UI)
  • channel_id parameter from canvas_create (standalone canvases only)
  • channel_ids parameter from canvas_access_add and canvas_access_remove

Full Changelog: v0.6.1...v0.6.2

v0.6.1

19 Mar 18:58

Choose a tag to compare

What's New

  • Improved slack-agents init — now generates .gitignore, .env.example with setup guide link and token instructions, and shows proposed content when skipping existing files
  • build-docker shows required env vars — after build (and push), lists all {ENV_VAR} patterns from the agent's config so you know what secrets to provide at runtime
  • req*.txt detectioninit warns and build-docker errors if requirements files are found, since Docker builds use pyproject.toml dependencies
  • YAML comment safety — commented-out {ENV_VAR} patterns no longer cause KeyError at startup
  • Updated setup flow — docs now use venv-first approach: create venv, install package, then slack-agents init

v0.6.0

19 Mar 00:20

Choose a tag to compare

What's New

  • slack-agents init <project_name> — new CLI command that scaffolds a project with pyproject.toml, src/, .env.example, and a hello-world agent. Sets up the required structure for custom providers and Docker builds.

  • AI agent discoverability — added llms.txt and llms-full.txt following the llms.txt convention. llms-full.txt is bundled in the PyPI wheel so AI agents can read the full reference locally after pip install.

  • Simplified Dockerfile — builds now work for both the framework repo and user projects without requiring README.md or llms-full.txt in the build context.

  • Documentation — new "Project Structure" section in README explaining the pyproject.toml + src/ requirement for custom providers. Updated docs for the init command, organizing agents, and the release process.