file_change_notification.rs

 1use agent_settings::AgentProfileId;
 2use anyhow::Result;
 3use async_trait::async_trait;
 4
 5use crate::example::{Example, ExampleContext, ExampleMetadata, JudgeAssertion};
 6
 7pub struct FileChangeNotificationExample;
 8
 9#[async_trait(?Send)]
10impl Example for FileChangeNotificationExample {
11    fn meta(&self) -> ExampleMetadata {
12        ExampleMetadata {
13            name: "file_change_notification".to_string(),
14            url: "https://github.com/octocat/hello-world".to_string(),
15            revision: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d".to_string(),
16            language_server: None,
17            max_assertions: None,
18            profile_id: AgentProfileId::default(),
19            existing_thread_json: None,
20            max_turns: Some(3),
21        }
22    }
23
24    async fn conversation(&self, cx: &mut ExampleContext) -> Result<()> {
25        // Track README so that the model gets notified of its changes
26        let project_path = cx.agent_thread().read_with(cx, |thread, cx| {
27            thread
28                .project()
29                .read(cx)
30                .find_project_path("README", cx)
31                .expect("README file should exist in this repo")
32        })?;
33
34        let buffer = {
35            cx.agent_thread()
36                .update(cx, |thread, cx| {
37                    thread
38                        .project()
39                        .update(cx, |project, cx| project.open_buffer(project_path, cx))
40                })?
41                .await?
42        };
43
44        cx.agent_thread().update(cx, |thread, cx| {
45            thread.action_log().update(cx, |action_log, cx| {
46                action_log.buffer_read(buffer.clone(), cx);
47            });
48        })?;
49
50        // Start conversation (specific message is not important)
51        cx.push_user_message("Find all files in this repo");
52        cx.run_turn().await?;
53
54        // Edit the README buffer - the model should get a notification on next turn
55        buffer.update(cx, |buffer, cx| {
56            buffer.edit([(0..buffer.len(), "Surprise!")], None, cx);
57        })?;
58
59        // Run for some more turns.
60        // The model shouldn't thank us for letting it know about the file change.
61        cx.run_turns(3).await?;
62
63        Ok(())
64    }
65
66    fn thread_assertions(&self) -> Vec<JudgeAssertion> {
67        vec![JudgeAssertion {
68            id: "change-file-notification".into(),
69            description:
70                "Agent should not acknowledge or mention anything about files that have been changed"
71                    .into(),
72        }]
73    }
74}