Configure ACP session scope per agent (#7578)

## Summary

PR #6732 taught the ACP harness to honor `BUZZ_ACP_SESSION_POLICY`, but
the desktop exposed that policy as one global experiment. Turning it on
changed every managed agent at once, even though conversation scope is
part of how an individual agent should behave. Some agents need
continuity across a channel, while agents such as validators may need
clean context for each thread.

This moves the choice onto the agent definition under Advanced as
**Conversation context**, with **Entire channel** and **Each thread**
options. **Entire channel** remains the default, so existing definitions
keep their current behavior.

The policy now travels through create and update IPC, returned agent
summaries, persona events, snapshots, teams, and community catalog
copies. Launches pass the effective definition value to the harness.
Editing a running agent uses the same lifecycle as a model edit: it
shows the restart-required state, leaves the deployed process untouched,
and applies the new policy on restart.

The global Thread Scoped ACP Sessions experiment and its desktop
command/state have been removed because the setting no longer has a
useful global meaning. There is intentionally no migration for the old
preview override. Users who enabled it can choose **Each thread** for
the agents that need it.

Unknown or null policy values degrade to **Entire channel** across
stored agents, persona events, and catalog projections. This keeps
forward-version data from dropping complete agent records.

### Related issue

No matching issue found. Builds on #6732.

### Testing

- Focused Playwright create flow selected **Each thread** and verified
`create_persona` received `sessionPolicy: "thread"`.
- Focused Playwright catalog flow added a thread-scoped agent and
verified the local copy stored `session_policy: "thread"`.

Generated with Codex

---------

Signed-off-by: Salman Mohammed <smohammed@squareup.com>
This commit is contained in:
Salman Mohammed
2026-09-11 16:38:41 -04:00
committed by GitHub
parent e17cdd9d5c
commit 78618804ec
95 changed files with 622 additions and 297 deletions

View File

@@ -70,7 +70,8 @@ The `content` field is a **plaintext** (unencrypted) JSON object:
"name_pool": ["<string>", ...],
"respond_to": "<string | null>",
"respond_to_allowlist": ["<64-hex pubkey>", ...],
"parallelism": "<integer | null>"
"parallelism": "<integer | null>",
"session_policy": "<channel | thread>"
}
```
@@ -93,20 +94,13 @@ The `content` field is a **plaintext** (unencrypted) JSON object:
| `respond_to` | string \| null | `null` | **Reserved.** Default respond-to policy for instances spawned from this definition: `"anyone"`, `"owner-only"`, or `"allowlist"`. `null` defers to the client default. |
| `respond_to_allowlist` | string[] | `[]` | **Reserved.** Allowlisted author pubkeys (64-char lowercase hex) when `respond_to` is `"allowlist"`. Ignored otherwise. |
| `parallelism` | integer \| null | `null` | **Reserved.** Default max concurrent turns for spawned instances. `null` defers to the client default. |
| `session_policy` | string | `"channel"` | ACP conversation boundary for instances launched from this definition. `"channel"` shares context across a channel; `"thread"` isolates context per channel thread. Direct messages remain conversation-scoped. |
The behavioral fields (`respond_to`, `respond_to_allowlist`,
`parallelism`) are definition-level *defaults*: a spawned instance copies them
at creation and may be reconfigured independently afterwards. They were
previously carried only on the kind:30177 projection (see
"Slimming: kind:30177" below).
**Status: reserved.** In the current implementation these behavioral fields are
*parsed but not yet applied*: readers tolerate and preserve them at the wire
layer, but the local definition store does not yet carry them and writers do
not emit them. The instance-copy-at-creation behavior activates in a
subsequent release (the create-path unification). Until then a definition
carrying these fields round-trips through the wire type but the values do not
survive a local edit-and-republish cycle.
The behavioral fields are definition-level defaults. `respond_to`, its
allowlist, and `parallelism` are copied when an instance is created.
`session_policy` remains definition-authoritative: changing it marks running
linked instances for restart, and the next restart launches with the current
definition value without rewriting an already-deployed instance in place.
Unknown fields MUST be ignored by readers (forward compatibility).