chore: fix conflict markers and cargo fmt drift in main (commands, openai_compat, trident, config, tools)

This commit is contained in:
YeonGyu-Kim
2026-05-25 11:51:44 +09:00
parent 499125c9a3
commit 3364dc4bee
8 changed files with 225 additions and 90 deletions

View File

@@ -115,7 +115,10 @@ pub fn compact_session(session: &Session, config: CompactionConfig) -> Compactio
let raw_keep_from = if config.preserve_recent_messages == 0 {
session.messages.len()
} else {
session.messages.len().saturating_sub(config.preserve_recent_messages)
session
.messages
.len()
.saturating_sub(config.preserve_recent_messages)
};
// Ensure we do not split a tool-use / tool-result pair at the compaction
// boundary. If the first preserved message is a user message whose first
@@ -300,7 +303,11 @@ fn merge_compact_summaries(existing_summary: Option<&str>, new_summary: &str) ->
// "- Previously compacted context:" or the nesting compounds with each
// compaction cycle, inflating the summary by ~depth * overhead per turn.
if !previous_highlights.is_empty() {
lines.extend(previous_highlights.into_iter().map(|line| format!("- {line}")));
lines.extend(
previous_highlights
.into_iter()
.map(|line| format!("- {line}")),
);
}
if !new_highlights.is_empty() {

View File

@@ -608,16 +608,28 @@ pub fn save_user_provider_settings(
let mut root = read_settings_root(&settings_path);
let mut provider = serde_json::Map::new();
provider.insert("kind".to_string(), serde_json::Value::String(kind.to_string()));
provider.insert("apiKey".to_string(), serde_json::Value::String(api_key.to_string()));
provider.insert(
"kind".to_string(),
serde_json::Value::String(kind.to_string()),
);
provider.insert(
"apiKey".to_string(),
serde_json::Value::String(api_key.to_string()),
);
if let Some(base_url) = base_url {
provider.insert("baseUrl".to_string(), serde_json::Value::String(base_url.to_string()));
provider.insert(
"baseUrl".to_string(),
serde_json::Value::String(base_url.to_string()),
);
} else {
provider.remove("baseUrl");
}
root.insert("provider".to_string(), serde_json::Value::Object(provider));
if let Some(model) = model {
root.insert("model".to_string(), serde_json::Value::String(model.to_string()));
root.insert(
"model".to_string(),
serde_json::Value::String(model.to_string()),
);
} else {
root.remove("model");
}

View File

@@ -10,7 +10,6 @@ pub mod bash_validation;
mod bootstrap;
pub mod branch_lock;
mod compact;
pub mod trident;
mod config;
pub mod config_validate;
mod conversation;
@@ -40,6 +39,7 @@ mod report_schema;
pub mod sandbox;
mod session;
pub mod session_control;
pub mod trident;
pub use session_control::SessionStore;
mod sse;
pub mod stale_base;

View File

@@ -78,7 +78,10 @@ impl TridentStats {
self.messages_clustered, self.clusters_found
),
format!(" Original: {} messages", self.original_message_count),
format!(" Final: {} messages ({:.1}x compression)", self.final_message_count, compression),
format!(
" Final: {} messages ({:.1}x compression)",
self.final_message_count, compression
),
];
if self.tokens_saved_estimate > 0 {
lines.push(format!(
@@ -121,7 +124,8 @@ pub fn trident_compact_session(
}
if trident_config.collapse_enabled {
let (collapsed, chains, collapsed_count) = stage2_collapse(&messages, trident_config.collapse_threshold);
let (collapsed, chains, collapsed_count) =
stage2_collapse(&messages, trident_config.collapse_threshold);
stats.collapsed_chains = chains;
stats.messages_collapsed = collapsed_count;
messages = collapsed;
@@ -178,10 +182,10 @@ fn stage1_supersede(messages: &[ConversationMessage]) -> (Vec<ConversationMessag
for (i, msg) in messages.iter().enumerate() {
for block in &msg.blocks {
if let Some((path, op_type)) = extract_file_operation(block) {
file_ops.entry(path).or_default().push(FileOperation {
index: i,
op_type,
});
file_ops
.entry(path)
.or_default()
.push(FileOperation { index: i, op_type });
}
}
}
@@ -235,7 +239,9 @@ fn extract_file_operation(block: &ContentBlock) -> Option<(String, FileOp)> {
};
Some((path, op_type))
}
ContentBlock::ToolResult { tool_name, output, .. } => {
ContentBlock::ToolResult {
tool_name, output, ..
} => {
let path = extract_path_from_tool_output(tool_name, output)?;
let op_type = match tool_name.as_str() {
"read_file" | "Read" => FileOp::Read,
@@ -250,8 +256,10 @@ fn extract_file_operation(block: &ContentBlock) -> Option<(String, FileOp)> {
}
fn extract_path_from_tool_input(tool_name: &str, input: &str) -> Option<String> {
if !matches!(tool_name, "read_file" | "write_file" | "edit_file" | "Read" | "Write" | "Edit")
{
if !matches!(
tool_name,
"read_file" | "write_file" | "edit_file" | "Read" | "Write" | "Edit"
) {
return None;
}
serde_json::from_str::<serde_json::Value>(input)
@@ -265,8 +273,10 @@ fn extract_path_from_tool_input(tool_name: &str, input: &str) -> Option<String>
}
fn extract_path_from_tool_output(tool_name: &str, output: &str) -> Option<String> {
if !matches!(tool_name, "read_file" | "write_file" | "edit_file" | "Read" | "Write" | "Edit")
{
if !matches!(
tool_name,
"read_file" | "write_file" | "edit_file" | "Read" | "Write" | "Edit"
) {
return None;
}
serde_json::from_str::<serde_json::Value>(output)
@@ -340,14 +350,24 @@ fn stage2_collapse(
}
fn is_chatty_message(msg: &ConversationMessage) -> bool {
let total_chars: usize = msg.blocks.iter().map(|b| match b {
ContentBlock::Text { text } => text.len(),
ContentBlock::ToolUse { input, .. } => input.len(),
ContentBlock::ToolResult { output, .. } => output.len(),
}).sum();
let total_chars: usize = msg
.blocks
.iter()
.map(|b| match b {
ContentBlock::Text { text } => text.len(),
ContentBlock::ToolUse { input, .. } => input.len(),
ContentBlock::ToolResult { output, .. } => output.len(),
})
.sum();
let has_tool_use = msg.blocks.iter().any(|b| matches!(b, ContentBlock::ToolUse { .. }));
let has_tool_result = msg.blocks.iter().any(|b| matches!(b, ContentBlock::ToolResult { .. }));
let has_tool_use = msg
.blocks
.iter()
.any(|b| matches!(b, ContentBlock::ToolUse { .. }));
let has_tool_result = msg
.blocks
.iter()
.any(|b| matches!(b, ContentBlock::ToolResult { .. }));
if has_tool_use || has_tool_result {
return false;
@@ -463,16 +483,12 @@ fn stage3_cluster(
cluster_buffers.entry(cid).or_default().push(*msg_idx);
}
for (i, msg) in messages.iter().enumerate() {
if let Some(&cid) = cluster_assignments.get(&i) {
if let Some(buffer) = cluster_buffers.get_mut(&cid) {
if buffer[0] == i {
let cluster_messages: Vec<&ConversationMessage> = buffer
.iter()
.filter_map(|&idx| messages.get(idx))
.collect();
let cluster_messages: Vec<&ConversationMessage> =
buffer.iter().filter_map(|&idx| messages.get(idx)).collect();
let summary = generate_cluster_summary(&cluster_messages);
result.push(ConversationMessage {
role: MessageRole::System,
@@ -518,7 +534,9 @@ fn fingerprint_message(index: usize, msg: &ConversationMessage) -> Option<Messag
}
text_length += input.len();
}
ContentBlock::ToolResult { tool_name, output, .. } => {
ContentBlock::ToolResult {
tool_name, output, ..
} => {
tool_names.insert(tool_name.clone());
if let Some(path) = extract_path_from_tool_output(tool_name, output) {
file_paths.insert(path);
@@ -591,7 +609,9 @@ fn generate_cluster_summary(messages: &[&ConversationMessage]) -> String {
file_paths.insert(path);
}
}
ContentBlock::ToolResult { tool_name, output, .. } => {
ContentBlock::ToolResult {
tool_name, output, ..
} => {
tool_names.insert(tool_name.clone());
if let Some(path) = extract_path_from_tool_output(tool_name, output) {
file_paths.insert(path);
@@ -660,13 +680,23 @@ mod tests {
name: "read_file".to_string(),
input: r#"{"path":"src/main.rs"}"#.to_string(),
}]),
ConversationMessage::tool_result("1", "read_file", r#"{"path":"src/main.rs","content":"old"}"#, false),
ConversationMessage::tool_result(
"1",
"read_file",
r#"{"path":"src/main.rs","content":"old"}"#,
false,
),
ConversationMessage::assistant(vec![ContentBlock::ToolUse {
id: "2".to_string(),
name: "edit_file".to_string(),
input: r#"{"path":"src/main.rs","old":"old","new":"new"}"#.to_string(),
}]),
ConversationMessage::tool_result("2", "edit_file", r#"{"path":"src/main.rs","ok":true}"#, false),
ConversationMessage::tool_result(
"2",
"edit_file",
r#"{"path":"src/main.rs","ok":true}"#,
false,
),
];
let (kept, superseded) = stage1_supersede(&messages);
@@ -682,7 +712,12 @@ mod tests {
name: "read_file".to_string(),
input: r#"{"path":"src/main.rs"}"#.to_string(),
}]),
ConversationMessage::tool_result("1", "read_file", r#"{"path":"src/main.rs","content":"data"}"#, false),
ConversationMessage::tool_result(
"1",
"read_file",
r#"{"path":"src/main.rs","content":"data"}"#,
false,
),
];
let (kept, superseded) = stage1_supersede(&messages);
@@ -699,11 +734,13 @@ mod tests {
text: format!("got {i}"),
}]));
}
messages.push(ConversationMessage::assistant(vec![ContentBlock::ToolUse {
id: "t".to_string(),
name: "bash".to_string(),
input: r#"{"command":"ls"}"#.to_string(),
}]));
messages.push(ConversationMessage::assistant(vec![
ContentBlock::ToolUse {
id: "t".to_string(),
name: "bash".to_string(),
input: r#"{"command":"ls"}"#.to_string(),
},
]));
let (result, chains, collapsed) = stage2_collapse(&messages, 4);
assert!(chains > 0, "should collapse at least one chain");
@@ -715,11 +752,13 @@ mod tests {
fn stage3_clusters_similar_messages() {
let mut messages = vec![];
for i in 0..5 {
messages.push(ConversationMessage::assistant(vec![ContentBlock::ToolUse {
id: format!("read_{i}"),
name: "read_file".to_string(),
input: format!(r#"{{"path":"src/{i}.rs"}}"#),
}]));
messages.push(ConversationMessage::assistant(vec![
ContentBlock::ToolUse {
id: format!("read_{i}"),
name: "read_file".to_string(),
input: format!(r#"{{"path":"src/{i}.rs"}}"#),
},
]));
messages.push(ConversationMessage::tool_result(
&format!("read_{i}"),
"read_file",
@@ -728,8 +767,7 @@ mod tests {
));
}
let (result, clusters, clustered) =
stage3_cluster(&messages, 3, 0.4);
let (result, clusters, clustered) = stage3_cluster(&messages, 3, 0.4);
assert!(clusters > 0, "should find at least one cluster");
assert!(clustered > 0);
assert!(result.len() < messages.len());
@@ -745,13 +783,23 @@ mod tests {
name: "read_file".to_string(),
input: r#"{"path":"src/main.rs"}"#.to_string(),
}]),
ConversationMessage::tool_result("1", "read_file", r#"{"path":"src/main.rs","content":"fn main() { buggy }"}"#, false),
ConversationMessage::tool_result(
"1",
"read_file",
r#"{"path":"src/main.rs","content":"fn main() { buggy }"}"#,
false,
),
ConversationMessage::assistant(vec![ContentBlock::ToolUse {
id: "2".to_string(),
name: "edit_file".to_string(),
input: r#"{"path":"src/main.rs","old":"buggy","new":"fixed"}"#.to_string(),
}]),
ConversationMessage::tool_result("2", "edit_file", r#"{"path":"src/main.rs","ok":true}"#, false),
ConversationMessage::tool_result(
"2",
"edit_file",
r#"{"path":"src/main.rs","ok":true}"#,
false,
),
ConversationMessage::assistant(vec![ContentBlock::Text {
text: "Fixed the bug in main.rs".to_string(),
}]),
@@ -767,7 +815,10 @@ mod tests {
&trident_config,
);
assert!(result.removed_message_count > 0 || result.compacted_session.messages.len() < session.messages.len());
assert!(
result.removed_message_count > 0
|| result.compacted_session.messages.len() < session.messages.len()
);
}
#[test]