mirror of
https://github.com/openai/codex.git
synced 2026-11-05 20:10:33 +00:00
preserve thread name state semantics
This commit is contained in:
@@ -377,7 +377,7 @@ ON CONFLICT(child_thread_id) DO NOTHING
|
||||
search_term: None,
|
||||
},
|
||||
);
|
||||
builder.push(" AND COALESCE(NULLIF(threads.name, ''), threads.title) = ");
|
||||
builder.push(" AND COALESCE(threads.name, threads.title) = ");
|
||||
builder.push_bind(title);
|
||||
if let Some(cwd) = cwd {
|
||||
builder.push(" AND threads.cwd = ");
|
||||
@@ -658,11 +658,19 @@ ON CONFLICT(id) DO NOTHING
|
||||
thread_id: ThreadId,
|
||||
name: Option<&str>,
|
||||
) -> anyhow::Result<bool> {
|
||||
let result = sqlx::query("UPDATE threads SET name = ? WHERE id = ?")
|
||||
.bind(name)
|
||||
let result = match name {
|
||||
Some(name) => sqlx::query("UPDATE threads SET name = ? WHERE id = ?")
|
||||
.bind(name)
|
||||
.bind(thread_id.to_string())
|
||||
.execute(self.pool.as_ref())
|
||||
.await?,
|
||||
None => sqlx::query(
|
||||
"UPDATE threads SET title = CASE WHEN name IS NOT NULL AND title = name THEN '' ELSE title END, name = '' WHERE id = ?",
|
||||
)
|
||||
.bind(thread_id.to_string())
|
||||
.execute(self.pool.as_ref())
|
||||
.await?;
|
||||
.await?,
|
||||
};
|
||||
Ok(result.rows_affected() > 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -176,15 +176,21 @@ pub(super) fn permission_profile_to_metadata_value(
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn thread_metadata_name(metadata: &ThreadMetadata) -> Option<String> {
|
||||
let explicit_name = metadata
|
||||
.name
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|name| !name.is_empty())
|
||||
.map(str::to_string);
|
||||
if explicit_name.is_some() {
|
||||
return explicit_name;
|
||||
#[derive(Clone)]
|
||||
pub(super) enum ThreadMetadataName {
|
||||
Explicit(String),
|
||||
Legacy(String),
|
||||
Cleared,
|
||||
}
|
||||
|
||||
pub(super) fn thread_metadata_name(metadata: &ThreadMetadata) -> Option<ThreadMetadataName> {
|
||||
if let Some(name) = metadata.name.as_deref() {
|
||||
let name = name.trim();
|
||||
return Some(if name.is_empty() {
|
||||
ThreadMetadataName::Cleared
|
||||
} else {
|
||||
ThreadMetadataName::Explicit(name.to_string())
|
||||
});
|
||||
}
|
||||
|
||||
// Preserve display names from rows written before explicit names had their own column.
|
||||
@@ -194,7 +200,15 @@ pub(super) fn thread_metadata_name(metadata: &ThreadMetadata) -> Option<String>
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(legacy_title.to_string())
|
||||
Some(ThreadMetadataName::Legacy(legacy_title.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn apply_thread_metadata_name(thread: &mut StoredThread, name: ThreadMetadataName) {
|
||||
match name {
|
||||
ThreadMetadataName::Explicit(name) => thread.name = Some(name),
|
||||
ThreadMetadataName::Legacy(name) => set_thread_name_from_title(thread, name),
|
||||
ThreadMetadataName::Cleared => thread.name = None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ use codex_rollout::find_thread_names_by_ids;
|
||||
use codex_rollout::parse_cursor;
|
||||
|
||||
use super::LocalThreadStore;
|
||||
use super::helpers::set_thread_name_from_title;
|
||||
use super::helpers::ThreadMetadataName;
|
||||
use super::helpers::apply_thread_metadata_name;
|
||||
use super::helpers::stored_thread_from_rollout_item;
|
||||
use super::helpers::thread_metadata_name;
|
||||
use crate::ListThreadsParams;
|
||||
@@ -80,14 +81,14 @@ pub(super) async fn list_threads(
|
||||
.iter()
|
||||
.map(|thread| thread.thread_id)
|
||||
.collect::<HashSet<_>>();
|
||||
let mut names = HashMap::<ThreadId, String>::with_capacity(thread_ids.len());
|
||||
let mut names = HashMap::<ThreadId, ThreadMetadataName>::with_capacity(thread_ids.len());
|
||||
if let Some(state_db_ctx) = store.state_db().await {
|
||||
for &thread_id in &thread_ids {
|
||||
let Ok(Some(metadata)) = state_db_ctx.get_thread(thread_id).await else {
|
||||
continue;
|
||||
};
|
||||
if let Some(title) = thread_metadata_name(&metadata) {
|
||||
names.insert(thread_id, title);
|
||||
if let Some(name) = thread_metadata_name(&metadata) {
|
||||
names.insert(thread_id, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,12 +97,14 @@ pub(super) async fn list_threads(
|
||||
find_thread_names_by_ids(store.config.codex_home.as_path(), &thread_ids).await
|
||||
{
|
||||
for (thread_id, title) in legacy_names {
|
||||
names.entry(thread_id).or_insert(title);
|
||||
names
|
||||
.entry(thread_id)
|
||||
.or_insert(ThreadMetadataName::Legacy(title));
|
||||
}
|
||||
}
|
||||
for thread in &mut items {
|
||||
if let Some(title) = names.get(&thread.thread_id).cloned() {
|
||||
set_thread_name_from_title(thread, title);
|
||||
if let Some(name) = names.get(&thread.thread_id).cloned() {
|
||||
apply_thread_metadata_name(thread, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ use codex_rollout::read_thread_item_from_rollout;
|
||||
use codex_state::ThreadMetadata;
|
||||
|
||||
use super::LocalThreadStore;
|
||||
use super::helpers::ThreadMetadataName;
|
||||
use super::helpers::apply_thread_metadata_name;
|
||||
use super::helpers::git_info_from_parts;
|
||||
use super::helpers::permission_profile_from_metadata_value;
|
||||
use super::helpers::rollout_path_is_archived;
|
||||
@@ -118,7 +120,7 @@ pub(super) async fn read_thread_by_rollout_path(
|
||||
if let Some(metadata) = read_sqlite_metadata(store, thread.thread_id).await {
|
||||
thread.recency_at = metadata.recency_at;
|
||||
if let Some(name) = thread_metadata_name(&metadata) {
|
||||
set_thread_name_from_title(&mut thread, name);
|
||||
apply_thread_metadata_name(&mut thread, name);
|
||||
}
|
||||
let existing_git_info = thread.git_info.take();
|
||||
let (fallback_sha, fallback_branch, fallback_origin_url) = match existing_git_info {
|
||||
@@ -307,7 +309,8 @@ async fn stored_thread_from_sqlite_metadata(
|
||||
metadata: ThreadMetadata,
|
||||
) -> StoredThread {
|
||||
let name = match thread_metadata_name(&metadata) {
|
||||
Some(title) => Some(title),
|
||||
Some(ThreadMetadataName::Explicit(name) | ThreadMetadataName::Legacy(name)) => Some(name),
|
||||
Some(ThreadMetadataName::Cleared) => None,
|
||||
None => find_thread_name_by_id(store.config.codex_home.as_path(), &metadata.id)
|
||||
.await
|
||||
.ok()
|
||||
|
||||
@@ -10,7 +10,8 @@ use codex_rollout::parse_cursor;
|
||||
use codex_rollout::search_rollout_matches;
|
||||
|
||||
use super::LocalThreadStore;
|
||||
use super::helpers::set_thread_name_from_title;
|
||||
use super::helpers::ThreadMetadataName;
|
||||
use super::helpers::apply_thread_metadata_name;
|
||||
use super::helpers::stored_thread_from_rollout_item;
|
||||
use super::helpers::thread_metadata_name;
|
||||
use super::list_threads::list_rollout_threads;
|
||||
@@ -205,14 +206,14 @@ async fn set_thread_search_result_names(
|
||||
.iter()
|
||||
.map(|item| item.thread.thread_id)
|
||||
.collect::<HashSet<_>>();
|
||||
let mut names = HashMap::<ThreadId, String>::with_capacity(thread_ids.len());
|
||||
let mut names = HashMap::<ThreadId, ThreadMetadataName>::with_capacity(thread_ids.len());
|
||||
if let Some(state_db_ctx) = store.state_db().await {
|
||||
for &thread_id in &thread_ids {
|
||||
let Ok(Some(metadata)) = state_db_ctx.get_thread(thread_id).await else {
|
||||
continue;
|
||||
};
|
||||
if let Some(title) = thread_metadata_name(&metadata) {
|
||||
names.insert(thread_id, title);
|
||||
if let Some(name) = thread_metadata_name(&metadata) {
|
||||
names.insert(thread_id, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,12 +222,14 @@ async fn set_thread_search_result_names(
|
||||
find_thread_names_by_ids(store.config.codex_home.as_path(), &thread_ids).await
|
||||
{
|
||||
for (thread_id, title) in legacy_names {
|
||||
names.entry(thread_id).or_insert(title);
|
||||
names
|
||||
.entry(thread_id)
|
||||
.or_insert(ThreadMetadataName::Legacy(title));
|
||||
}
|
||||
}
|
||||
for item in items {
|
||||
if let Some(title) = names.get(&item.thread.thread_id).cloned() {
|
||||
set_thread_name_from_title(&mut item.thread, title);
|
||||
if let Some(name) = names.get(&item.thread.thread_id).cloned() {
|
||||
apply_thread_metadata_name(&mut item.thread, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user