Skip to content

[Feature] Native Slack task cards for Fast delegations - #1431

Draft
mrubens wants to merge 11 commits into
developfrom
codex/slack-task-cards-wip
Draft

[Feature] Native Slack task cards for Fast delegations#1431
mrubens wants to merge 11 commits into
developfrom
codex/slack-task-cards-wip

Conversation

@mrubens

@mrubens mrubens commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Fast-delegated tasks now stream a native Slack agent task card into the parent thread, showing live progress instead of a static kickoff link.

What this does

  • The Fast launcher opens a native task stream (chat.startStream, plan display mode) alongside the parent-owned kickoff: the card header carries the task title via a plan_update chunk, and a single active row shows the current step with a spinner and a View task link.
  • The worker projects callback events onto the card through run-scoped SDK endpoints (sandboxed workers cannot reach control-plane Redis): todo progress, narrative updates, waiting-for-input, and completion with the task's real output.
  • Card state is keyed by task id and the liveTaskStream payload flag is inherited across snapshot resumes, so resumed runs keep updating the same card.
  • Card callbacks are wired by the payload flag for every payload kind (Fast children run as StandardTask), with an onExit fallback that settles the card even if the completion event is lost.
  • task_update chunks are size-fitted and Slack response warnings are logged, so silently dropped chunks are visible.

Still iterating (WIP)

  • Row ordering: emit the full todo checklist upfront in plan order so rows flow top to bottom
  • Richer sequential detail in the card body (regular-weight details under the bold row title)
  • Possibly replacing the kickoff message's task link with the card once stable

- Wire card callbacks by the liveTaskStream payload flag for every payload
  kind (Fast children run as StandardTask; resumes as SnapshotResume),
  replacing the SlackAppMention-only wiring
- Serve card stream data to workers through runScoped SDK endpoints;
  sandboxed workers cannot reach control-plane Redis
- Key stream data by task id so resumes keep updating the same card
- Inherit liveTaskStream across Fast-child snapshot resumes
- Fit task_update chunks to Slack's 256-char limit before sending and log
  response warnings; oversized chunks were silently dropped, rendering the
  card as an empty message
- Settle the card on Completed in onExit as a fallback when the completion
  event is lost or its Slack call fails
…kickoff

- Start the card in_progress: Slack's timeline view does not render a
  pending-only stream, which delayed card visibility until the worker's
  first update (~sandbox boot time)
- Emit one timeline task entry per todo with per-todo ids and statuses so
  the card shows the checklist progressing, with only changed entries
  re-sent per todo_update
- Finalize outstanding todo entries when the stream settles so no row is
  left spinning
- appendTaskStream/stopTaskStream accept multiple task entries per call
The Slack client does not render a stream whose only content is the
opening task_update chunk (no warnings, chunk accepted); the card only
appeared when the worker's first append arrived. Re-appending the same
entry right after chat.startStream makes the card visible at kickoff.
'plan' display mode renders todo entries as rows inside a single card
instead of separate sequential spinner cards.
…ckmarks

- plan_update chunk carries the task title as the card header, fixing the
  duplicated-title rows
- One active row shows the current step with the spinner and the View task
  link; completed todos accumulate as checkmark rows sent once each, so
  exactly one row is ever animated
- Completion settles the active row to 'Task completed' with the real
  output text
- Drop the assistant thread status for Fast turns: Slack replaces custom
  status text with its own rotating 'Generating response…' placeholders
@roomote-community

roomote-community Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

1 issue outstanding. See task

  • Preserve todo-row delivery state when Slack rejects an append (apps/worker/src/callbacks/slack-live-task-stream.ts:232)
  • Record Slack card-detail delivery only after append succeeds (apps/worker/src/callbacks/slack-live-task-stream.ts:151)

Reviewed dee5fac

… task cards

- The full todo checklist is emitted upfront in plan order, so rows flow
  top to bottom and check off in place; rows stay unchecked until
  completed, keeping the active row as the only animated one
- Narrative and tool events feed a rolling transcript rendered as the
  active row's regular-weight details text under the short bold title
- Relax per-field caps (details 3000 / output 4000): the surface
  demonstrably renders large card content, and Slack response warnings are
  logged if a chunk is ever dropped
Slack accumulates task-card sources per append instead of replacing them,
so the repaint append and worker updates no longer re-send the link.
Comment thread apps/worker/src/callbacks/slack-live-task-stream.ts
…view

Rows appear in start order once a step has actually begun (unchecked, no
animation) instead of rendering the whole pending checklist upfront.
One entry per card: the task title stays constant as the bold header, the
latest progress update (current todo with progress, narrative text,
waiting state) renders as regular-weight details, and completion settles
the card with the run's full output. Drops the row checklist and the plan
container; timeline mode renders a single entry as one card.
Slack appends each chunk's details to the entry body instead of replacing
it (same as sources), which duplicated the launcher's opening line. Each
update is now a newline-prefixed delta, consecutive duplicates are
skipped, the repaint append carries no details, and the length cap
preserves the delta's leading newline. The card body naturally accumulates
a sequential transcript.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant