mirror of
https://github.com/openai/codex.git
synced 2026-11-11 02:29:10 +00:00
feat: add turn lifecycle contributors (#22480)
## Why Extensions can already contribute prompt, tool, turn-item, and thread-lifecycle behavior, but there was no explicit host-owned hook for per-turn setup and cleanup. That makes extension-private turn state awkward: an extension either has to stash it outside the turn lifecycle or depend on core runtime objects. This adds a small turn lifecycle boundary. Extensions receive stable identifiers plus the existing session, thread, and turn `ExtensionData` stores, while core keeps owning task scheduling, cancellation, and turn teardown. ## What Changed - Added `TurnLifecycleContributor` with `on_turn_start`, `on_turn_stop`, and `on_turn_abort` callbacks in `codex-rs/ext/extension-api`. - Added typed `TurnStartInput`, `TurnStopInput`, and `TurnAbortInput` payloads that expose `thread_id`, `turn_id`, `session_store`, `thread_store`, and `turn_store`. - Registered and re-exported turn lifecycle contributors through `ExtensionRegistry` and `ExtensionRegistryBuilder`. - Wired `Session` to emit turn start, stop, and abort callbacks from the existing turn/task lifecycle paths. - Carried the turn-scoped `ExtensionData` through `RunningTask` and `RemovedTask` so stop/abort callbacks receive the same turn store created at turn start. ## Verification - Not run locally.
This commit is contained in:
1 parent
e831db7a96
commit
27e67a8c2a
7 files changed
+180
-2
No files matched your search
@@ -1,5 +1,6 @@
|
||||
//! Turn-scoped state and active turn metadata scaffolding.
|
||||
|
||||
use codex_extension_api::ExtensionData;
|
||||
use codex_sandboxing::policy_transforms::merge_permission_profiles;
|
||||
use indexmap::IndexMap;
|
||||
use std::collections::HashMap;
|
||||
@@ -75,6 +76,7 @@ pub(crate) struct RunningTask {
|
||||
pub(crate) cancellation_token: CancellationToken,
|
||||
pub(crate) handle: AbortOnDropHandle<()>,
|
||||
pub(crate) turn_context: Arc<TurnContext>,
|
||||
pub(crate) turn_extension_data: Arc<ExtensionData>,
|
||||
// Timer recorded when the task drops to capture the full turn duration.
|
||||
pub(crate) _timer: Option<codex_otel::Timer>,
|
||||
}
|
||||
@@ -82,6 +84,7 @@ pub(crate) struct RunningTask {
|
||||
pub(crate) struct RemovedTask {
|
||||
pub(crate) records_turn_token_usage_on_span: bool,
|
||||
pub(crate) active_turn_is_empty: bool,
|
||||
pub(crate) turn_extension_data: Arc<ExtensionData>,
|
||||
}
|
||||
|
||||
impl ActiveTurn {
|
||||
@@ -97,6 +100,7 @@ impl ActiveTurn {
|
||||
Some(RemovedTask {
|
||||
records_turn_token_usage_on_span,
|
||||
active_turn_is_empty: self.tasks.is_empty(),
|
||||
turn_extension_data: task.turn_extension_data,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -120,6 +124,7 @@ pub(crate) struct TurnState {
|
||||
pub(crate) tool_calls: u64,
|
||||
pub(crate) has_memory_citation: bool,
|
||||
pub(crate) token_usage_at_turn_start: TokenUsage,
|
||||
pub(crate) extension_data: Arc<ExtensionData>,
|
||||
}
|
||||
|
||||
pub(crate) struct PendingRequestPermissions {
|
||||
|
||||
Reference in new issue
Block a user