Wait until we have a summary before saving a conversation
Also, avoid collisions by adding a discriminant. Co-Authored-By: Kyle Caverly <kyle@zed.dev>
This commit is contained in:
parent
c416551318
commit
9f783944a7
1 changed files with 33 additions and 59 deletions
|
@ -458,12 +458,6 @@ enum AssistantEvent {
|
||||||
StreamedCompletion,
|
StreamedCompletion,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
struct SavedConversationPath {
|
|
||||||
path: PathBuf,
|
|
||||||
had_summary: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Summary {
|
struct Summary {
|
||||||
text: String,
|
text: String,
|
||||||
|
@ -485,7 +479,7 @@ struct Assistant {
|
||||||
pending_token_count: Task<Option<()>>,
|
pending_token_count: Task<Option<()>>,
|
||||||
api_key: Rc<RefCell<Option<String>>>,
|
api_key: Rc<RefCell<Option<String>>>,
|
||||||
pending_save: Task<Result<()>>,
|
pending_save: Task<Result<()>>,
|
||||||
path: Option<SavedConversationPath>,
|
path: Option<PathBuf>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1062,15 +1056,6 @@ impl Assistant {
|
||||||
if let Some(debounce) = debounce {
|
if let Some(debounce) = debounce {
|
||||||
cx.background().timer(debounce).await;
|
cx.background().timer(debounce).await;
|
||||||
}
|
}
|
||||||
let conversation = SavedConversation {
|
|
||||||
zed: "conversation".into(),
|
|
||||||
version: "0.1".into(),
|
|
||||||
messages: this.read_with(&cx, |this, cx| {
|
|
||||||
this.messages(cx)
|
|
||||||
.map(|message| message.to_open_ai_message(this.buffer.read(cx)))
|
|
||||||
.collect()
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (old_path, summary) = this.read_with(&cx, |this, _| {
|
let (old_path, summary) = this.read_with(&cx, |this, _| {
|
||||||
let path = this.path.clone();
|
let path = this.path.clone();
|
||||||
|
@ -1085,53 +1070,42 @@ impl Assistant {
|
||||||
};
|
};
|
||||||
(path, summary)
|
(path, summary)
|
||||||
});
|
});
|
||||||
let mut new_path = None;
|
|
||||||
if let Some(old_path) = old_path.as_ref() {
|
|
||||||
if old_path.had_summary || summary.is_none() {
|
|
||||||
new_path = Some(old_path.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_path = if let Some(new_path) = new_path {
|
if let Some(summary) = summary {
|
||||||
new_path
|
let conversation = SavedConversation {
|
||||||
} else {
|
zed: "conversation".into(),
|
||||||
let mut path =
|
version: "0.1".into(),
|
||||||
CONVERSATIONS_DIR.join(summary.as_deref().unwrap_or("conversation-1"));
|
messages: this.read_with(&cx, |this, cx| {
|
||||||
|
this.messages(cx)
|
||||||
|
.map(|message| message.to_open_ai_message(this.buffer.read(cx)))
|
||||||
|
.collect()
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
while fs.is_file(&path).await {
|
let path = if let Some(old_path) = old_path {
|
||||||
let file_name = path.file_name().ok_or_else(|| anyhow!("no filename"))?;
|
old_path
|
||||||
let file_name = file_name.to_string_lossy();
|
} else {
|
||||||
|
let mut discriminant = 1;
|
||||||
|
let mut new_path;
|
||||||
|
loop {
|
||||||
|
new_path = CONVERSATIONS_DIR.join(&format!(
|
||||||
|
"{} - {}.zed.json",
|
||||||
|
summary.trim(),
|
||||||
|
discriminant
|
||||||
|
));
|
||||||
|
if fs.is_file(&new_path).await {
|
||||||
|
discriminant += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_path
|
||||||
|
};
|
||||||
|
|
||||||
if let Some((prefix, suffix)) = file_name.rsplit_once('-') {
|
fs.create_dir(CONVERSATIONS_DIR.as_ref()).await?;
|
||||||
let new_version = suffix.parse::<u32>().ok().unwrap_or(1) + 1;
|
fs.atomic_write(path.clone(), serde_json::to_string(&conversation).unwrap())
|
||||||
path.set_file_name(format!("{}-{}", prefix, new_version));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
SavedConversationPath {
|
|
||||||
path,
|
|
||||||
had_summary: summary.is_some(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fs.create_dir(CONVERSATIONS_DIR.as_ref()).await?;
|
|
||||||
fs.atomic_write(
|
|
||||||
new_path.path.clone(),
|
|
||||||
serde_json::to_string(&conversation).unwrap(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
this.update(&mut cx, |this, _| this.path = Some(new_path.clone()));
|
|
||||||
if let Some(old_path) = old_path {
|
|
||||||
if new_path.path != old_path.path {
|
|
||||||
fs.remove_file(
|
|
||||||
&old_path.path,
|
|
||||||
fs::RemoveOptions {
|
|
||||||
recursive: false,
|
|
||||||
ignore_if_not_exists: true,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
}
|
this.update(&mut cx, |this, _| this.path = Some(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue