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
parent 87b9275fff
commit 7999b0f60f
17 changed files with 167 additions and 22 deletions

View File

@@ -474,6 +474,7 @@ impl ThreadManager {
) -> CodexResult<NewThread> {
Box::pin(self.start_thread_with_tools_and_service_name(
config,
InitialHistory::New,
dynamic_tools,
persist_extended_history,
/*metrics_service_name*/ None,
@@ -485,6 +486,7 @@ impl ThreadManager {
pub async fn start_thread_with_tools_and_service_name(
&self,
config: Config,
initial_history: InitialHistory,
dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
persist_extended_history: bool,
metrics_service_name: Option<String>,
@@ -492,7 +494,7 @@ impl ThreadManager {
) -> CodexResult<NewThread> {
Box::pin(self.state.spawn_thread(
config,
InitialHistory::New,
initial_history,
Arc::clone(&self.state.auth_manager),
self.agent_control(),
dynamic_tools,
@@ -668,6 +670,7 @@ impl ThreadManager {
ForkSnapshot::Interrupted => {
let history = match history {
InitialHistory::New => InitialHistory::New,
InitialHistory::Cleared => InitialHistory::Cleared,
InitialHistory::Forked(history) => InitialHistory::Forked(history),
InitialHistory::Resumed(resumed) => InitialHistory::Forked(resumed.history),
};
@@ -1070,7 +1073,7 @@ fn append_interrupted_boundary(history: InitialHistory, turn_id: Option<String>)
}));
match history {
InitialHistory::New => InitialHistory::Forked(vec![
InitialHistory::New | InitialHistory::Cleared => InitialHistory::Forked(vec![
RolloutItem::ResponseItem(interrupted_turn_history_marker()),
aborted_event,
]),