mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
tui: include exec sessions in resume list (#24503)
## Why Fixes #24502. `codex resume --include-non-interactive` should include sessions created by `codex exec`, but the TUI was sending no `sourceKinds` filter to `thread/list` for that mode. `thread/list` treats omitted or empty `sourceKinds` as interactive-only (`cli`, `vscode`), so exec sessions were still filtered out. ## What Changed - Added a shared TUI `resume_source_kinds` helper so both resume lookup paths always pass explicit `sourceKinds` to `thread/list`. - Kept the default resume behavior scoped to `cli` and `vscode`. - Made `--include-non-interactive` include `exec` and `appServer` sessions, while continuing to exclude subagent and unknown sources. ## Verification Added focused coverage for both affected TUI request builders: - `latest_session_lookup_params_can_include_non_interactive_sources` - `remote_thread_list_params_can_include_non_interactive_sources`
This commit is contained in:
committed by
GitHub
Unverified
parent
ff7513cd83
commit
b84c5898df
+35
-2
@@ -651,6 +651,17 @@ fn session_target_from_app_server_thread(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resume_source_kinds(include_non_interactive: bool) -> Vec<ThreadSourceKind> {
|
||||
let mut source_kinds = vec![ThreadSourceKind::Cli, ThreadSourceKind::VsCode];
|
||||
if include_non_interactive {
|
||||
// `thread/list` treats omitted and empty `sourceKinds` as interactive-only,
|
||||
// so include-non-interactive has to name the user-resumable non-interactive
|
||||
// sources explicitly until the API grows an unfiltered request.
|
||||
source_kinds.extend([ThreadSourceKind::Exec, ThreadSourceKind::AppServer]);
|
||||
}
|
||||
source_kinds
|
||||
}
|
||||
|
||||
async fn lookup_session_target_by_name_with_app_server(
|
||||
app_server: &mut AppServerSession,
|
||||
name: &str,
|
||||
@@ -756,8 +767,7 @@ fn latest_session_lookup_params(
|
||||
} else {
|
||||
Some(vec![config.model_provider_id.clone()])
|
||||
},
|
||||
source_kinds: (!include_non_interactive)
|
||||
.then_some(vec![ThreadSourceKind::Cli, ThreadSourceKind::VsCode]),
|
||||
source_kinds: Some(resume_source_kinds(include_non_interactive)),
|
||||
archived: Some(false),
|
||||
cwd: cwd_filter.map(|cwd| ThreadListCwdFilter::One(cwd.to_string_lossy().to_string())),
|
||||
use_state_db_only: false,
|
||||
@@ -2295,6 +2305,29 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn latest_session_lookup_params_can_include_non_interactive_sources()
|
||||
-> std::io::Result<()> {
|
||||
let temp_dir = TempDir::new()?;
|
||||
let config = build_config(&temp_dir).await?;
|
||||
|
||||
let params = latest_session_lookup_params(
|
||||
/*uses_remote_workspace*/ true, &config, /*cwd_filter*/ None,
|
||||
/*include_non_interactive*/ true,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
params.source_kinds,
|
||||
Some(vec![
|
||||
ThreadSourceKind::Cli,
|
||||
ThreadSourceKind::VsCode,
|
||||
ThreadSourceKind::Exec,
|
||||
ThreadSourceKind::AppServer,
|
||||
])
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn latest_session_lookup_params_keep_explicit_cwd_filter_for_remote_sessions()
|
||||
-> std::io::Result<()> {
|
||||
|
||||
@@ -36,7 +36,6 @@ use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadListCwdFilter;
|
||||
use codex_app_server_protocol::ThreadListParams;
|
||||
use codex_app_server_protocol::ThreadSortKey;
|
||||
use codex_app_server_protocol::ThreadSourceKind;
|
||||
use codex_config::types::SessionPickerViewMode;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_utils_path as path_utils;
|
||||
@@ -1829,8 +1828,7 @@ fn thread_list_params(
|
||||
ProviderFilter::Any => None,
|
||||
ProviderFilter::MatchDefault(default_provider) => Some(vec![default_provider]),
|
||||
},
|
||||
source_kinds: (!include_non_interactive)
|
||||
.then_some(vec![ThreadSourceKind::Cli, ThreadSourceKind::VsCode]),
|
||||
source_kinds: Some(crate::resume_source_kinds(include_non_interactive)),
|
||||
archived: Some(false),
|
||||
cwd: cwd_filter.map(|cwd| ThreadListCwdFilter::One(cwd.to_string_lossy().into_owned())),
|
||||
use_state_db_only: false,
|
||||
@@ -3207,6 +3205,7 @@ fn render_empty_state_line(state: &PickerState) -> Line<'static> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::Duration;
|
||||
use codex_app_server_protocol::ThreadSourceKind;
|
||||
use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_utils_absolute_path::test_support::PathBufExt;
|
||||
@@ -3572,7 +3571,8 @@ mod tests {
|
||||
|
||||
assert_eq!(params.cursor, Some(String::from("cursor-1")));
|
||||
assert_eq!(params.model_providers, None);
|
||||
assert_eq!(params.source_kinds, None);
|
||||
let source_kinds = crate::resume_source_kinds(/*include_non_interactive*/ true);
|
||||
assert_eq!(params.source_kinds, Some(source_kinds));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user