Support clear SessionStart source (#17073)

## Motivation

The `SessionStart` hook already receives `startup` and `resume` sources,
but sessions created from `/clear` previously looked like normal startup
sessions. This makes it impossible for hook authors to distinguish
between these with the matcher.

## Summary

- Add `InitialHistory::Cleared` so `/clear`-created sessions can be
distinguished from ordinary startup sessions.
- Add `SessionStartSource::Clear` and wire it through core, app-server
thread start params, and TUI clear-session flow.
- Update app-server protocol schemas, generated TypeScript, docs, and
related tests.


https://github.com/user-attachments/assets/9cae3cb4-41c7-4d06-b34f-966252442e5c
This commit is contained in:
Abhinav
2026-04-10 16:05:21 -07:00
committed by GitHub
Unverified
parent 87b9275fff
commit 7999b0f60f
17 changed files with 167 additions and 22 deletions
@@ -2236,6 +2236,7 @@ impl CodexMessageProcessor {
experimental_raw_events,
personality,
ephemeral,
session_start_source,
persist_extended_history,
} = params;
let mut typesafe_overrides = self.build_thread_config_overrides(
@@ -2277,6 +2278,7 @@ impl CodexMessageProcessor {
config,
typesafe_overrides,
dynamic_tools,
session_start_source,
persist_extended_history,
service_name,
experimental_raw_events,
@@ -2352,6 +2354,7 @@ impl CodexMessageProcessor {
config_overrides: Option<HashMap<String, serde_json::Value>>,
typesafe_overrides: ConfigOverrides,
dynamic_tools: Option<Vec<ApiDynamicToolSpec>>,
session_start_source: Option<codex_app_server_protocol::ThreadStartSource>,
persist_extended_history: bool,
service_name: Option<String>,
experimental_raw_events: bool,
@@ -2475,6 +2478,12 @@ impl CodexMessageProcessor {
.thread_manager
.start_thread_with_tools_and_service_name(
config,
match session_start_source
.unwrap_or(codex_app_server_protocol::ThreadStartSource::Startup)
{
codex_app_server_protocol::ThreadStartSource::Startup => InitialHistory::New,
codex_app_server_protocol::ThreadStartSource::Clear => InitialHistory::Cleared,
},
core_dynamic_tools,
persist_extended_history,
service_name,
@@ -4443,7 +4452,7 @@ impl CodexMessageProcessor {
thread.preview = preview_from_rollout_items(items);
Ok(thread)
}
InitialHistory::New => Err(format!(
InitialHistory::New | InitialHistory::Cleared => Err(format!(
"failed to build resume response for thread {thread_id}: initial history missing"
)),
};
@@ -9114,7 +9123,7 @@ pub(crate) async fn read_rollout_items_from_rollout(
path: &Path,
) -> std::io::Result<Vec<RolloutItem>> {
let items = match RolloutRecorder::get_rollout_history(path).await? {
InitialHistory::New => Vec::new(),
InitialHistory::New | InitialHistory::Cleared => Vec::new(),
InitialHistory::Forked(items) => items,
InitialHistory::Resumed(resumed) => resumed.history,
};