## 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
## What changed
Replace duplicated content-kind strings with constants shared by fragment producers and consumers, including authorization checks, forked-history filtering, and memory instructions. Share the compaction summary kind between core and Guardian's transcript filter.
## Testing
Add a regression test verifying that Guardian excludes compaction summaries while retaining surrounding user messages, including a user message with identical text.
GitOrigin-RevId: 36dbdf0f82c61b52d2571ac1c392fb151c98151b
## Why
Message roles and content classifications do not identify who supplied each context part. Source attribution needs to survive prompt assembly and history truncation, including messages that combine text from different producers.
## What changed
- Add per-part `ContentItemMetadata` for user input, developer instructions, `AGENTS.md`, skills, harness context, command hooks, and tool context with optional callable namespaces.
- Carry attribution alongside content and classifications through contextual fragments, extension prompts, hook output, and agent messages. Keep tool-provided context-window hints separate from harness text.
- Preserve the source of retained text slices during compaction and attribute generated truncation notices to the harness. Default missing historical attribution to unknown.
- Attribute host MCP calls using cached tool namespaces only when catalog revisions remain stable, without starting servers or refreshing catalogs for attribution.
- Send the new metadata to Responses Lite and strip it from requests to endpoints that do not support it.
## Testing
Extend compaction tests to cover mixed sources, missing or extra metadata entries, and discarded media. Update Responses Lite request assertions to verify endpoint-specific attribution handling.
GitOrigin-RevId: b0ebc929b7c60f3ec49d1affbf897312d63edcc8
## What changed
- Remove `ContentItemMetadata`, provenance and namespace types, and the `content_item_metadata` protocol field while retaining `content_item_kinds` classifications.
- Simplify context fragments, extension contributions, and hook output to carry content without source attribution. Return MCP tool results directly without an attribution wrapper.
- Render context-window hints together in a single text fragment.
## Testing
Update Responses and Responses Lite request assertions to expect content-kind classifications without per-content attribution, and adapt context, hook, and extension tests to the simplified types.
GitOrigin-RevId: 201894cd4c93c6d4b4c41c845e7a9af1dd3c95ca
## What changed
- Add `ContentItemMetadata` to distinguish user input, developer instructions, `AGENTS.md`, skills, harness context, and tool-supplied context independently of message role and content classification.
- Keep attribution attached to content through prompt assembly, history processing, and hook-output spilling. Distinguish command hooks from MCP hooks and retain tool namespaces when known.
- Treat missing historical attribution as unknown and send per-content metadata only to Responses Lite.
## Testing
Update request and history assertions to cover attribution persistence and Responses Lite metadata handling.
GitOrigin-RevId: 24e56005f5bdb98bf82f2b3943f29c4c81f3d587
## 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
- Accept `fileId` alongside the existing `url` form for app-server image inputs, and forward file references to the Responses API as `file_id`. Update generated schemas and client types.
- Preserve file references, image detail hints, and mixed inline/file image ordering through user-message events, thread history, and rollout migration. Retain file images when truncating tool output.
- Pass file references through image preparation without resolving them, while keeping resize-notice numbering correct. Omit them from unsupported TUI display and Guardian image context.
- Reject image-edit requests whose recent-image window includes a file reference, preventing selection of an older inline image instead.
## Testing
Add coverage for serialization, request and rollout preservation, mixed-image history ordering, incomplete ordering metadata, tool-output truncation, and rejection of unsupported image-edit selections.
GitOrigin-RevId: 6ca20a8577155cc934b720803c3b7b3bffdf972a
## What changed
Represent images in `ContentItem` and `FunctionCallOutputContentItem` with `ImageReference::Inline`, flattened to preserve the existing `image_url` wire format. Update image producers and consumers and regenerate app-server schemas and SDK artifacts.
Preserve the Python SDK's `InputImageContentItem` and `InputImageFunctionCallOutputContentItem` class names during generation.
## Testing
Add a regression test for stable Python image class names and adapt existing image tests to the shared representation.
GitOrigin-RevId: c38a780ac3314c2ac2deb3afc1b93b94b6f93fec
## What changed
- Add `PromptImageMode::HIGH_DETAIL` and `PromptImageMode::ORIGINAL_DETAIL`
constants with the standard resize limits.
- Use the shared modes during core image preparation instead of defining the
limits locally.
- Cover the dimension and patch budgets for both detail modes in the image
utility tests.
GitOrigin-RevId: 27fdc77719f23d2e8f1060886576b3be843a8491
## Why
Reasoning configuration changes need to retain their position and trusted provenance when model history is persisted and replayed. Client-injected history must not be able to forge these controls.
## What changed
- Add a typed `configuration_update` response item carrying reasoning effort, including custom model-defined values.
- Persist harness-authored updates with provenance and preserve them across history reconstruction, thread resume, raw response notifications, and agent forks.
- Exclude untrusted configuration updates from model history, strip client-supplied provenance metadata, and reject configuration updates supplied as turn input.
- Export the new item through the JSON and TypeScript app-server schemas and classify it in telemetry and persistence metrics.
## Testing
- Cover serialization, provenance persistence, history filtering and rollback, resume reconstruction, and injection attempts before and after restart.
GitOrigin-RevId: eb5559d2b52b7a931621e7c9812f009ff9fb8939
## Why
Image preparation can rewrite message content, including replacing images that
cannot be processed with model-visible error text. The positional content-kind
metadata must stay aligned with those rewrites.
## What changed
- Process message images together with their content-kind annotations.
- Preserve existing kinds for unchanged and resized content.
- Classify failed-image placeholders as `images.preparation_error`.
## Testing
- Cover metadata preservation across successful, resized, and failed images.
- Verify Responses Lite sends `user.image` and `images.preparation_error` kinds.
GitOrigin-RevId: 1be7bcbe47014251019bfff0d826c9dfe3239dec
## Why
External tool events may need to enter thread history without a preceding function call and therefore do not have a `call_id`.
## What changed
- Allow `function_call_output` items to omit `call_id` and carry optional `name` and `namespace` fields.
- Preserve named standalone outputs during history normalization and agent forks while retaining existing pairing behavior for outputs with a `call_id`.
- Accept, persist, and forward these outputs through `thread/inject_items`, and update the app-server schemas and documentation.
## Testing
- Cover paired and standalone JSON round trips, history normalization, agent forks, and injected thread history.
GitOrigin-RevId: a3258163a7dc93777c7c3023116fe204819bdbb0
## What changed
- Add the gated `unified_image_budget` feature for models that support original image detail or Responses Lite.
- Apply one 6,000-pixel, 10,000-patch preprocessing limit regardless of legacy image detail hints.
- Hide detail controls from `view_image` and code mode while continuing to accept existing hints for compatibility.
- Preserve detail-based resizing and tool contracts for unsupported models.
## Testing
- Cover unified resizing limits, Responses Lite, legacy detail hints, unsupported models, and `view_image` integration in code mode.
GitOrigin-RevId: cb07bff1669a96599fdfd076b3d9ec80f2b6fff7
## What changed
- Add the disabled-by-default `image_resize_notice` feature.
- When enabled, append a developer message after resized images from user
messages or tool outputs. The notice identifies each image and reports its
original and prepared dimensions.
- Persist notices with new history while avoiding backfilled notices for images
processed when a session is resumed.
## Testing
- Cover notice placement, image numbering, failed images, user and tool image
sources, and resumed-session replay.
GitOrigin-RevId: 11dd808b3ad47eac35e9e2f4a4370f85d0122770
## What changed
- Record the effective detail setting and source and prepared dimensions for
successfully decoded images.
- Associate message images with their role and tool-output images with their
originating call ID.
- Include the collected image preparation metadata in the corresponding turn
analytics event.
## Testing
- Cover image resize metadata, tool-output attribution, turn aggregation, event
serialization, and app-server analytics output.
GitOrigin-RevId: dbfb5ba1ce7cb02dd93d9b579c5109817f16aef5
When using Responses Lite, we should all use `additional_tools` and a
developer item instead of the top level tools array & instructions
field. This keeps things 1-to-1.
Forced namespacing for _all_ tools will land in a following PR after
some coordination & fixes in Responses API (around collisions & return
items).
The goal is to eventually expand the scope of this to _all_ requests
from codex, but that will require larger coordination across providers &
slower rollout.
## What
This PR will extend the existing centralized image-preparation path to
replace HTTP(S) image inputs with a model visible error message. It
won't "ruin" and break existing rollouts, but it will deprecate support
for the pathway. App server clients should no longer use HTTP image urls
if they'd like to upgrade.
The HTTP image url pathway is currently resolved in the responsesapi. It
is slow and not reccomended.
## Behavior
- HTTP(S) image URL: replace with `input_text`
- data URL: use the existing decode and resize path
- other image URL schemes: leave unchanged
This intentionally does not change app-server ingress. That validation
remains a follow-up.
## Test plan
- `just test -p codex-core -E
'test(/image_preparation|prepares_image_failures_before_history_insertion|prepares_resumed_history_before_installing_it|responses_lite_prepares_images/)'`
— 7 passed
- `just fix -p codex-core`
- `just fmt`
## Description
This PR adds an optional `metadata` field to `ResponseItem` for
Responses API calls. Only mechanical plumbing, no actual values
populated and sent yet. Turns out just adding a new field to
`ResponseItem` has quite a large blast radius already.
This change is backwards compatible because `metadata` is optional and
omitted when absent, so existing response items and rollout history
without it still deserialize and requests that do not set it keep the
same wire shape. For provider compatibility, we strip out `metadata`
before non-OpenAI Responses requests so Azure and AWS Bedrock never see
this field.
My followup PR here will actually make use of it to start storing and
passing along `turn_id`: https://github.com/openai/codex/pull/28360
## What changed
- Added `ResponseItemMetadata` with optional `turn_id`, plus optional
`metadata` on Responses API item variants and inter-agent communication.
- Preserved item metadata through response-item rewrites such as
truncation, missing tool-output synthesis, compaction history
rebuilding, visible-history conversion, rollout/resume, and generated
app-server schemas/types.
- Strip item metadata from non-OpenAI Responses requests while
preserving it for OpenAI-shaped requests.
- Updated the mechanical fixture/test construction churn required by the
new optional field.
## Summary
Adds complete client-side image preparation behind the default-off
`resize_all_images` feature flag.
When enabled, local image producers defer decoding and resizing. Images
are prepared centrally before insertion into conversation history,
covering user input, `view_image`, and structured tool-output images.
## Behavior
- Processes base64 `data:` images in messages and function/custom tool
outputs.
- Leaves non-data URLs, including HTTP(S) URLs, unchanged.
- Applies image-detail budgets:
- `high` and omitted: 2048px maximum dimension and 2.5K 32px patches.
- `original`: 6000px maximum dimension and 10K 32px patches.
- `auto`: uses the same 2048px / 2.5K-patch budget as high.
- `low`: unsupported and replaced with an actionable placeholder.
- Preserves original image bytes when no resize or format conversion is
needed.
- Enforces the shared 1 GiB encoded and decoded data-URL sanity limits.
- Replaces only an image that fails preparation, preserving sibling
content and tool-output metadata.
- Uses bounded placeholders distinguishing generic processing failures,
oversized images, and unsupported `low` detail.
- Prepares resumed and forked history before installing it as live
history without modifying persisted rollouts.
## Flag-Off Behavior
When `resize_all_images` is disabled:
- Existing local user-input and `view_image` processing remains
unchanged.
- Existing decoding and error behavior remains unchanged.
- Arbitrary tool-output images are not processed.
- HTTP(S) image URLs continue to be forwarded unchanged.
#### [git stack](https://github.com/magus/git-stack-cli)
- ✅ `1` https://github.com/openai/codex/pull/27245
- 👉 `2` https://github.com/openai/codex/pull/27247
- ⏳ `3` https://github.com/openai/codex/pull/27246
- ⏳ `4` https://github.com/openai/codex/pull/27266