Skip to content

feat: add message reactions and priority messages#29

Merged
Killea merged 1 commit intoKillea:mainfrom
bertheto:feat/reactions-priority
Mar 2, 2026
Merged

feat: add message reactions and priority messages#29
Killea merged 1 commit intoKillea:mainfrom
bertheto:feat/reactions-priority

Conversation

@bertheto
Copy link
Contributor

@bertheto bertheto commented Mar 2, 2026

Summary

This PR adds two new first-class messaging capabilities to AgentChatBus:

  1. Message Reactions (annotations) — any agent can react to a message with a short label (e.g. agree, disagree, important). Reactions are idempotent, multi-agent, and emitted as SSE events for real-time UI updates.
  2. Priority Messages — messages can be classified as normal (default), urgent, or system. 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_post calls without priority default to "normal", and reactions appear as a new empty [] field in msg_list responses.

Changes

Database

  • New reactions table with UNIQUE constraint on (message_id, agent_id, reaction) and index on message_id
  • Safe migration for messages.priority TEXT NOT NULL DEFAULT 'normal' via the existing _add_column_if_missing() helper

CRUD (src/db/crud.py)

  • msg_post: new priority param with validation (normal | urgent | system)
  • msg_list: new optional priority filter param
  • _row_to_message: reads priority with safe fallback for legacy rows
  • New functions: msg_react, msg_unreact, msg_reactions, msg_reactions_bulk
  • SSE events: msg.react (only on actual insert) and msg.unreact (only on actual delete) — no spurious events for idempotent no-ops

REST API (src/main.py)

  • POST /api/threads/{id}/messages: accepts priority field, returns it in response
  • GET /api/threads/{id}/messages: accepts optional ?priority= filter, returns priority and reactions per message (batch-fetched)
  • POST /api/messages/{id}/reactions → 201
  • DELETE /api/messages/{id}/reactions/{reaction}?agent_id= → 200
  • GET /api/messages/{id}/reactions → 200

MCP Tools (src/mcp_server.py, src/tools/dispatch.py)

  • msg_post: new priority property in schema
  • msg_list: new optional priority filter property; responses include priority and reactions
  • New tools: msg_react, msg_unreact

Web UI (src/static/index.html, src/static/css/main.css)

  • Priority badges: URGENT (red) and SYSTEM (blue) next to message timestamp
  • Reaction pills: grouped by label with count (e.g. agree ×3)

Tests (tests/test_reactions_priority.py)

  • 19 unit tests (in-memory DB, no server required)
  • 10 integration tests (HTTP via test server)
  • Full regression suite: all existing tests still pass

Backward Compatibility

  • priority defaults to "normal" — existing callers unaffected
  • reactions is a new additive field ([] when empty) — existing consumers can ignore it
  • Schema migration is safe for existing databases

- 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
@bertheto bertheto force-pushed the feat/reactions-priority branch from bb6ff0a to 9e21365 Compare March 2, 2026 13:09
@Killea Killea merged commit 8ebc8ba into Killea:main Mar 2, 2026
1 check passed
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.

2 participants