feat: add extension turn-input contributors (#25959)

## Disclaimer
Do not use for now

## Why

Extensions can already contribute prompt fragments and request same-turn
item injection, but there was no host-owned hook for contributing
structured `ResponseItem`s while Codex is assembling a new turn's
initial model input. This change adds that seam so extensions can attach
turn-local input that depends on the submitted user input and resolved
turn environments without routing through prompt text or late injection.

## What changed

- add `TurnInputContributor` to `codex_extension_api` and export the new
`TurnInputContext` / `TurnInputEnvironment` types it receives
- teach `ExtensionRegistry` to register and expose turn-input
contributors alongside the existing extension hooks
- call registered turn-input contributors from
`core/src/session/turn.rs` while building the initial injected input for
a turn, then append their returned `ResponseItem`s after the skill and
plugin injections
This commit is contained in:
jif authored and GitHub committed 2026-06-03 01:33:31 +02:00
1 parent a28b32a835
commit 271d5cecf2
5 files changed
+120

No files matched your search

@@ -2,6 +2,7 @@ use std::future::Future;
use std::sync::Arc;
use codex_protocol::items::TurnItem;
use codex_protocol::models::ResponseItem;
use codex_protocol::protocol::ReviewDecision;
use codex_protocol::protocol::TokenUsageInfo;
use codex_tools::ToolCall;
@@ -12,6 +13,7 @@ use crate::ExtensionData;
mod prompt;
mod thread_lifecycle;
mod tool_lifecycle;
mod turn_input;
mod turn_lifecycle;
pub use prompt::PromptFragment;
@@ -25,6 +27,8 @@ pub use tool_lifecycle::ToolCallSource;
pub use tool_lifecycle::ToolFinishInput;
pub use tool_lifecycle::ToolLifecycleFuture;
pub use tool_lifecycle::ToolStartInput;
pub use turn_input::TurnInputContext;
pub use turn_input::TurnInputEnvironment;
pub use turn_lifecycle::TurnAbortInput;
pub use turn_lifecycle::TurnErrorInput;
pub use turn_lifecycle::TurnStartInput;
@@ -85,6 +89,25 @@ pub trait TurnLifecycleContributor: Send + Sync {
async fn on_turn_error(&self, _input: TurnErrorInput<'_>) {}
}
/// WARNING: DO NOT USE YET
/// Extension contribution that can add turn-local model input.
///
/// Implementations should resolve only the model-visible input they own and
/// must preserve authority boundaries for external resources. Expensive or
/// host-specific dependencies belong on the extension value installed by the
/// host, not in this input.
#[async_trait::async_trait]
pub trait TurnInputContributor: Send + Sync {
/// Returns additional model input items for one submitted turn.
async fn contribute(
&self,
input: TurnInputContext,
session_store: &ExtensionData,
thread_store: &ExtensionData,
turn_store: &ExtensionData,
) -> Vec<ResponseItem>;
}
/// Contributor for host-owned configuration changes.
///
/// Implementations should treat the supplied values as immutable before/after