feat: add message reactions and priority messages#29
Merged
Killea merged 1 commit intoKillea:mainfrom Mar 2, 2026
Merged
Conversation
- New `reactions` table with UNIQUE constraint on (message_id, agent_id, reaction)
- CRUD: `msg_react` (idempotent INSERT OR IGNORE), `msg_unreact`, `msg_reactions`, `msg_reactions_bulk`
- REST: `POST /api/messages/{id}/reactions` (201), `DELETE /api/messages/{id}/reactions/{reaction}` (200), `GET /api/messages/{id}/reactions`
- MCP tools: `msg_react`, `msg_unreact`
- SSE events: `msg.react` (on actual insert), `msg.unreact` (on actual delete)
- Reactions embedded in `GET /api/threads/{id}/messages` response (batch-fetched, no N+1)
- Web UI: reaction pills grouped by label with count
- New `messages.priority` column: `TEXT NOT NULL DEFAULT 'normal'`
- Valid values: `normal`, `urgent`, `system` — validated server-side (ValueError on invalid)
- Safe migration via `_add_column_if_missing()` — backward-compatible
- CRUD: `msg_post(priority=)`, `msg_list(priority=)` filter, `_row_to_message` with fallback
- REST: `MessageCreate.priority` field, filter via `?priority=` query param
- MCP: `priority` in `msg_post` and `msg_list` schemas
- Web UI: priority badges (`URGENT` in red, `SYSTEM` in blue)
- 29 tests (19 unit in-memory, 10 integration via HTTP)
- Full regression suite: 210 passed
bb6ff0a to
9e21365
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds two new first-class messaging capabilities to AgentChatBus:
agree,disagree,important). Reactions are idempotent, multi-agent, and emitted as SSE events for real-time UI updates.normal(default),urgent, orsystem. Priority is a dedicated column (not metadata) to allow efficient SQL filtering and a fixed default for backward compatibility.Both features are additive and backward-compatible: existing
msg_postcalls withoutprioritydefault to"normal", and reactions appear as a new empty[]field inmsg_listresponses.Changes
Database
reactionstable with UNIQUE constraint on(message_id, agent_id, reaction)and index onmessage_idmessages.priority TEXT NOT NULL DEFAULT 'normal'via the existing_add_column_if_missing()helperCRUD (
src/db/crud.py)msg_post: newpriorityparam with validation (normal | urgent | system)msg_list: new optionalpriorityfilter param_row_to_message: readsprioritywith safe fallback for legacy rowsmsg_react,msg_unreact,msg_reactions,msg_reactions_bulkmsg.react(only on actual insert) andmsg.unreact(only on actual delete) — no spurious events for idempotent no-opsREST API (
src/main.py)POST /api/threads/{id}/messages: acceptspriorityfield, returns it in responseGET /api/threads/{id}/messages: accepts optional?priority=filter, returnspriorityandreactionsper message (batch-fetched)POST /api/messages/{id}/reactions→ 201DELETE /api/messages/{id}/reactions/{reaction}?agent_id=→ 200GET /api/messages/{id}/reactions→ 200MCP Tools (
src/mcp_server.py,src/tools/dispatch.py)msg_post: newpriorityproperty in schemamsg_list: new optionalpriorityfilter property; responses includepriorityandreactionsmsg_react,msg_unreactWeb UI (
src/static/index.html,src/static/css/main.css)URGENT(red) andSYSTEM(blue) next to message timestampagree ×3)Tests (
tests/test_reactions_priority.py)Backward Compatibility
prioritydefaults to"normal"— existing callers unaffectedreactionsis a new additive field ([]when empty) — existing consumers can ignore it