Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0416373
feat(slack): per-turn reaction controller with phases, and fix premat…
penso Jul 24, 2026
95eaea7
feat(slack): reconnect supervision, Block Kit rendering, and assistan…
penso Jul 24, 2026
141f573
refactor(channels): extract activity types to keep files under size l…
penso Jul 24, 2026
b729dea
test(slack): allow unwrap in blocks test module for --all-targets clippy
penso Jul 24, 2026
3109858
fix(slack): split long fenced code into balanced Block Kit fences
penso Jul 24, 2026
ffe0548
refactor(slack): bound reaction worker lifetime and reuse the HTTP cl…
penso Jul 25, 2026
8193085
fix(slack): finalize replaced reaction controller and test the state …
penso Jul 25, 2026
b31ccfc
refactor(channels): share a neutral ack-emoji vocabulary and add befo…
penso Jul 25, 2026
1b46b5d
fix(slack): route acknowledgments per message, not per session
penso Jul 25, 2026
5d5386a
test(slack): assert jitter is two-sided; resolve acks for dropped que…
penso Jul 25, 2026
3caded1
fix(slack): let Slack callbacks reach their HMAC check, and settle st…
penso Jul 25, 2026
c5868da
fix(slack): surface final streaming delivery failures instead of swal…
penso Jul 25, 2026
8db430d
fix(chat): make abort clean up its own turn, and stop collect droppin…
penso Jul 25, 2026
f2509e2
Move ACP selection into the chat model picker (#1171)
penso Jul 28, 2026
0baf6a1
fix(scripts): target local validation tests
penso Jul 28, 2026
4180b54
fix(slack): harden callback and delivery lifecycle
penso Jul 29, 2026
e1c288a
fix(web): distinguish models from ACP picker entries
penso Jul 29, 2026
93d1b64
Merge remote-tracking branch 'origin/main' into slack-reactions-v2
penso Jul 29, 2026
cacd299
fix(channels): stabilize callback and persistence lifecycle
penso Jul 29, 2026
1c7a842
fix(scripts): parse CRLF Cargo manifests
penso Jul 29, 2026
ce0073a
refactor(slack): deduplicate callback routes and restore stripped docs
penso Jul 29, 2026
a980683
Merge remote-tracking branch 'origin/main' into slack-reactions-v2
penso Jul 29, 2026
88c4890
fix(slack): stop client-supplied ack keys, isolate callback panics
penso Jul 29, 2026
790fe33
fix(channels): reject spoofed reply targets, share the fair callback …
penso Jul 29, 2026
b65f855
fix(httpd): gate Slack callback throttle state
penso Jul 30, 2026
f177386
Merge origin/main into slack-reactions-v2
penso Jul 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ tower = "0.5"
tower-http = "0.6"
url = "2"
urlencoding = "2"
web-push = "0.11"
# Form bodies (application/x-www-form-urlencoded)
form_urlencoded = "1"
web-push = "0.11"
# Metrics
metrics = "0.24"
metrics-exporter-prometheus = "0.16"
Expand Down
1 change: 1 addition & 0 deletions crates/channels/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

Expand Down
68 changes: 68 additions & 0 deletions crates/channels/src/activity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! Channel acknowledgment-reaction signals.
//!
//! Small value types shared across the chat layer (which emits them) and the
//! gateway (which forwards them to a per-session reaction controller). Kept in
//! their own module so the plugin module stays focused.

/// Canonical acknowledgment-reaction emoji, as Unicode glyphs.
///
/// These are the platform-neutral names the reaction controller emits. Each
/// channel adapts them at its own boundary: Slack normalizes glyphs to
/// shortcodes (its Web API rejects raw glyphs), while Matrix uses the glyph
/// itself as the reaction key. Keeping the vocabulary here β€” rather than
/// hardcoding one platform's spelling in the controller β€” is what lets the
/// controller stay channel-agnostic.
pub mod ack_emoji {
/// Message received, work starting.
pub const RECEIVED: &str = "πŸ‘€";
/// Turn completed successfully.
pub const SUCCESS: &str = "βœ…";
/// Turn failed.
pub const ERROR: &str = "❌";
/// Turn is taking a while with no activity.
pub const STALL: &str = "⏳";
/// Phase: web search / fetch / browsing.
pub const WEB: &str = "🌐";
/// Phase: shell / process execution.
pub const SHELL: &str = "πŸ’»";
/// Phase: editing or writing files.
pub const EDIT: &str = "✏️";
/// Phase: deploying / releasing.
pub const DEPLOY: &str = "πŸ›«";
/// Phase: building / compiling.
pub const BUILD: &str = "πŸ—οΈ";
/// Phase: any other tool.
pub const TOOL: &str = "πŸ› οΈ";

/// Every canonical emoji, for exhaustive per-channel mapping tests.
pub const ALL: &[&str] = &[
RECEIVED, SUCCESS, ERROR, STALL, WEB, SHELL, EDIT, DEPLOY, BUILD, TOOL,
];
}

/// Terminal outcome of a channel-dispatched agent turn, used to finalize
/// acknowledgment reactions (βœ… / ❌ / none).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChannelAckOutcome {
/// The reply was delivered successfully.
Success,
/// The turn errored (timeout, provider failure, etc.).
Failure,
/// The turn was cancelled/aborted β€” leave no terminal marker.
Cancelled,
}

/// A mid-turn activity signal emitted by the agent run, used to drive channel
/// acknowledgment reactions (phase emojis) and, later, live status text.
///
/// Kept intentionally small β€” richer phases are derived from the tool name at
/// the controller.
#[derive(Debug, Clone)]
pub enum ChannelActivity {
/// The model is reasoning/planning before or between tool calls.
Thinking,
/// A tool call started; carries the tool name for phase classification.
Tool(String),
/// The turn finished with the given terminal outcome.
Finished(ChannelAckOutcome),
}
Loading
Loading