STATE-WP-0093: per-recipient broadcast receipts and standing notices (T01-T06).
Founder approved T01 on 2026-09-22 (D2, D3, D6 as recommended).
- T02: message_receipts table; kind/expires_at/supersedes_id on
agent_messages; migration d7e8f9a0b1c2 archives existing broadcasts,
leaves direct messages untouched, reversible.
- T03: reader-aware mark-read (unattributed broadcast mark-read is a
metered, deprecated no-op), delivery receipts on the scoped unread inbox,
POST /messages/{id}/ack, news/standing kinds, expiry, supersede, broadcast
archive no longer stamps read_at, reply writes the replier's receipt.
- T04 (state-hub part): Codex MCP reader param and acknowledge_notice;
hub-core part handed off (message 69fc387c).
- T05: GET /messages/notices, standing_notices in /state/summary,
dashboard standing-notices panel.
- T06: 17 new tests; full suite green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-22 00:26:33 +02:00
|
|
|
"""Agent message schemas.
|
|
|
|
|
|
|
|
|
|
The base shapes come from hub-core. STATE-WP-0093 extends them locally with
|
|
|
|
|
broadcast kinds, expiry, supersede and per-reader receipt fields; direct
|
|
|
|
|
messages keep the hub-core semantics (the new fields stay at their defaults).
|
|
|
|
|
"""
|
|
|
|
|
import uuid
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
from hub_core.schemas.agent_message import MessageCreate as _HubMessageCreate
|
|
|
|
|
from hub_core.schemas.agent_message import MessageRead as _HubMessageRead
|
|
|
|
|
from hub_core.schemas.agent_message import MessageReply
|
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MessageCreate(_HubMessageCreate):
|
|
|
|
|
# Only meaningful for broadcasts: news | standing. A broadcast without a
|
|
|
|
|
# kind defaults to ``news``; direct messages must leave it unset or
|
|
|
|
|
# ``message``.
|
|
|
|
|
kind: str | None = None
|
|
|
|
|
expires_at: datetime | None = None
|
|
|
|
|
supersedes_id: uuid.UUID | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MessageRead(_HubMessageRead):
|
|
|
|
|
kind: str = "message"
|
|
|
|
|
expires_at: datetime | None = None
|
|
|
|
|
supersedes_id: uuid.UUID | None = None
|
|
|
|
|
# Per-reader receipt state; populated for broadcasts when the request is
|
|
|
|
|
# scoped to a reader (``to_agent`` on list, ``reader`` on mark-read/ack).
|
|
|
|
|
# For such responses ``read_at`` is the reader's own read time.
|
|
|
|
|
reader: str | None = None
|
|
|
|
|
delivered_at: datetime | None = None
|
|
|
|
|
acknowledged_at: datetime | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MessageMarkRead(BaseModel):
|
|
|
|
|
reader: str | None = None
|
|
|
|
|
ack: bool = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MessageAck(BaseModel):
|
|
|
|
|
agent: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NoticeStatus(BaseModel):
|
|
|
|
|
id: uuid.UUID
|
|
|
|
|
from_agent: str
|
|
|
|
|
subject: str
|
|
|
|
|
body: str
|
|
|
|
|
created_at: datetime
|
|
|
|
|
expires_at: datetime | None = None
|
|
|
|
|
supersedes_id: uuid.UUID | None = None
|
|
|
|
|
acknowledged: list[str] = []
|
|
|
|
|
delivered_only: list[str] = []
|
|
|
|
|
unreached: list[str] = []
|
|
|
|
|
acked_count: int = 0
|
|
|
|
|
delivered_only_count: int = 0
|
|
|
|
|
unreached_count: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StandingNoticeDigest(BaseModel):
|
|
|
|
|
id: uuid.UUID
|
|
|
|
|
subject: str
|
|
|
|
|
expires_at: datetime | None = None
|
|
|
|
|
acked: int = 0
|
|
|
|
|
pending: int = 0
|
|
|
|
|
|
feat(CUST-WP-0015): implement agent inbox for inter-agent coordination
Adds a message-passing layer to state-hub so Claude instances can
coordinate across sessions without polling shared progress events.
- Migration f3a4b5c6d7e8: agent_messages table with thread support
- FastAPI router: POST/GET /messages/, thread view, mark-read, archive, reply
- 4 MCP tools: send_message, get_messages, mark_message_read, reply_to_message
- Observable dashboard: /inbox page with unread/read/archived sections + KPI
- CLAUDE.md updates: global, custodian, marki-docx, activity-core, template
- TOOLS.md: Agent Inbox tools section documented
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 02:55:45 +01:00
|
|
|
|
2026-06-07 01:20:57 +02:00
|
|
|
__all__ = [
|
STATE-WP-0093: per-recipient broadcast receipts and standing notices (T01-T06).
Founder approved T01 on 2026-09-22 (D2, D3, D6 as recommended).
- T02: message_receipts table; kind/expires_at/supersedes_id on
agent_messages; migration d7e8f9a0b1c2 archives existing broadcasts,
leaves direct messages untouched, reversible.
- T03: reader-aware mark-read (unattributed broadcast mark-read is a
metered, deprecated no-op), delivery receipts on the scoped unread inbox,
POST /messages/{id}/ack, news/standing kinds, expiry, supersede, broadcast
archive no longer stamps read_at, reply writes the replier's receipt.
- T04 (state-hub part): Codex MCP reader param and acknowledge_notice;
hub-core part handed off (message 69fc387c).
- T05: GET /messages/notices, standing_notices in /state/summary,
dashboard standing-notices panel.
- T06: 17 new tests; full suite green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-22 00:26:33 +02:00
|
|
|
"MessageAck",
|
2026-06-07 01:20:57 +02:00
|
|
|
"MessageCreate",
|
STATE-WP-0093: per-recipient broadcast receipts and standing notices (T01-T06).
Founder approved T01 on 2026-09-22 (D2, D3, D6 as recommended).
- T02: message_receipts table; kind/expires_at/supersedes_id on
agent_messages; migration d7e8f9a0b1c2 archives existing broadcasts,
leaves direct messages untouched, reversible.
- T03: reader-aware mark-read (unattributed broadcast mark-read is a
metered, deprecated no-op), delivery receipts on the scoped unread inbox,
POST /messages/{id}/ack, news/standing kinds, expiry, supersede, broadcast
archive no longer stamps read_at, reply writes the replier's receipt.
- T04 (state-hub part): Codex MCP reader param and acknowledge_notice;
hub-core part handed off (message 69fc387c).
- T05: GET /messages/notices, standing_notices in /state/summary,
dashboard standing-notices panel.
- T06: 17 new tests; full suite green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-22 00:26:33 +02:00
|
|
|
"MessageMarkRead",
|
2026-06-07 01:20:57 +02:00
|
|
|
"MessageRead",
|
|
|
|
|
"MessageReply",
|
STATE-WP-0093: per-recipient broadcast receipts and standing notices (T01-T06).
Founder approved T01 on 2026-09-22 (D2, D3, D6 as recommended).
- T02: message_receipts table; kind/expires_at/supersedes_id on
agent_messages; migration d7e8f9a0b1c2 archives existing broadcasts,
leaves direct messages untouched, reversible.
- T03: reader-aware mark-read (unattributed broadcast mark-read is a
metered, deprecated no-op), delivery receipts on the scoped unread inbox,
POST /messages/{id}/ack, news/standing kinds, expiry, supersede, broadcast
archive no longer stamps read_at, reply writes the replier's receipt.
- T04 (state-hub part): Codex MCP reader param and acknowledge_notice;
hub-core part handed off (message 69fc387c).
- T05: GET /messages/notices, standing_notices in /state/summary,
dashboard standing-notices panel.
- T06: 17 new tests; full suite green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-22 00:26:33 +02:00
|
|
|
"NoticeStatus",
|
|
|
|
|
"StandingNoticeDigest",
|
2026-06-07 01:20:57 +02:00
|
|
|
]
|