Add thread section management APIs (#36380)

## What changed

- Add `threadSection/create`, `threadSection/update`, and `threadSection/delete` app-server methods, with generated protocol schemas and TypeScript bindings.
- Persist custom sections in SQLite with stable UUIDv7 identities, trim and validate display names, and prevent renaming or deleting the built-in pinned section.
- Delete sections transactionally and return their active and archived threads to the unsectioned list.
- Serialize section mutations with section listing so concurrent requests observe ordered updates.

## Testing

- Cover section persistence across restarts, ordered renames, member cleanup on deletion, invalid requests, unsupported stores, and thread-store/state-runtime behavior.

GitOrigin-RevId: dc9a4be283c21dbc93ab1829eafc4825d8df6575
This commit is contained in:
joeytrasatti-openai
2026-07-31 19:08:45 +00:00
committed by copyberry
parent d62353a312
commit c42ea41ee0
38 changed files with 1862 additions and 62 deletions
@@ -633,9 +633,24 @@ client_request_definitions! {
},
ThreadSectionList => "threadSection/list" {
params: v2::ThreadSectionListParams,
serialization: None,
serialization: global_shared_read("thread-sections"),
response: v2::ThreadSectionListResponse,
},
ThreadSectionCreate => "threadSection/create" {
params: v2::ThreadSectionCreateParams,
serialization: global("thread-sections"),
response: v2::ThreadSectionCreateResponse,
},
ThreadSectionUpdate => "threadSection/update" {
params: v2::ThreadSectionUpdateParams,
serialization: global("thread-sections"),
response: v2::ThreadSectionUpdateResponse,
},
ThreadSectionDelete => "threadSection/delete" {
params: v2::ThreadSectionDeleteParams,
serialization: global("thread-sections"),
response: v2::ThreadSectionDeleteResponse,
},
#[experimental("thread/search")]
ThreadSearch => "thread/search" {
params: v2::ThreadSearchParams,
@@ -1139,6 +1139,57 @@ pub struct ThreadSectionListResponse {
pub next_cursor: Option<String>,
}
/// Parameters for creating an independently persisted thread section.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadSectionCreateParams {
/// The user-visible name of the section.
pub name: String,
}
/// The independently persisted section created by the server.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadSectionCreateResponse {
pub section: ThreadSection,
}
/// Parameters for updating an independently persisted thread section.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadSectionUpdateParams {
/// The stable, server-generated identity of the section to update.
pub section_id: String,
/// The updated user-visible name of the section.
pub name: String,
}
/// The independently persisted section after its name is updated.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadSectionUpdateResponse {
pub section: ThreadSection,
}
/// Parameters for deleting an independently persisted thread section.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadSectionDeleteParams {
/// The stable, server-generated identity of the section to delete.
pub section_id: String,
}
/// Successful deletion does not return additional section data.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadSectionDeleteResponse {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS, ExperimentalApi)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]