Commit Graph
18 Commits
Author SHA1 Message Date
jif d3e5840932 Subscribe authors to message-board channels created by posting (#47259)
## Why

Posting to a new channel subscribed its author to replies on that post, but not to new discussion roots in the channel. The creator could therefore miss notifications for subsequent discussions.

## What changed

Subscribe the author to the channel in the same transaction that creates the channel and its first post. Document this behavior in the API and the `new_channel_name` tool parameter.

## Testing

Update coverage to verify that channel creators receive notifications without explicit targeting and that posting to an existing channel preserves an explicit unsubscribe. Adjust thread-deletion test expectations for the additional persisted subscription.

GitOrigin-RevId: 5553ebc9f9b51456ab48886e9871733e93370a2b
2026-09-22 11:10:53 +00:00
jif 0160eb3497 Preserve explicit message-board unsubscribes when posting (#47257)
## Why

Posting to a discussion automatically subscribed its author, undoing an explicit unsubscribe and restoring unwanted reply notifications.

## What changed

Persist explicit opt-outs so posting follows a discussion by default but leaves unsubscribed agents opted out until explicitly subscribed again. Keep active subscriptions in the existing table for compatibility with older readers, and remove opt-outs when deleting a board. Update the API and tool descriptions to explain the behavior.

## Testing

Extend the local board test to cover reopening an older database, preserving opt-outs across reopen and subsequent posts, legacy subscription queries, explicit notifications without resubscribing, explicit resubscription, and board cleanup.

GitOrigin-RevId: 8b8f7f50cea5041541b8d93067c52db18cdde85c
2026-09-22 11:07:21 +00:00
jif b58b05e062 Suppress agent message board notifications to the post author (#47236)
## Why

Channel and thread subscriptions, or explicit `agents_to_notify`, could cause agents to receive notifications for their own posts.

## What changed

Exclude the author from notification recipients, even when explicitly targeted. Preserve the author's subscriptions so replies from other agents still reach them, and document this requirement in the board API.

## Testing

Update board tests to cover explicit self-targeting, subscribed authors, and delivery of other agents' replies. Update the model-context scenario and snapshot to verify posts remain searchable without a `CHANNEL_POST` self-notification.

GitOrigin-RevId: 0b2558e7df79122a6da06ad592f9735ba260cce1
2026-09-22 09:39:49 +00:00
jif e51aacad60 Include attributed previews in agent message board notifications (#47075)
## Why

Message board notifications exposed only post and thread IDs, requiring a read to see any post content.

## What changed

Deliver notifications as `agent_message` items with author and recipient attribution. Include a `CHANNEL_POST` payload with the sender, channel, message and thread IDs, and up to 150 characters of post text. Direct agents to `read_post` when the preview is truncated, and retain recognition of legacy user-role notices.

## Testing

Update the model-context scenario to assert the notification's author, recipient, and preview payload, and update the idle-agent scenario to check for the new notification format.

GitOrigin-RevId: e0e2794be82e38bba47f41fb4fc8128eb5e47619
2026-09-21 17:29:13 +00:00
jif 51d221a9b7 Stop redundant message-board reads when limits reach one (#47064)
## Why

When result metadata exceeds the output budget, message-board tools keep retrying identical reads after all limits reach one.

## What changed

Stop shrinking reads once every page and character limit reaches one, returning the existing metadata-budget error if the result still does not fit. Use the largest effective limit to keep retrying while either the page size or preview length can still shrink.

## Testing

Add regression assertions for all five read tools with an impossible output budget, checking the error and exact read counts. Cover unequal page and preview limits and limits that are not powers of two.

GitOrigin-RevId: f00ddbcf0372c8f9318fa178259868caae55e68b
2026-09-21 16:17:31 +00:00
jif fe6455a438 Add a partial index for agent message board root posts (#47063)
Create `posts_roots_created` on `(board, channel, timestamp, seq)` for
posts where `id = root` in the local SQLite schema.

GitOrigin-RevId: 4c40e0d853deaa3ab6b6303525870e3b7bfc3b14
2026-09-21 16:16:40 +00:00
jif d583e73c4d Fetch local message board thread summaries in one query (#47055)
## Why

Listing threads issued two additional SQL queries per root to fetch its reply count and latest reply.

## What changed

Fetch roots, reply counts, and latest replies in a single query. Materialize the selected page before looking up reply summaries, preserving creation and activity ordering, pagination, and preview limits.

## Testing

Strengthen pagination assertions to check complete thread summaries for threads without replies, including Unicode preview truncation, reply counts, and last activity timestamps.

GitOrigin-RevId: cbbed36418a349a18daf0771f4ed27aa47de0bc1
2026-09-21 15:47:52 +00:00
jif 0e69d3bd9b Batch message-board subscriber reads into one SQLite result (#47050)
## Why

Posting to the local agent message board fetched each subscriber row across SQLite's worker thread while holding a write transaction.

## What changed

Use `json_group_array(agent)` to fetch subscribers as a single JSON array, then deserialize it before collecting notification recipients.

## Testing

Extend the local board test to verify that posting to a channel with no subscribers succeeds without sending notifications.

GitOrigin-RevId: ad294e19c78ee501f1de2084f7c02fa96f53418d
2026-09-21 15:27:08 +00:00
jif f484f7228d Share SQLite pools across local agent message-board handles (#47049)
## Why

Opening each local message-board handle created a separate SQLite pool for the same database.

## What changed

- Cache one shared pool per canonical database path within the process, using weak references so the last handle can release it.
- Serialize pool initialization with deletion and corruption recovery. Close and evict the cached pool before replacing a corrupt database, and block new handles until deletion tombstones are saved.

## Testing

Enable library unit tests and add coverage for concurrent handles sharing a pool, releasing it after the last handle drops, and creating a new pool on reopen.

GitOrigin-RevId: 4d4a5c9ea9f063733df85a2ac120d51099736520
2026-09-21 15:25:58 +00:00
jif 40eeb6e8a8 Recover corrupt message-board storage during thread deletion (#47042)
## Why

A corrupt agent message-board database can block thread deletion even when the feature is disabled.

## What changed

When corruption prevents opening the database for board deletion, back it up and recreate it before recording deletion tombstones. Recovery resets all boards, retaining their previous storage in the backup. Other database open failures continue to return an error without deleting the thread or replacing storage.

## Testing

Add an app-server regression test with the feature disabled that verifies ordinary open failures preserve storage and the thread, while corruption recovery preserves the backup, deletes the requested thread, retains another thread, and records the board tombstone in the recreated database.

GitOrigin-RevId: 85f7d6303ae5c359782018cad4a78461d86c43db
2026-09-21 14:31:50 +00:00
jif 73129716c2 Delete persisted message boards with their root threads (#47029)
## Why

Permanent thread deletion needs to remove persisted agent message board data even when the message board feature has been disabled.

## What changed

- Add a cleanup hook for single and batch thread deletion, invoked after reference and writer checks but before rollout removal so cleanup failures remain retryable.
- Remove the deleted roots' channels, posts, and subscriptions regardless of the current feature setting.
- Record board tombstones and check them within write transactions to prevent delayed writes from recreating deleted data.

## Testing

Add an app-server regression test that creates a board, archives its root thread, restarts with the feature disabled, and verifies that permanent deletion removes the persisted channels, posts, and subscriptions.

GitOrigin-RevId: 4ea71559a8df0814dffda23a056a9bbaf6e0a0cb
2026-09-21 13:28:02 +00:00
jif 8a62cc4dc1 Align message-board tools with the multi-agent namespace (#47028)
## Why

Message-board tools hardcoded the `collaboration` namespace and used a different namespace description from the multi-agent tools. This ignored custom namespace configuration and caused conflicts under strict tool collision checking.

## What changed

- Use `multi_agent_v2.tool_namespace` and the shared multi-agent namespace description for message-board tools, resolving the namespace at runtime startup.
- Support unnamespaced tool specifications when no namespace is supplied.
- Remove hardcoded `collaboration` prefixes from message-board notifications.

## Testing

Add app-server integration coverage for the default `collaboration` namespace and a configured `agents` namespace with strict collision checking enabled. Verify that both tool families are advertised together and that `get_channels` executes through the installed extension.

GitOrigin-RevId: fef7be51ea2a84bbdb6d3491606db442ed4e6ea3
2026-09-21 13:27:39 +00:00
jif 6149914a0e Wire agent message boards into persistent multi-agent runtimes (#47017)
## What changed

- Register the existing message-board tools with the app server through a lifecycle extension, gated on `agent_message_board`, multi-agent v2, and non-ephemeral sessions. The new feature flag is disabled by default.
- Bind tools to each agent's identity and share the SQLite-backed board across the agent tree and runtime resumes.
- Use the runtime clock for posts and deliver ID-only notifications to running agents, with tools to retrieve post contents. Skip inactive recipients without starting them or queuing notices.
- Emit a warning and leave board tools unavailable if initialization fails.

## Testing

Add runtime scenarios and a context snapshot covering feature gating without creating storage, posting and searching, active-only notifications, sharing with child agents, persistence across resume, and clock failure without channel creation.

GitOrigin-RevId: a81bd85cd372b0d122ba375ed1a1bfd3ba3a3b7c
2026-09-21 12:35:36 +00:00
jif 695ab0a0b4 Add collaboration tools for the agent message board (#46985)
## What changed

Expose `message_board_tools` to create nine tools for channel creation and discovery, thread listing, post search and reading, subscriptions, and posting. Bind tools to the host-supplied caller identity and resolve agent references relative to the caller. The factory does not register or enable the extension.

Keep responses valid JSON within an 8,000-byte cap and the call's output budget. Reduce read limits and previews as needed while preserving backend pagination, and reject mutations when the budget is too small to acknowledge them. Derive post request IDs from turn and invocation metadata for direct and Code Mode calls.

## Testing

Add integration coverage for invalid arguments, mutation rejection without writes under insufficient budgets, duplicate post calls, distinct Code Mode invocations, relative notification recipients, author filtering, and bounded Unicode reads with continuation offsets.

GitOrigin-RevId: 2fbc58a4c7eb861055847c363061d73749bf573c
2026-09-21 09:28:24 +00:00
jif 4d160ea71d Index channel posts by timestamp for latest-message lookups (#46979)
Add an index on `posts(board,channel,timestamp,seq)` to support the channel summary query that selects the latest message by `timestamp` and `seq`.

GitOrigin-RevId: 862b318fd70a039aa749240c389865f1c84f552c
2026-09-21 09:07:24 +00:00
jif 8f2c15c398 Implement paginated queries for the local agent message board (#46978)
## What changed

Implement `AgentMessageBoard` for `LocalAgentMessageBoard`, adding SQLite queries to list channels and threads, search posts, and read thread replies.

- Support Unicode case-insensitive substring search and post filters for channel, author, and `after_message_id`.
- Sort threads by creation time or latest activity, with reply counts and previews of the root post and latest reply.
- Bound pages to 50 results and post previews to a shared 20,000-character response budget. Use offset cursors for pagination; concurrent posts may shift results between pages.
- Add indexes for board and thread timestamp queries.

## Testing

Add integration tests covering pagination, page and preview caps, Unicode search and truncation, thread activity ordering, filtered search, and rejection of non-root thread IDs and unknown callers.

GitOrigin-RevId: c9c673768596efb6d33160e2db8dff62ee9b9cdb
2026-09-21 09:00:44 +00:00
jif 293de27177 Add SQLite storage for local agent message boards (#46966)
## What changed

Add `LocalAgentMessageBoard` with persistent channels, posts, and subscriptions scoped by `SessionId`. Support channel creation, posting and replies, subscription changes, and bounded reads using Unicode character offsets.

Serialize mutations across independent handles with immediate transactions. Deduplicate retries by caller and request ID, reject changed requests that reuse an ID, and return existing post metadata without repeating notifications. Deliver deduplicated notifications after commit; notification failures leave committed posts successful and readable.

## Testing

Add integration tests covering concurrent retries across independent handles, reopening persisted boards, subscription routing, board isolation, Unicode reads, invalid recipients, inactive recipients, and notification failures.

GitOrigin-RevId: 0cdf621d19517bf57d527fd729290e08ac99f165
2026-09-21 08:23:58 +00:00
jif abbdde95b5 Add shared agent message-board extension interfaces (#46959)
## What changed

Add `codex-agent-message-board-extension` to the Cargo workspace with a Bazel target. Define backend-independent contracts for discussions within a persistent agent tree:

- `AgentMessageBoard` covers channel creation, posting, thread listing, post search, bounded reads, and subscriptions, with documented membership and retry semantics.
- `MessageBoardHost` provides agent resolution, the caller's configured clock, and metadata notifications restricted to active turns.
- Shared request and response types represent channels, posts, threads, subscriptions, and cursor pagination, including derived page counts and continuation indicators.

The crate defines interfaces and records for local or remote backends; storage, tool adapters, and feature registration remain separate.

GitOrigin-RevId: d8734f0226bc0c0d521929e7dd30b414136dcb95
2026-09-21 07:52:40 +00:00