Skip to content

Commit 481db8a

Browse files
authored
feat: adding in agent contribution metric (#2534)
1 parent 2a7559f commit 481db8a

File tree

8 files changed

+394
-43
lines changed

8 files changed

+394
-43
lines changed

crates/chat-cli/src/cli/chat/conversation.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use super::context::{
3030
ContextManager,
3131
calc_max_context_files_size,
3232
};
33+
use super::line_tracker::FileLineTracker;
3334
use super::message::{
3435
AssistantMessage,
3536
ToolUseResult,
@@ -109,6 +110,11 @@ pub struct ConversationState {
109110
/// Model explicitly selected by the user in this conversation state via `/model`.
110111
#[serde(default, skip_serializing_if = "Option::is_none")]
111112
pub model: Option<String>,
113+
/// Used to track agent vs user updates to file modifications.
114+
///
115+
/// Maps from a file path to [FileLineTracker]
116+
#[serde(default)]
117+
pub file_line_tracker: HashMap<String, FileLineTracker>,
112118
}
113119

114120
impl ConversationState {
@@ -150,6 +156,7 @@ impl ConversationState {
150156
latest_summary: None,
151157
agents,
152158
model: current_model_id,
159+
file_line_tracker: HashMap::new(),
153160
}
154161
}
155162

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use serde::{
2+
Deserialize,
3+
Serialize,
4+
};
5+
6+
/// Contains metadata for tracking user and agent contribution metrics for a given file for
7+
/// `fs_write` tool uses.
8+
#[derive(Debug, Clone, Serialize, Deserialize)]
9+
pub struct FileLineTracker {
10+
/// Line count at the end of the last `fs_write`
11+
pub prev_fswrite_lines: usize,
12+
/// Line count before `fs_write` executes
13+
pub before_fswrite_lines: usize,
14+
/// Line count after `fs_write` executes
15+
pub after_fswrite_lines: usize,
16+
/// Whether or not this is the first `fs_write` invocation
17+
pub is_first_write: bool,
18+
}
19+
20+
impl Default for FileLineTracker {
21+
fn default() -> Self {
22+
Self {
23+
prev_fswrite_lines: 0,
24+
before_fswrite_lines: 0,
25+
after_fswrite_lines: 0,
26+
is_first_write: true,
27+
}
28+
}
29+
}
30+
31+
impl FileLineTracker {
32+
pub fn lines_by_user(&self) -> isize {
33+
(self.before_fswrite_lines as isize) - (self.prev_fswrite_lines as isize)
34+
}
35+
36+
pub fn lines_by_agent(&self) -> isize {
37+
(self.after_fswrite_lines as isize) - (self.before_fswrite_lines as isize)
38+
}
39+
}

crates/chat-cli/src/cli/chat/mod.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod input_source;
77
mod message;
88
mod parse;
99
use std::path::MAIN_SEPARATOR;
10+
mod line_tracker;
1011
mod parser;
1112
mod prompt;
1213
mod prompt_parser;
@@ -1897,7 +1898,10 @@ impl ChatSession {
18971898
}
18981899
}
18991900

1900-
let invoke_result = tool.tool.invoke(os, &mut self.stdout).await;
1901+
let invoke_result = tool
1902+
.tool
1903+
.invoke(os, &mut self.stdout, &mut self.conversation.file_line_tracker)
1904+
.await;
19011905

19021906
if self.spinner.is_some() {
19031907
queue!(
@@ -1959,6 +1963,33 @@ impl ChatSession {
19591963
tool_telemetry
19601964
.and_modify(|ev| ev.output_token_size = Some(TokenCounter::count_tokens(&result.as_str())));
19611965
}
1966+
1967+
// Send telemetry for agent contribution
1968+
if let Tool::FsWrite(w) = &tool.tool {
1969+
let sanitized_path_str = w.path(os).to_string_lossy().to_string();
1970+
let conversation_id = self.conversation.conversation_id().to_string();
1971+
let message_id = self.conversation.message_id().map(|s| s.to_string());
1972+
if let Some(tracker) = self.conversation.file_line_tracker.get_mut(&sanitized_path_str) {
1973+
let lines_by_agent = tracker.lines_by_agent();
1974+
let lines_by_user = tracker.lines_by_user();
1975+
1976+
os.telemetry
1977+
.send_agent_contribution_metric(
1978+
&os.database,
1979+
conversation_id,
1980+
message_id,
1981+
Some(tool.id.clone()), // Already a String
1982+
Some(tool.name.clone()), // Already a String
1983+
Some(lines_by_agent),
1984+
Some(lines_by_user),
1985+
)
1986+
.await
1987+
.ok();
1988+
1989+
tracker.prev_fswrite_lines = tracker.after_fswrite_lines;
1990+
}
1991+
}
1992+
19621993
tool_results.push(ToolUseResult {
19631994
tool_use_id: tool.id.clone(),
19641995
content: vec![result.into()],

0 commit comments

Comments
 (0)