actually record coach feedback and use it
This commit is contained in:
@@ -163,15 +163,33 @@ fn extract_coach_feedback_from_logs(
|
|||||||
if let Some(context_window) = log_json.get("context_window") {
|
if let Some(context_window) = log_json.get("context_window") {
|
||||||
if let Some(conversation_history) = context_window.get("conversation_history") {
|
if let Some(conversation_history) = context_window.get("conversation_history") {
|
||||||
if let Some(messages) = conversation_history.as_array() {
|
if let Some(messages) = conversation_history.as_array() {
|
||||||
// Simply get the last message content - this is the coach's final feedback
|
// Get the last message which contains the final_output tool result
|
||||||
|
// The last message is a USER message with format "Tool result: {summary}"
|
||||||
if let Some(last_message) = messages.last() {
|
if let Some(last_message) = messages.last() {
|
||||||
if let Some(content) = last_message.get("content") {
|
if let Some(content) = last_message.get("content") {
|
||||||
if let Some(content_str) = content.as_str() {
|
if let Some(content_str) = content.as_str() {
|
||||||
|
// Strip the "Tool result: " prefix if present
|
||||||
|
let feedback = if content_str.starts_with("Tool result: ") {
|
||||||
|
content_str.strip_prefix("Tool result: ")
|
||||||
|
.unwrap_or(content_str)
|
||||||
|
.to_string()
|
||||||
|
} else {
|
||||||
|
content_str.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log the extraction for debugging
|
||||||
|
output.print(&format!(
|
||||||
|
"Coach feedback extracted: {} characters (from {} total)",
|
||||||
|
feedback.len(),
|
||||||
|
content_str.len()
|
||||||
|
));
|
||||||
|
output.print(&format!("Coach feedback:\n{}", feedback));
|
||||||
|
|
||||||
output.print(&format!(
|
output.print(&format!(
|
||||||
"✅ Extracted coach feedback from session: {}",
|
"✅ Extracted coach feedback from session: {}",
|
||||||
session_id
|
session_id
|
||||||
));
|
));
|
||||||
return Ok(content_str.to_string());
|
return Ok(feedback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3604,40 +3604,6 @@ impl<W: UiWriter> Agent<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this was a final_output tool call
|
|
||||||
if tool_call.tool == "final_output" {
|
|
||||||
// The summary was already displayed via print_final_output
|
|
||||||
// Don't add it to full_response to avoid duplicate printing
|
|
||||||
// full_response is intentionally left empty/unchanged
|
|
||||||
self.ui_writer.println("");
|
|
||||||
let _ttft =
|
|
||||||
first_token_time.unwrap_or_else(|| stream_start.elapsed());
|
|
||||||
|
|
||||||
// Add timing if needed
|
|
||||||
let final_response = if show_timing {
|
|
||||||
format!(
|
|
||||||
"🕝 {} | 💭 {}",
|
|
||||||
Self::format_duration(stream_start.elapsed()),
|
|
||||||
Self::format_duration(_ttft)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Return empty string since content was already displayed
|
|
||||||
String::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(TaskResult::new(
|
|
||||||
final_response,
|
|
||||||
self.context_window.clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closure marker with timing
|
|
||||||
if tool_call.tool != "final_output" {
|
|
||||||
self.ui_writer
|
|
||||||
.print_tool_timing(&Self::format_duration(exec_duration));
|
|
||||||
self.ui_writer.print_agent_prompt();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the tool call and result to the context window using RAW unfiltered content
|
// Add the tool call and result to the context window using RAW unfiltered content
|
||||||
// This ensures the log file contains the true raw content including JSON tool calls
|
// This ensures the log file contains the true raw content including JSON tool calls
|
||||||
let tool_message = if !raw_content_for_log.trim().is_empty() {
|
let tool_message = if !raw_content_for_log.trim().is_empty() {
|
||||||
@@ -3701,6 +3667,43 @@ impl<W: UiWriter> Agent<W> {
|
|||||||
self.context_window.add_message(tool_message);
|
self.context_window.add_message(tool_message);
|
||||||
self.context_window.add_message(result_message);
|
self.context_window.add_message(result_message);
|
||||||
|
|
||||||
|
// Check if this was a final_output tool call
|
||||||
|
if tool_call.tool == "final_output" {
|
||||||
|
// Save context window BEFORE returning so the session log includes final_output
|
||||||
|
self.save_context_window("completed");
|
||||||
|
|
||||||
|
// The summary was already displayed via print_final_output
|
||||||
|
// Don't add it to full_response to avoid duplicate printing
|
||||||
|
// full_response is intentionally left empty/unchanged
|
||||||
|
self.ui_writer.println("");
|
||||||
|
let _ttft =
|
||||||
|
first_token_time.unwrap_or_else(|| stream_start.elapsed());
|
||||||
|
|
||||||
|
// Add timing if needed
|
||||||
|
let final_response = if show_timing {
|
||||||
|
format!(
|
||||||
|
"🕝 {} | 💭 {}",
|
||||||
|
Self::format_duration(stream_start.elapsed()),
|
||||||
|
Self::format_duration(_ttft)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Return empty string since content was already displayed
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(TaskResult::new(
|
||||||
|
final_response,
|
||||||
|
self.context_window.clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Closure marker with timing
|
||||||
|
if tool_call.tool != "final_output" {
|
||||||
|
self.ui_writer
|
||||||
|
.print_tool_timing(&Self::format_duration(exec_duration));
|
||||||
|
self.ui_writer.print_agent_prompt();
|
||||||
|
}
|
||||||
|
|
||||||
// Update the request with the new context for next iteration
|
// Update the request with the new context for next iteration
|
||||||
request.messages = self.context_window.conversation_history.clone();
|
request.messages = self.context_window.conversation_history.clone();
|
||||||
|
|
||||||
@@ -3922,6 +3925,9 @@ impl<W: UiWriter> Agent<W> {
|
|||||||
full_response = String::new();
|
full_response = String::new();
|
||||||
|
|
||||||
self.ui_writer.println("");
|
self.ui_writer.println("");
|
||||||
|
|
||||||
|
// Save context window BEFORE returning
|
||||||
|
self.save_context_window("completed");
|
||||||
let _ttft =
|
let _ttft =
|
||||||
first_token_time.unwrap_or_else(|| stream_start.elapsed());
|
first_token_time.unwrap_or_else(|| stream_start.elapsed());
|
||||||
|
|
||||||
@@ -4060,6 +4066,9 @@ impl<W: UiWriter> Agent<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save context window BEFORE returning
|
||||||
|
self.save_context_window("completed");
|
||||||
|
|
||||||
// Add timing if needed
|
// Add timing if needed
|
||||||
let final_response = if show_timing {
|
let final_response = if show_timing {
|
||||||
format!(
|
format!(
|
||||||
|
|||||||
Reference in New Issue
Block a user