Files
codex/codex-rs/thread-store/src/thread_attachments.rs
joeytrasatti-openai 2df0b747ba Add thread attachment operations with coordinated deletion (#44350)
## Why

Attachment mutations must coordinate with thread deletion so queued requests cannot use metadata belonging to a deleted thread.

## What changed

- Add typed `ThreadStore` operations for idempotent attachment creation, paginated listing, and removal, with capability detection and unsupported defaults.
- Implement attachment operations for SQLite-backed `LocalThreadStore`, including unloaded threads, and preserve invalid-request and missing-thread errors.
- Coordinate attachment mutations with lifecycle locks and move SQLite cleanup into thread-store deletion. Remove state rows only after rollout deletion, preserving retries after cleanup failures.
- Give the in-memory store ownership of its associated SQLite cleanup and remove duplicate cleanup from the app-server.

## Testing

Add coverage for attachment pagination and idempotency, unsupported stores, error categories, lifecycle exclusion, mutations queued behind single and batch deletion, cleanup failure retries, and in-memory state cleanup. Extend the app-server descendant deletion test to verify SQLite rows are removed.

GitOrigin-RevId: f0157538c7c5c2ee1362ce40eac157101c5d4505
2026-09-10 00:30:27 +00:00

40 lines
1.3 KiB
Rust

//! Typed parameters for attachment operations on stored threads.
use codex_protocol::ThreadId;
use serde_json::Value;
/// Parameters for attaching a thread-owned attachment.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AddThreadAttachmentParams {
/// Thread that owns the attachment.
pub thread_id: ThreadId,
/// Client-defined attachment type.
pub attachment_type: String,
/// Stable attachment identity within its thread and type.
pub identity_key: String,
/// Bounded, client-defined attachment metadata.
pub payload: Value,
}
/// Parameters for listing attachments owned by one thread.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ListThreadAttachmentsParams {
/// Thread whose attachments should be returned.
pub thread_id: ThreadId,
/// Opaque cursor returned by a previous attachment listing.
pub cursor: Option<String>,
/// Maximum number of attachments to return.
pub limit: usize,
}
/// Parameters for removing a thread-owned attachment.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RemoveThreadAttachmentParams {
/// Thread that owns the attachment.
pub thread_id: ThreadId,
/// Client-defined attachment type.
pub attachment_type: String,
/// Stable attachment identity within its thread and type.
pub identity_key: String,
}