parent
9db4c8b710
commit
130abc8998
5 changed files with 55 additions and 5 deletions
|
@ -8,6 +8,8 @@ It will be up to you to decide which of these you are doing based on what the us
|
||||||
You should only perform actions that modify the user’s system if explicitly requested by the user:
|
You should only perform actions that modify the user’s system if explicitly requested by the user:
|
||||||
- If the user asks a question about how to accomplish a task, provide guidance or information, and use read-only tools (e.g., search) to assist. You may suggest potential actions, but do not directly modify the user’s system without explicit instruction.
|
- If the user asks a question about how to accomplish a task, provide guidance or information, and use read-only tools (e.g., search) to assist. You may suggest potential actions, but do not directly modify the user’s system without explicit instruction.
|
||||||
- If the user clearly requests that you perform an action, carry out the action directly without explaining why you are doing so.
|
- If the user clearly requests that you perform an action, carry out the action directly without explaining why you are doing so.
|
||||||
|
- The editing actions you perform might produce errors or warnings. At the end of your changes, check whether you introduced any problems, and fix them before providing a summary of the changes you made.
|
||||||
|
- Do not fix errors unrelated to your changes unless the user explicitly asks you to do so.
|
||||||
|
|
||||||
Be concise and direct in your responses.
|
Be concise and direct in your responses.
|
||||||
|
|
||||||
|
|
|
@ -873,17 +873,23 @@ impl Thread {
|
||||||
request.messages.push(context_message);
|
request.messages.push(context_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.attach_stale_files(&mut request.messages, cx);
|
self.attached_tracked_files_state(&mut request.messages, cx);
|
||||||
|
|
||||||
request
|
request
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attach_stale_files(&self, messages: &mut Vec<LanguageModelRequestMessage>, cx: &App) {
|
fn attached_tracked_files_state(
|
||||||
|
&self,
|
||||||
|
messages: &mut Vec<LanguageModelRequestMessage>,
|
||||||
|
cx: &App,
|
||||||
|
) {
|
||||||
const STALE_FILES_HEADER: &str = "These files changed since last read:";
|
const STALE_FILES_HEADER: &str = "These files changed since last read:";
|
||||||
|
|
||||||
let mut stale_message = String::new();
|
let mut stale_message = String::new();
|
||||||
|
|
||||||
for stale_file in self.action_log.read(cx).stale_buffers(cx) {
|
let action_log = self.action_log.read(cx);
|
||||||
|
|
||||||
|
for stale_file in action_log.stale_buffers(cx) {
|
||||||
let Some(file) = stale_file.read(cx).file() else {
|
let Some(file) = stale_file.read(cx).file() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -895,10 +901,22 @@ impl Thread {
|
||||||
writeln!(&mut stale_message, "- {}", file.path().display()).ok();
|
writeln!(&mut stale_message, "- {}", file.path().display()).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut content = Vec::with_capacity(2);
|
||||||
|
|
||||||
if !stale_message.is_empty() {
|
if !stale_message.is_empty() {
|
||||||
|
content.push(stale_message.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if action_log.has_edited_files_since_project_diagnostics_check() {
|
||||||
|
content.push(
|
||||||
|
"When you're done making changes, make sure to check project diagnostics and fix all errors AND warnings you introduced!".into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !content.is_empty() {
|
||||||
let context_message = LanguageModelRequestMessage {
|
let context_message = LanguageModelRequestMessage {
|
||||||
role: Role::User,
|
role: Role::User,
|
||||||
content: vec![stale_message.into()],
|
content,
|
||||||
cache: false,
|
cache: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@ pub struct ActionLog {
|
||||||
stale_buffers_in_context: HashSet<Entity<Buffer>>,
|
stale_buffers_in_context: HashSet<Entity<Buffer>>,
|
||||||
/// Buffers that we want to notify the model about when they change.
|
/// Buffers that we want to notify the model about when they change.
|
||||||
tracked_buffers: HashMap<Entity<Buffer>, TrackedBuffer>,
|
tracked_buffers: HashMap<Entity<Buffer>, TrackedBuffer>,
|
||||||
|
/// Has the model edited a file since it last checked diagnostics?
|
||||||
|
edited_since_project_diagnostics_check: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -93,6 +95,7 @@ impl ActionLog {
|
||||||
Self {
|
Self {
|
||||||
stale_buffers_in_context: HashSet::default(),
|
stale_buffers_in_context: HashSet::default(),
|
||||||
tracked_buffers: HashMap::default(),
|
tracked_buffers: HashMap::default(),
|
||||||
|
edited_since_project_diagnostics_check: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +113,12 @@ impl ActionLog {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stale_buffers_in_context.extend(buffers);
|
self.stale_buffers_in_context.extend(buffers);
|
||||||
|
self.edited_since_project_diagnostics_check = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Notifies a diagnostics check
|
||||||
|
pub fn checked_project_diagnostics(&mut self) {
|
||||||
|
self.edited_since_project_diagnostics_check = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over buffers changed since last read or edited by the model
|
/// Iterate over buffers changed since last read or edited by the model
|
||||||
|
@ -120,6 +129,11 @@ impl ActionLog {
|
||||||
.map(|(buffer, _)| buffer)
|
.map(|(buffer, _)| buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if any files have been edited since the last project diagnostics check
|
||||||
|
pub fn has_edited_files_since_project_diagnostics_check(&self) -> bool {
|
||||||
|
self.edited_since_project_diagnostics_check
|
||||||
|
}
|
||||||
|
|
||||||
/// Takes and returns the set of buffers pending refresh, clearing internal state.
|
/// Takes and returns the set of buffers pending refresh, clearing internal state.
|
||||||
pub fn take_stale_buffers_in_context(&mut self) -> HashSet<Entity<Buffer>> {
|
pub fn take_stale_buffers_in_context(&mut self) -> HashSet<Entity<Buffer>> {
|
||||||
std::mem::take(&mut self.stale_buffers_in_context)
|
std::mem::take(&mut self.stale_buffers_in_context)
|
||||||
|
|
|
@ -25,9 +25,19 @@ pub struct DiagnosticsToolInput {
|
||||||
///
|
///
|
||||||
/// If you wanna access diagnostics for `dolor.txt` in `ipsum`, you should use the path `ipsum/dolor.txt`.
|
/// If you wanna access diagnostics for `dolor.txt` in `ipsum`, you should use the path `ipsum/dolor.txt`.
|
||||||
/// </example>
|
/// </example>
|
||||||
|
#[serde(deserialize_with = "deserialize_path")]
|
||||||
pub path: Option<String>,
|
pub path: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_path<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let opt = Option::<String>::deserialize(deserializer)?;
|
||||||
|
// The model passes an empty string sometimes
|
||||||
|
Ok(opt.filter(|s| !s.is_empty()))
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DiagnosticsTool;
|
pub struct DiagnosticsTool;
|
||||||
|
|
||||||
impl Tool for DiagnosticsTool {
|
impl Tool for DiagnosticsTool {
|
||||||
|
@ -71,7 +81,7 @@ impl Tool for DiagnosticsTool {
|
||||||
input: serde_json::Value,
|
input: serde_json::Value,
|
||||||
_messages: &[LanguageModelRequestMessage],
|
_messages: &[LanguageModelRequestMessage],
|
||||||
project: Entity<Project>,
|
project: Entity<Project>,
|
||||||
_action_log: Entity<ActionLog>,
|
action_log: Entity<ActionLog>,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Task<Result<String>> {
|
) -> Task<Result<String>> {
|
||||||
match serde_json::from_value::<DiagnosticsToolInput>(input)
|
match serde_json::from_value::<DiagnosticsToolInput>(input)
|
||||||
|
@ -140,6 +150,10 @@ impl Tool for DiagnosticsTool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_log.update(cx, |action_log, _cx| {
|
||||||
|
action_log.checked_project_diagnostics();
|
||||||
|
});
|
||||||
|
|
||||||
if has_diagnostics {
|
if has_diagnostics {
|
||||||
Task::ready(Ok(output))
|
Task::ready(Ok(output))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,3 +14,5 @@ To get diagnostics for a specific file:
|
||||||
To get a project-wide diagnostic summary:
|
To get a project-wide diagnostic summary:
|
||||||
{}
|
{}
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
|
IMPORTANT: When you're done making changes, you **MUST** get the **project** diagnostics (input: `{}`) at the end of your edits so you can fix any problems you might have introduced. **DO NOT** tell the user you're done before doing this!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue