## Why
Unified exec can yield while a command is still running. Plugin measurement
collection must remain active until that background command exits, including
when its item completion arrives after the turn has completed.
## What changed
- Keep the plugin metrics sidecar with the stored process and let either the
exit watcher or a poll that observes completion finalize it exactly once.
- Retain completed turn analytics state while tool items are pending so late
command completion events can be emitted without duplicating the turn event.
## Testing
- Verify that a background command completed after its turn emits a command
execution event and does not emit a second turn event.
GitOrigin-RevId: ecf715b3e047aa29ca9a417d12d955257fed8557
## What changed
- Add `TurnInputRequest` and typed submission results for atomically starting a turn, steering the active turn, or declining input with a specific reason.
- Expose `start_or_steer_turn`, `start_turn_if_idle`, and `steer_turn` on `CodexThread`, and migrate Core consumers to these APIs.
- Make app-server `turn/start` steer an active regular turn and return that turn's ID. Reject incompatible output schemas and non-steerable turns without applying settings or enqueueing input.
## Testing
- Cover concurrent start-or-steer submissions, accepted and rejected settings updates, output-schema compatibility, idle-start rejection, and app-server steering.
GitOrigin-RevId: dd9b5528d76ec650c019e97af420bc13190ea86a
## Why
World-state snapshots and merge patches are keyed collections of sections. Allowing
their persisted `state` field to contain any JSON value required replay code to
handle shapes that cannot represent world state.
## What changed
- Type `WorldStateItem.state` and snapshot patches as JSON object maps.
- Reconstruct full snapshots directly from those maps and apply patches without
fallible arbitrary-value conversions.
- Regenerate the app-server protocol schema for the object-only representation.
GitOrigin-RevId: 3d7662b74f3dd1f3ccc5fdd0200074c13a73cbe5
## What changed
- Add fractional Unix creation times to locally authored user, developer, agent, and tool-output items when they enter durable conversation history.
- Preserve any creation time already supplied with an item across subsequent requests, remote compaction, and resumed history.
## Testing
- Cover timestamp assignment and preservation in session, client, tool, agent-spawn, and remote-compaction tests.
GitOrigin-RevId: 431d1770b9746005c808bc0a43953845166d68ad
## Why
Skill catalogs can present shortened package locators, but callers previously had
to expand those aliases before reading a skill.
## What changed
- Resolve catalog aliases automatically when `skills.read` looks up a
model-visible executor or orchestrator skill package.
- Update skill prompts and tool documentation to tell models to pass the listed
package locator directly.
## Testing
- Exercise reading an executor skill through its shortened package locator when
the skills catalog exceeds its context budget.
GitOrigin-RevId: d1cdfd64002510b616146929deb5b7077850b951
## What changed
- Use each `ExternalAuth` provider's error classification for resolve, refresh,
and validation failures.
- Allow runtime providers to be replaced, clearing any recorded permanent
refresh failure after the replacement resolves successfully.
- Preserve workload identity as immutable, host-managed authentication while
sharing external ChatGPT credentials through the process-local store.
## Testing
- Cover provider replacement after a permanent failure, provider-defined error
classification, workload identity immutability, and refreshed headers after
an unauthorized response.
GitOrigin-RevId: ec75cf9224dc82d3fd10063606c724e3b06fb1e7
## Why
A single execution can trigger multiple network approval reviews. Its tool
result should reflect the latest specific rejection.
## What changed
- Let each explicit network review outcome replace the previously recorded
outcome for the execution.
- Keep generic blocked-request messages as fallbacks that cannot overwrite an
explicit review outcome.
## Testing
- Add unit coverage for outcome precedence.
- Add an integration test that rejects two network requests from one execution
and verifies that only the latest rejection is returned.
GitOrigin-RevId: 644a01e5c49855adcdc48ba8f91baededce26875
## What changed
- Create a metrics sidecar for attributed local plugin commands launched through unified exec, and grant the sandbox access to its output file.
- Publish valid measurements when the initial command exits, while discarding the sidecar when the process remains live for later polling.
- Strip inherited or configured `CODEX_PLUGIN_METRICS_OUTPUT` values so each command can only use its own sidecar.
GitOrigin-RevId: 43e669e4c77171aec8a798de0c12ca13bfb8adee
## What changed
- Provide matching local plugin commands with a sandbox-writable temporary output file through `CODEX_PLUGIN_METRICS_OUTPUT` when analytics is enabled.
- Validate successful command output against the plugin's `analytics.yaml` declaration, including measurement names, enum dimensions, finite values, duplicate rows, and size limits, before publishing analytics events.
- Keep the output path reserved from user overrides and clean up the temporary file after execution.
## Testing
- Cover output validation, limits, cleanup, sandbox permissions, environment handling, and path replacement.
- Verify measurement collection through both classic and zsh-fork shell runtimes.
GitOrigin-RevId: 88af0f87dc2f207fcbcca6af498f5c940d79349d
## What changed
- Extract `x-models-etag` from `codex.response.metadata` events and emit it as a `ModelsEtag` response event.
- Stop reading or reporting the model ETag from WebSocket upgrade headers.
## Testing
- Update the WebSocket response-stream test to deliver the ETag through a metadata event and verify that it is emitted.
GitOrigin-RevId: 9b9cff3d8a0a914549aca62d8d316483a9a47f69
## What changed
- Add `http_headers_helper` configuration for local streamable HTTP MCP servers. The configured shell command runs once per connection and returns a JSON object of headers that is cached across requests.
- Apply helper headers to MCP startup and OAuth flows while restricting them to the server origin, stopping redirects, rejecting reserved or duplicate headers, and enforcing output and execution limits.
- Reject helpers for remote or managed-disabled servers, use the local environment working directory, and redact helper commands from `codex mcp list` and `codex mcp get` output.
## Testing
- Cover configuration validation, helper lifecycle and output parsing, origin isolation, OAuth discovery and token refresh, managed requirements, environment selection, and CLI redaction.
GitOrigin-RevId: 84e0e26ce75520b0869d37c72b1678e033bd6818
## What changed
- Mark developer messages received from clients with `client_authored` harness
metadata when `retain_client_developer_messages` is enabled.
- Carry that provenance through pending input and persist it alongside rollout
response items without adding it to provider requests or the serialized
`TurnInput` payload.
- Preserve existing behavior for unannotated response items and when the
feature is disabled.
## Testing
- Cover client item injection before and during turns, additional application
context, rollout replay, image resize notices, and serialization boundaries.
GitOrigin-RevId: f385c177732becde732272e4b8440eb91f5c1039
## What changed
- Parse `node_repl_auto_review_required` and `node_repl_disabled` from model catalog entries and include their values in each turn's Responses API metadata.
- Treat both fields as reserved metadata so client-provided values cannot override the selected model's policy.
- Use the selected review model's catalog entry when building metadata for review turns.
## Testing
- Cover metadata propagation across model switches, review turns, Responses API requests, and MCP tool calls.
GitOrigin-RevId: c1f63426eeb8e559abff439fbc618716a4908aff
## Why
`parent_turn_id` identifies the immediate caller of a nested request, but not the
top-level turn that initiated a multi-level chain of work.
## What changed
- Add `root_turn_id` to turn state, submissions, and Responses API metadata.
- Propagate the root through spawned agents, delegated work, review sessions, and
turn-triggering inter-agent messages.
- Omit the root when background work has no user turn or combined input makes the
root ambiguous.
## Testing
Added coverage for nested agent resumes, reviews, mailbox delivery, steered input,
and reserved metadata handling.
GitOrigin-RevId: 60057db2ee81f4efefa946a9f63c74ff98b93929
## What changed
- Register `retain_client_developer_messages` as an under-development feature
that is disabled by default.
- Expose the feature in the configuration schema.
GitOrigin-RevId: dc56c48fe79a9f288b7fe0a11d97af992d36797f
## Why
Subagents can reuse cached MCP tool definitions without opening another server
connection immediately, but marking a server as required previously forced eager
startup even when its cached tools were available.
## What changed
- Allow required MCP servers with usable cached tools to remain dormant under
the lazy startup policy.
- Treat those cached tools as satisfying required-server validation and tool
catalog capture until the server is needed.
- Preserve eager startup for required servers without cached tools and start a
dormant server when one of its tools is called.
## Testing
Extend the cached HTTP MCP subagent test to cover both optional and required
servers, verifying that the required server stays dormant until its cached tool
is called.
GitOrigin-RevId: 48ea20b9ae447eef27461caee2320ea78465bb6a
## What changed
- Require delegated Codex sessions to use the `never` approval policy and reject
delegate creation with any prompt-capable policy.
- Stop forwarding delegate approval and permission requests to the parent
session. Approval-requiring commands and MCP tool calls are denied within the
delegate instead.
- Skip prompts for missing skill MCP dependencies when approvals are disabled.
## Testing
Add coverage for review and Guardian delegates to verify that command
escalations, MCP approvals, and skill dependency installation do not prompt or
execute approval-gated actions.
GitOrigin-RevId: fee96a97624352cd25c904592ba7eebe2ae3fd63
## Why
The search tool integration test suite was disabled entirely on Windows.
## What changed
- Remove the suite-wide Windows exclusion and build test fixtures with automatic environment selection.
- Configure stdio MCP fixtures with environment-aware server paths and environment IDs for local and remote runs.
- Skip the three stdio MCP cases that still require a native Windows test server when running through Wine.
GitOrigin-RevId: cf6f919bed28722996680dd0a085c1d1f80e4dcb
## What changed
- Add an embedded `defaults.toml` and always install it as the lowest-precedence configuration layer when no packaged-defaults path is supplied.
- Keep packaged defaults out of config RPC layer and origin metadata.
- Report a user setting as overridden only when the effective layer has higher precedence, so clearing a setting can fall back to its packaged default without a false override.
## Testing
- Cover loading the packaged layer when other configuration files are absent.
- Cover config RPC filtering and clearing a user value that falls back to a packaged default.
GitOrigin-RevId: c1c0e1e681e4ac1be2602550972533443c5df51b
## Why
Executor skills required a `skills.list` lookup before their contents could be
read, even when the catalog already identified the skill.
## What changed
- Render executor skill catalog entries as package locators, including shortened
locators when skill roots are aliased.
- Tell the model to pass those packages directly to `skills.read`, while keeping
`skills.list` as the fallback when no package is available.
- Use the shorter package locators when applying the skills context budget.
## Testing
Update catalog, aliasing, budget-pressure, and selected-skill coverage, including
an executor package ID containing a literal backslash.
GitOrigin-RevId: 2ace5e527dc4f29651a8f3214475ccc90d52c73f
## What changed
- Represent MCP tool calls as approval actions and route them through the
session-level approval flow for permission hooks, reviewer selection,
rejection handling, and resolution telemetry.
- Preserve MCP-specific user prompts, session and persistent approval choices,
and the approval policy and reviewer captured for the tool call.
## Testing
- Add coverage for permission hooks resolving MCP calls before user or
automatic review, persistence choices, captured policy routing, and MCP turn
metadata with strict automatic review enabled.
GitOrigin-RevId: 8e134b3d17a19dc62b3b56076d2cd05a54c9f638
## What changed
- Include the connector ID, action name, and model in file creation requests for hosted app tool calls.
- Use the file size returned by upload finalization when available, while falling back to the local size for older server responses.
- Keep upload finalization requests empty for compatibility with older servers.
## Testing
- Cover hosted app upload metadata and legacy finalization responses.
GitOrigin-RevId: 1bc834736db4fe3515f8224965cde0e5d6955ca3
## What changed
Add integration coverage verifying that Guardian receives both the user prompt
and the outer code mode `exec` source when reviewing a nested escalated
`exec_command` call.
GitOrigin-RevId: e78e9d4d69e7ebccc935c548565a07600659f65a
## What changed
- Resolve user message admission when Core accepts the input as a new turn or a steer, without waiting for rollout persistence.
- Remove persistence- and hook-specific admission errors and task bookkeeping.
- Delete queued messages after Core accepts them for turn processing, including messages subsequently stopped by a prompt hook.
## Testing
- Update concurrent admission and queue service tests for acceptance-based admission.
GitOrigin-RevId: 7dcc311cfecd3d710733b420f2add546edb86153
## What changed
- Permit immediate user-message admission to start a turn when `Op::UserInput`
has no items. The turn can proceed with its generated environment context and
does not emit a user-message item.
- Continue rejecting empty input for persisted admission, where there is no
user message to persist.
## Testing
- Cover successful empty-input turn admission and completion.
- Cover prompt rejection of empty persisted admission.
GitOrigin-RevId: d534cf0e228e3bc77f45fe6d9bd25c9073216fbd
## What changed
- Add `ApprovedMcpPolicyAmendment` to represent MCP approvals that persist across sessions.
- Route MCP approval responses directly through the shared `ReviewDecision` type while preserving session-only approvals, rejection reasons, timeouts, and cancellations.
- Reject the MCP-only policy decision if it reaches command, shell, network, or other tool approval paths.
## Testing
- Update MCP approval parsing, normalization, hook, and Guardian tests for the shared decisions.
- Verify generic tool approvals reject MCP policy amendments.
GitOrigin-RevId: b8cc931dc61d4c794915145273ede82b9eb30fc8
## What changed
- Deserialize typed section snapshots directly from borrowed JSON values.
- Build and apply world-state merge patches in place instead of cloning and converting entire snapshots.
- Preserve the existing snapshot when a top-level patch has an invalid shape.
## Testing
- Extend the world-state merge-patch test to cover invalid top-level patches and verify that they leave the snapshot unchanged.
GitOrigin-RevId: 6c2212587b025a8dc3878008a0466d4526eee204
## What changed
- Detect executor-owned skill document reads and script executions across native and URI-based working directories.
- Match skills only within the active execution environment while preserving host skill detection for local commands.
- Emit resource-backed implicit invocation events and deduplicate repeated accesses within a turn.
## Testing
- Add unit coverage for document reads, script executions, and environment-scoped matching.
- Add an integration test for environment selection, resource-backed analytics, and repeated-access deduplication.
GitOrigin-RevId: f78a48c3a4766fe8775bd88926b45a76761f6af8
## Why
Threads that share an executor environment can require different capability roots and login-shell policies. Treating readiness configuration as executor-wide can expose one thread's settings to another.
## What changed
- Add `CodexThread::environment_ready` and `EnvironmentConfig` so hosts can install capability roots and login-shell policy for an exact thread, environment, and working-directory attachment.
- Validate attachment readiness updates, merge ready attachment roots with persisted thread roots, and refresh MCP capabilities when those roots change.
- Preserve installed environment policy across thread settings updates and child-thread inheritance while resetting it when the selected working directory changes.
## Testing
- Cover attachment config inheritance and reset behavior.
- Verify that threads sharing an executor retain independent model-visible capability roots and login-shell tool schemas across updates.
GitOrigin-RevId: 60e7a296b3e41b835b0413aa2837451e8a55c230
## What changed
- Emit skill invocation analytics when a resource-backed skill is explicitly selected or its main resource is successfully read from the first page.
- Preserve provider-supplied skill IDs and user scope when available, and derive a stable ID from the main resource otherwise.
- Deduplicate repeated implicit reads of the same main resource within a turn.
## Testing
- Extend the orchestrator skill integration test to cover explicit and implicit invocation events, stable fallback IDs, failed reads, and repeated-read deduplication.
GitOrigin-RevId: 7d8453b31b5a2205847e65cda2c46183d6c97b45
## What changed
- Set `store` to `false` for every Responses request, including requests sent
through Azure providers.
- Remove the provider-specific storage check and simplify request construction.
- Update the Azure request test to verify that storage is disabled while
prefixed item IDs remain unchanged.
GitOrigin-RevId: 1c71cb80880058cb26789112f03269b73f0645b9
## What changed
- Wrap response items with optional harness-owned metadata while keeping the persisted response payload shape backward compatible.
- Store compacted-history metadata in an aligned sidecar and reject malformed sidecars.
- Carry metadata through history normalization, compaction, resume, fork, truncation, migration, and rollout recording without sending it to model providers.
## Testing
- Cover legacy rollout compatibility, metadata serialization and validation, compaction retention, and resume/fork reconstruction.
GitOrigin-RevId: 17a6127c9048ff984cb4df4d97c0751a38c29f5f
## What changed
- Recognize validated create and edit marker commands from the trusted presentations, documents, spreadsheets, and PDF plugins.
- Emit a `codex_artifact_operation` analytics event plus started-count and expected-output-count metrics when a recognized marker starts through unified exec.
- Attribute remote executor commands only when their plugin cache path and script contents match a trusted local plugin, including primary-runtime plugins.
## Testing
- Cover supported marker combinations and reject mismatched plugins, paths, arguments, counts, and output formats.
- Cover local, relocated remote, and Windows-style plugin attribution, including rejection of modified remote scripts.
GitOrigin-RevId: 475cc1689aa7f371a24dec0a8bdb6f7fd5a2e922
## What changed
- Add the under-development `psp` feature and expose it in the config schema.
- Use the feature to attach the PSP cookie to first-party ChatGPT clients.
- Remove the hidden `--psp` flag and its process-scoped configuration plumbing.
- Preserve configured ChatGPT cookies when creating the PSP client used for GET and POST requests.
## Testing
- Update the config manager service test to verify that enabling `features.psp` retains the setting in the effective config and configures the expected ChatGPT cookie.
GitOrigin-RevId: 53acb5495d2ff71e4ed25f674a0cff787aea474a
## What changed
- Add a host-owned external auth source that runtime account APIs cannot replace,
clear, or log out, and keep its credentials process-local instead of writing
them to auth storage.
- Let configured providers classify refresh failures. Preserve cached credentials
after permanent reload failures while retaining transient behavior for runtime
providers.
- Compare external ChatGPT token data when detecting auth changes so a refreshed
access token is applied to a retried request.
## Testing
- Cover configured-auth immutability, process-local storage, permanent reload
failures, runtime error classification, and refreshed headers after a `401`.
GitOrigin-RevId: c6d70a39325c8ba6ca65ae68e12b55609f00a876
## What changed
- Add `--oauth-client-registration` with `auto` and `dcr` choices to `codex mcp add` and `codex mcp login`.
- Add the equivalent optional `clientRegistration` field to `mcpServer/oauth/login` and the generated protocol schemas.
- Keep automatic dynamic client registration as the default, prefer a configured OAuth client ID when present, and apply the selection only to the current login without persisting it in MCP configuration.
## Testing
- Cover dynamic registration and configured-client OAuth flows through the app server.
- Verify the CLI does not persist the per-login registration choice.
GitOrigin-RevId: 653a4a1054ff43c2c5d52ae863b6a96d21692a53
## What changed
- Add `inject_response_items_for_turn` for callers that inject Responses API
items immediately before admitting user input. It defers the rollout flush so
the injected items and user input are persisted together by turn admission.
- Keep `inject_response_items` behavior unchanged by flushing after it delegates
to the new helper.
- Update the turn-start persistence test to exercise the turn-aware path.
GitOrigin-RevId: 8349b65f937af2b2a95d36b3fd73d862d38e5fd9
## What changed
- Add `auto_review_enabled` to serialized turn metadata for regular and review turns.
- Derive the value from approval-policy routing and reserve the metadata key so client-provided metadata cannot override it.
## Testing
- Cover enabled metadata, reserved-key handling, Guardian review requests, and updated compaction request snapshots.
GitOrigin-RevId: 52773e2bf7d4be251f8466332de9f9c9869dd084
## What changed
- Add `ResponseItemEnvelope` as the history-owned wrapper for a `ResponseItem`.
- Store envelopes in `ContextManager` while keeping raw-item iteration and consuming APIs for existing callers.
- Preserve envelopes when compaction and history normalization rewrite retained items, and wrap newly synthesized items.
## Testing
- Cover envelope access, mutation, and conversion back to raw response items.
- Cover annotated history replacement and annotated user-message collection for compaction.
GitOrigin-RevId: 3fa2e7bdd981b08cc7aec410c80deccaecdabab4
## Why
Cross-platform remote `apply_patch` calls were rejected when filesystem writes
were restricted because patch verification and writes could not be safely
performed against executor files.
## What changed
- Route intercepted and direct remote patches through the executor-managed
filesystem sandbox, including the configured workspace roots.
- Select the restricted-token sandbox for Windows executor paths when no
Windows sandbox level was configured.
- Fail closed when an executor cannot enforce the requested sandbox, and treat
executor-managed access failures as sandbox denials so approval can retry the
patch without sandboxing.
## Testing
- Cover sandboxed remote patches, denied writes, approval retries, Windows
sandbox selection, and executor filesystem enforcement.
GitOrigin-RevId: caddeed0b266c456a689080a14a3a58e2bd7887c
## What changed
- Add structured `usageLimitExceeded` metadata to failed image-generation
items, including the image limit ID and optional reset timestamp.
- Preserve the failure metadata in completion events, app-server thread
history, thread reads and resumes, and migrated legacy rollouts.
- Export the new failure type in the generated JSON and TypeScript schemas.
## Testing
- Cover usage-limit responses through item completion, persistence, and thread
resume.
- Verify legacy rollout migration retains image-generation failure metadata.
GitOrigin-RevId: 91c31a2a47456b6b916ee03002ff314b05946dd4
## What changed
- Remove effective-config lockfile export, replay, and validation from session startup.
- Remove the `debug.config_lockfile` settings and generated schema entries.
- Remove feature-config materialization helpers that were only used to create lockfiles.
GitOrigin-RevId: a8c07c1c06325b3ec3dae9a97c36c2488d37df25
## What changed
- Import skill metadata and mention helpers directly from `codex-skills`.
- Import host skill loading types directly from `codex-skills-extension`.
- Make the remaining `codex-core` skills module private and remove its skill API re-exports, including the `HostSkillsService` re-export from `codex-core-api`.
GitOrigin-RevId: 26bf8fffd980df9c4d0c308d7e983ceab9a5df82
## Why
`skills/list` can load multiple working directories in one request, but bundled
skill discovery did not account for different effective configurations across
those directories.
## What changed
- Resolve `skills.bundled.enabled` from each load input's effective config layer
stack inside the host skills service.
- Include or exclude system-scoped skills for each working directory based on
that resolved setting.
- Keep bundled skills enabled by default when the setting is absent or invalid.
## Testing
- Add a multi-directory `skills/list` test with bundled skills disabled in one
project and enabled in another.
- Add config-layer tests for defaults, overrides, and malformed bundled-skill
configuration.
GitOrigin-RevId: e4e97dc7d0a374ac71d0aa11e55a9e337f661717
## Why
Subagents should be able to use known HTTP MCP tool definitions without opening a connection until a tool is actually called.
## What changed
- Add streamable HTTP configurations to the process-scoped MCP tool catalog cache when their authentication identity can be derived safely.
- Fingerprint transport settings, relevant environment variables, protocol mode, plugin status, and client capabilities so catalogs are reused only across equivalent connections.
- Keep OAuth and other dynamically resolved credential configurations out of the shared cache.
## Testing
- Add an integration test proving that a subagent receives cached HTTP tools without reinitializing the server, then starts its own connection when it calls one.
GitOrigin-RevId: bb2787e29e9b71993def31aafd1f0d8f1b728d26
## What changed
- Reject invalid or unsupported image data before producing tool output, so
non-image file contents are not exposed through code mode.
- Preserve valid image bytes and metadata while leaving image preparation and
resizing to the history insertion path.
## Testing
- Cover invalid images in both code mode and standard `view_image` calls.
- Verify that code mode preserves PNG bytes, dimensions, EXIF orientation, and
metadata.
GitOrigin-RevId: 07343ed10b781d0ce0ffb5b24432658be4c046e3
## What changed
- Add `PersistContext` to the thread-store persistence contract so stores can
identify persistence requested immediately before model sampling. A
`TurnStart` request may be enqueued in the background when later flush and
shutdown operations fence it and report any failure; all other persistence
remains synchronous.
- Use the turn-start context only for the initial input of a regular turn, while
admission acknowledgments, steered input, and other persistence paths keep
the standard durability behavior.
- Flush pending metadata before turn-start persistence and ensure shutdown is
still attempted if that metadata update fails.
## Testing
- Verify that developer instructions and user input are persisted before the
model request completes for a default paginated-history thread.
GitOrigin-RevId: 162f0ec796a61aebe66ca0b909fbcccec3047b85
## Why
Background refreshes previously warmed only the on-disk cache, so new sessions in the same process continued using the startup snapshot.
## What changed
- Make `CloudConfigBundleLoader` retrieve the latest shared bundle on each configuration load.
- Update the in-memory bundle after successful refreshes while preserving the last successful bundle when a refresh fails.
- Stop refresh work when its loader is replaced or its final clone is dropped.
## Testing
- Cover refreshed requirements and managed configuration in later sessions.
- Cover concurrent initial loads, refresh failures and recovery, bundle clearing, and refresh-task cancellation.
GitOrigin-RevId: ae3d79b575bad71a1eed370cee6dc66dc022ffa8
## What changed
- Pass image bytes from `view_image` through unchanged for both direct and code-mode calls, leaving decoding and resizing to the shared history-insertion path.
- Represent invalid image data with the existing image-omission placeholder instead of returning a tool error.
## Testing
- Update the `view_image` integration test to cover placeholder output for invalid image data.
GitOrigin-RevId: 62863defd4815efb8a7725712fd583ad81db3fbb