## Why
Image files can become unavailable between turns. Model requests should reflect their current availability while preserving the original references in saved history.
## What changed
- Add opt-in availability checks through `AttachmentStore::is_resolvable`, retaining references by default and on backend or access errors.
- Check distinct file IDs concurrently for each prepared request and replace confirmed-missing images with `[image unavailable]` in messages and tool outputs.
- Apply the same handling to compaction requests, with background image checks running outside the session lock without delaying foreground turn completion.
## Testing
Add unit tests and multi-turn scenarios covering placeholders, preserved history and annotations, concurrent deduplicated checks, backend errors, and nonblocking background compaction.
GitOrigin-RevId: ec98c7014c6e6b5063d87b943d2cd66a9ce7c1e3
## What changed
- Upload generated images to the attachment store and expose `fileId` in image-generation items when available, with inline `result` fallback on upload or decoding failure.
- Preserve file references through legacy events, persisted rollouts, thread history, and task output summaries. Keep model-facing image preparation separate.
- Add attachment request tags and mark generated-image uploads with `usage=image_gen`, preserving the thread's ephemeral setting.
- Update public schemas and SDK types to accept either image representation, retain the Python `ImageGenerationThreadItem` alias, and prefer `fileId` when reading records containing both fields.
## Testing
Add coverage for file-backed generation and rollout persistence, legacy history replay, inline and transitional serialization, task output visibility, and Python SDK alias compatibility.
GitOrigin-RevId: f7a2bb5707e2f277348a547a988bc33c8e96d891
## Why
Attachment stores need to distinguish uploads from ephemeral threads, which intentionally skip durable persistence.
## What changed
Add `ephemeral` to `UploadRequest` and propagate the turn configuration through image preparation for messages, tool outputs, and history replay. Include the flag in debug output while keeping attachment bytes redacted.
## Testing
Extend the Guardian context-budget test to assert that a persistent Guardian uploads exactly one image with `ephemeral: false`. Update the attachment debug-output assertion to include the new field.
GitOrigin-RevId: 42814c514a571ed6798e4dcf79a22028ee4efc28
## Why
Attachment stores need the receiving thread ID to support thread-based placement.
## What changed
Add `thread_id` to `UploadRequest` and pass the session's thread ID through image preparation for messages and tool outputs. Include the ID in debug output while continuing to redact attachment bytes.
## Testing
Extend the image rollout test to assert that a new image uploaded after resume carries the resumed session's thread ID. Update the debug-output test for the new field.
GitOrigin-RevId: f81e3bd761dca704064287177b8ecd7175662f07
## What changed
Upload prepared images from messages and tool outputs through the session's `AttachmentStore` before recording history. Use the returned inline bytes or file reference, and fall back to the prepared inline image if upload fails.
Keep history replay on `InlineAttachmentStore` so it does not upload recorded images, and preserve existing file references. Reuse image resizing directly for guardian review comparisons without uploading.
## Testing
Add coverage for upload failure preserving resized inline images. Extend rollout coverage to verify that only new images are uploaded, uploaded bytes have the expected dimensions, and file references and resize notices survive replay.
GitOrigin-RevId: e9966297c3579ef1e52376f0235fe3a7e3ec7ecc
## What changed
Replace `AttachmentStore::persist` with `upload` and `resolve`. Uploads return inline bytes or a file ID; resolution returns optional file metadata and a download URL only when a minimum URL lifetime is requested. Add image dimensions, digest, size, MIME type, and categorized errors to the API.
Make `InlineAttachmentStore` return the original bytes and report `NotFound` when resolving file IDs. Redact attachment bytes and file URLs in debug output.
Pass the configured image store from the thread manager into sessions and inherit it in delegated sessions. Allow `TestCodexBuilder` to accept a custom image store.
## Testing
Update unit coverage for preserving PNG and JPEG bytes, redacting bytes and URLs in debug output, and rejecting file resolution in the inline store.
GitOrigin-RevId: f313e0048925998d84394c7e5a278e0d39d86a45
## What changed
- Add the `codex-attachment-store` crate with storage-neutral attachment metadata, references, errors, and an asynchronous persistence interface.
- Provide an inline implementation that preserves attachment bytes as media-typed base64 data URLs.
- Inject the store into `ThreadManager`, expose it to consumers, and retain inline storage as the default for existing entry points.
## Testing
- Verify inline storage round-trips binary, text, PNG, and JPEG data.
- Verify attachment debug output redacts URLs while retaining file IDs.
GitOrigin-RevId: 7688dcd3c89d7540ed2398f3e7c63881fbfcda97