feat(api): Slack thread hears back when an agent it launched finishes
Phase 1, PR D of the Slack agent plan. Depends on nothing open; sits on top of #7583 and #7588.
Summary
- When the Slack agent launches an agent (
agents_create, orworkspaces_createwith agents), the thread gets one reply when that agent's first turn ends: the last thing it said and the PR its workspace is linked to, if any. agents_createnow yields anagent_launchedaction, so the Changes footer and the thread's entity log show it.- New table
slack_agent_launchesrecords each launch (thread session, user, host, workspace, terminal).slack_thread_sessions.quieted_atlets the guard tell "quieted after the launch" from "quiet before it". Migration0118.
How It Works
The API polls the host through the relay. Host-service reports nothing about agent status to the API today, and a host-side callback would mean changes across the agents router, the launch schema, the lifecycle hooks and the terminal-exit path, then a host release before any thread heard back. The poll uses three procedures every host already serves (terminalAgents.listByWorkspace, terminal.list, terminal.hasRunningProcess) on a QStash delay that backs off 30s → 5min and stops at the first Stop, Failed or exit, or after 24h. Worst case is about 290 invocations per launch at maxDuration 60. The completion post is claimed on completed_at with a conditional update, so it happens at most once per launch. The completion logic is independent of the trigger, so a real turn-end callback from the host can replace the poll later without touching it.
Only threads with a session get launches recorded, so this is implicitly gated by the slack-thread-follow-ups flag like the rest of thread sessions.
Manual QA (Superset workspace, flag on)
-
@Superset start an agent in a workspace to fix X→ agent launches, thread shows "Launched agent …" in the Changes footer - When that agent's first turn ends, one reply lands in the thread with its last message; if it opened a PR, the link is there
-
!mutethe thread after launching → no completion reply - Two deliveries of the same completion post once (check
slack_agent_launches.completed_at)
Testing
bun test src/app/api/integrations/slack(112 pass)bunx tsc --noEmit --pretty falsein apps/api and packages/db (exit 0)bunx biome check apps/api packages/db
Known Limitations
- An agent parked on a permission request reads as running, so the thread hears nothing until the 24h expiry.
- The relay call has no timeout of its own; a hung relay burns the invocation and QStash retries.
Rollout / Rollback
- Migration is additive (new table, one nullable column). Rollback is a code revert; the table can stay.
https://claude.ai/code/session_01YDDSQYG6WSZn4jXWTR3Pid
Summary by cubic
Slack threads now receive one follow-up when a host agent launched from agents_create or workspaces_create ends its first turn; previously, they received no completion reply. The reply includes the last harness assistant line, workspace details, and a linked PR when available, and reports failures, exits, or permission waits.
Details
- Adds an
agent_launchedaction to the Changes footer and entity log. - Polls hosts through QStash from 30 seconds up to 5 minutes, stopping after completion or 24 hours.
- Uses a 15-second relay timeout, recoverable completion leases, and an orphan sweep for failed initial schedules.
- Tracks only threaded launches with a host identity, so cloud agents remain untracked.
- A thread quieted after launch suppresses the reply; one quieted before launch still receives it.
- Records outcomes such as waiting, expired, quieted, orphaned, and failed posts without sending duplicates.
Migration
- Migration
0119addsslack_agent_launchesand nullableslack_thread_sessions.quieted_at; rollback only requires reverting the code.
Summary by CodeRabbit
- New Features
- Added Slack notifications when hosted agents finish, including summaries, workspace details, branch information, and linked pull requests.
- Added status reporting for completed, failed, exited, expired, quieted, and unavailable agent runs.
- Added automatic monitoring and follow-up checks while agents are still running.
- Added support for displaying launched agents and workspaces in Slack activity updates.
- Bug Fixes
- Prevented duplicate completion messages during concurrent processing.
- Improved handling of interrupted agents, unreachable hosts, and failed Slack posts.