Skip to content

Commit 54e0158

Browse files
committed
style: cargo fmt after upstream merge
1 parent 681738d commit 54e0158

54 files changed

Lines changed: 841 additions & 321 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

crates/jcode-app-core/src/agent.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod compaction;
44
mod environment;
55
mod interrupts;
66
mod messages;
7+
mod orchestrator;
78
mod prompting;
89
mod provider;
910
mod response_recovery;
@@ -13,7 +14,6 @@ mod tools;
1314
mod turn_execution;
1415
mod turn_loops;
1516
mod turn_streaming_mpsc;
16-
mod orchestrator;
1717
mod utils;
1818

1919
use self::streaming::{send_stream_keepalive_mpsc, stream_keepalive_ticker};

crates/jcode-app-core/src/agent/compaction.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ impl Agent {
3838
.iter()
3939
.map(message_to_json_value)
4040
.collect();
41-
if let Err(e) = restore_todos_after_compaction(
42-
&self.session.id,
43-
&messages_json,
44-
) {
41+
if let Err(e) = restore_todos_after_compaction(&self.session.id, &messages_json) {
4542
crate::logging::warn(&format!(
4643
"failed to restore todos after compaction for session={}: {e}",
4744
self.session.id,

crates/jcode-app-core/src/agent/orchestrator.rs

Lines changed: 155 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
99
use super::*;
1010
use anyhow::Result;
11+
use futures::future::try_join_all;
1112
use jcode_task_types::TodoItem;
1213
use std::collections::HashSet;
13-
use futures::future::try_join_all;
1414

1515
const MAX_RETRIES: u32 = 2;
1616

@@ -31,41 +31,76 @@ pub(super) struct PipelineResult {
3131
pub(super) fn classify_todo(todo: &TodoItem) -> String {
3232
let c = todo.content.to_ascii_lowercase();
3333
let g = todo.group.as_deref().unwrap_or("").to_ascii_lowercase();
34-
if g.contains("plan")||g.contains("foundation") { return "planner".into(); }
35-
if g.contains("test")||g.contains("verify")||g.contains("qa") { return "basher".into(); }
36-
if g.contains("review") { return "code-reviewer".into(); }
37-
if g.contains("search")||g.contains("find") { return "file-picker".into(); }
38-
if c.contains("plan")||c.contains("analyz")||c.contains("design") { return "planner".into(); }
39-
if c.contains("test")||c.contains("verif")||c.contains("check") { return "basher".into(); }
40-
if c.contains("review")||c.contains("audit") { return "code-reviewer".into(); }
41-
if c.contains("search")||c.contains("find")||c.starts_with("read") { return "file-picker".into(); }
34+
if g.contains("plan") || g.contains("foundation") {
35+
return "planner".into();
36+
}
37+
if g.contains("test") || g.contains("verify") || g.contains("qa") {
38+
return "basher".into();
39+
}
40+
if g.contains("review") {
41+
return "code-reviewer".into();
42+
}
43+
if g.contains("search") || g.contains("find") {
44+
return "file-picker".into();
45+
}
46+
if c.contains("plan") || c.contains("analyz") || c.contains("design") {
47+
return "planner".into();
48+
}
49+
if c.contains("test") || c.contains("verif") || c.contains("check") {
50+
return "basher".into();
51+
}
52+
if c.contains("review") || c.contains("audit") {
53+
return "code-reviewer".into();
54+
}
55+
if c.contains("search") || c.contains("find") || c.starts_with("read") {
56+
return "file-picker".into();
57+
}
4258
"editor".into()
4359
}
4460

4561
/// Build allowed-tool set matching each agent type.
4662
pub(crate) fn build_allowed_tools(tp: &str) -> HashSet<String> {
4763
let tools: Vec<&str> = match tp {
48-
"planner" => vec!["read","glob","grep","codesearch","session_search","ls"],
49-
"file-picker" => vec!["ls","glob","read"],
50-
"editor" => vec!["read","write","edit","hashline_edit","propose_edit","glob","grep","codesearch","ls","bash"],
51-
"code-reviewer" => vec!["read","glob","grep","codesearch","ls"],
52-
"basher" => vec!["bash","read","glob","ls"],
53-
_ => vec!["read","bash"],
64+
"planner" => vec!["read", "glob", "grep", "codesearch", "session_search", "ls"],
65+
"file-picker" => vec!["ls", "glob", "read"],
66+
"editor" => vec![
67+
"read",
68+
"write",
69+
"edit",
70+
"hashline_edit",
71+
"propose_edit",
72+
"glob",
73+
"grep",
74+
"codesearch",
75+
"ls",
76+
"bash",
77+
],
78+
"code-reviewer" => vec!["read", "glob", "grep", "codesearch", "ls"],
79+
"basher" => vec!["bash", "read", "glob", "ls"],
80+
_ => vec!["read", "bash"],
5481
};
5582
tools.into_iter().map(String::from).collect()
5683
}
5784

5885
impl Agent {
59-
pub fn set_todo_orchestrator_enabled(&mut self, v: bool) { self.todo_orchestrator_enabled = v; }
60-
pub fn todo_orchestrator_enabled(&self) -> bool { self.todo_orchestrator_enabled }
86+
pub fn set_todo_orchestrator_enabled(&mut self, v: bool) {
87+
self.todo_orchestrator_enabled = v;
88+
}
89+
pub fn todo_orchestrator_enabled(&self) -> bool {
90+
self.todo_orchestrator_enabled
91+
}
6192

6293
/// Run the full Codebuff pipeline for all incomplete todos.
6394
pub async fn poll_todo_pipeline(&mut self) -> Result<usize> {
6495
let sid = self.session.id.clone();
6596
let todos = crate::todo::load_todos(&sid).unwrap_or_default();
66-
let incomplete: Vec<TodoItem> = todos.into_iter()
67-
.filter(|t| !matches!(t.status.as_str(), "completed"|"cancelled")).collect();
68-
if incomplete.is_empty() { return Ok(0); }
97+
let incomplete: Vec<TodoItem> = todos
98+
.into_iter()
99+
.filter(|t| !matches!(t.status.as_str(), "completed" | "cancelled"))
100+
.collect();
101+
if incomplete.is_empty() {
102+
return Ok(0);
103+
}
69104

70105
let provider = Arc::clone(&self.provider);
71106
let registry = self.registry.clone();
@@ -76,15 +111,22 @@ impl Agent {
76111
let result = orchestrate_one_todo(&provider, &registry, &parent_sid, todo).await;
77112
match result {
78113
Ok(r) => {
79-
if r.all_tests_pass { processed += 1; }
114+
if r.all_tests_pass {
115+
processed += 1;
116+
}
80117
crate::logging::info(&format!(
81-
"[orchestrator] '{}': {} subtasks, pass={}", todo.content, r.subtask_count, r.all_tests_pass,
118+
"[orchestrator] '{}': {} subtasks, pass={}",
119+
todo.content, r.subtask_count, r.all_tests_pass,
82120
));
83121
}
84-
Err(e) => crate::logging::warn(&format!("[orchestrator] '{}' failed: {e}", todo.content)),
122+
Err(e) => {
123+
crate::logging::warn(&format!("[orchestrator] '{}' failed: {e}", todo.content))
124+
}
85125
}
86126
}
87-
if processed > 0 { crate::logging::info(&format!("[orchestrator] processed {processed} todos")); }
127+
if processed > 0 {
128+
crate::logging::info(&format!("[orchestrator] processed {processed} todos"));
129+
}
88130
Ok(processed)
89131
}
90132
}
@@ -103,7 +145,8 @@ async fn orchestrate_one_todo(
103145
let plan_prompt = format!(
104146
"Break this task into 2-4 subtasks. Return ONLY a JSON array of \
105147
objects with keys: description, prompt, subagent_type. \
106-
No extra text.\n\nTask:\n{}", todo.content,
148+
No extra text.\n\nTask:\n{}",
149+
todo.content,
107150
);
108151
let plan_text = spawn_child(provider, registry, parent_sid, "planner", &plan_prompt).await?;
109152
let mut subtasks = parse_swarm_tasks(&plan_text);
@@ -119,18 +162,24 @@ async fn orchestrate_one_todo(
119162
let mut all_pass = false;
120163
while attempts < MAX_RETRIES && !all_pass {
121164
// 2. Run subtasks in PARALLEL (try_join_all)
122-
let futures: Vec<_> = subtasks.iter().map(|st| {
123-
let p = Arc::clone(provider);
124-
let r = registry.clone();
125-
let sid = parent_sid.to_string();
126-
let prompt = st.prompt.clone();
127-
let atype = st.subagent_type.clone();
128-
async move { spawn_child(&p, &r, &sid, &atype, &prompt).await }
129-
}).collect();
165+
let futures: Vec<_> = subtasks
166+
.iter()
167+
.map(|st| {
168+
let p = Arc::clone(provider);
169+
let r = registry.clone();
170+
let sid = parent_sid.to_string();
171+
let prompt = st.prompt.clone();
172+
let atype = st.subagent_type.clone();
173+
async move { spawn_child(&p, &r, &sid, &atype, &prompt).await }
174+
})
175+
.collect();
130176
let outputs = try_join_all(futures).await?;
131177

132178
// 3. Basher child → run tests
133-
let test_prompt = format!("Run relevant tests for this task AND REPORT pass/fail:\n\n{}", todo.content);
179+
let test_prompt = format!(
180+
"Run relevant tests for this task AND REPORT pass/fail:\n\n{}",
181+
todo.content
182+
);
134183
let test_out = spawn_child(provider, registry, parent_sid, "basher", &test_prompt).await?;
135184
all_pass = !test_out.to_ascii_lowercase().contains("fail");
136185
attempts += 1;
@@ -141,21 +190,35 @@ async fn orchestrate_one_todo(
141190
"Integrate the completed subtask results and produce a final summary.\n\nTask:\n{}",
142191
todo.content,
143192
);
144-
let _final_out = spawn_child(provider, registry, parent_sid, "editor", &integration_prompt).await?;
193+
let _final_out = spawn_child(
194+
provider,
195+
registry,
196+
parent_sid,
197+
"editor",
198+
&integration_prompt,
199+
)
200+
.await?;
145201

146202
// 5. Persist and broadcast: load ALL todos, update the one just processed.
147203
// save_todos replaces the full list (whole-list replace pattern).
148204
let mut all_todos = crate::todo::load_todos(parent_sid).unwrap_or_default();
149205
for t in &mut all_todos {
150206
if t.content == todo.content && t.id == todo.id {
151-
t.status = if all_pass { "completed".into() } else { "blocked".into() };
207+
t.status = if all_pass {
208+
"completed".into()
209+
} else {
210+
"blocked".into()
211+
};
152212
break;
153213
}
154214
}
155215
crate::todo::save_todos(parent_sid, &all_todos)?;
156216
// save_todos internally broadcasts BusEvent::TodoUpdated.
157217

158-
Ok(PipelineResult { all_tests_pass: all_pass, subtask_count: subtasks.len() })
218+
Ok(PipelineResult {
219+
all_tests_pass: all_pass,
220+
subtask_count: subtasks.len(),
221+
})
159222
}
160223

161224
/// Spawn a single child agent with given type and prompt.
@@ -203,28 +266,70 @@ fn parse_swarm_tasks(text: &str) -> Vec<SwarmTaskSpec> {
203266
fn parse_one_task(v: serde_json::Value) -> Option<SwarmTaskSpec> {
204267
let desc = v.get("description")?.as_str()?.to_string();
205268
let prompt = v.get("prompt")?.as_str()?.to_string();
206-
let subagent_type = v.get("subagent_type").and_then(|s| s.as_str())
207-
.unwrap_or("editor").to_string();
208-
Some(SwarmTaskSpec { description: desc, prompt, subagent_type })
269+
let subagent_type = v
270+
.get("subagent_type")
271+
.and_then(|s| s.as_str())
272+
.unwrap_or("editor")
273+
.to_string();
274+
Some(SwarmTaskSpec {
275+
description: desc,
276+
prompt,
277+
subagent_type,
278+
})
209279
}
210280

211281
#[cfg(test)]
212282
mod tests {
213283
use super::*;
214-
fn td(c: &str, g: Option<&str>) -> TodoItem { TodoItem { content: c.into(), group: g.map(String::from), ..Default::default() } }
215-
fn check(c: &str, g: Option<&str>, e: &str) { assert_eq!(classify_todo(&td(c, g)), e, "mismatch for {c:?} group={g:?}"); }
216-
#[test] fn t_pl() { check("Design auth", None, "planner"); }
217-
#[test] fn t_ed() { check("Implement btn", None, "editor"); }
218-
#[test] fn t_ba() { check("Fix test", Some("qa"), "basher"); }
219-
#[test] fn t_rv() { check("Review PR", None, "code-reviewer"); }
220-
#[test] fn t_fp() { check("Find files", Some("search"), "file-picker"); }
221-
#[test] fn t_tools() { let t = build_allowed_tools("planner"); assert!(t.contains("read")); assert!(!t.contains("write")); }
284+
fn td(c: &str, g: Option<&str>) -> TodoItem {
285+
TodoItem {
286+
content: c.into(),
287+
group: g.map(String::from),
288+
..Default::default()
289+
}
290+
}
291+
fn check(c: &str, g: Option<&str>, e: &str) {
292+
assert_eq!(
293+
classify_todo(&td(c, g)),
294+
e,
295+
"mismatch for {c:?} group={g:?}"
296+
);
297+
}
298+
#[test]
299+
fn t_pl() {
300+
check("Design auth", None, "planner");
301+
}
302+
#[test]
303+
fn t_ed() {
304+
check("Implement btn", None, "editor");
305+
}
306+
#[test]
307+
fn t_ba() {
308+
check("Fix test", Some("qa"), "basher");
309+
}
310+
#[test]
311+
fn t_rv() {
312+
check("Review PR", None, "code-reviewer");
313+
}
314+
#[test]
315+
fn t_fp() {
316+
check("Find files", Some("search"), "file-picker");
317+
}
318+
#[test]
319+
fn t_tools() {
320+
let t = build_allowed_tools("planner");
321+
assert!(t.contains("read"));
322+
assert!(!t.contains("write"));
323+
}
222324

223-
fn parse(s: &str) -> Vec<SwarmTaskSpec> { parse_swarm_tasks(s) }
325+
fn parse(s: &str) -> Vec<SwarmTaskSpec> {
326+
parse_swarm_tasks(s)
327+
}
224328

225329
#[test]
226330
fn parse_json_array() {
227-
let json = r#"[{"description":"Fix auth","prompt":"Update login.ts","subagent_type":"editor"}]"#;
331+
let json =
332+
r#"[{"description":"Fix auth","prompt":"Update login.ts","subagent_type":"editor"}]"#;
228333
assert_eq!(parse(json).len(), 1);
229334
}
230335

crates/jcode-app-core/src/agent/turn_streaming_mpsc.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -923,10 +923,11 @@ impl Agent {
923923
model_at_request_start, model_after_stream
924924
));
925925
self.session.model = Some(model_after_stream.clone());
926-
self.provider_runtime_state
927-
.apply(crate::provider::ProviderStateEvent::RuntimeModelObserved {
926+
self.provider_runtime_state.apply(
927+
crate::provider::ProviderStateEvent::RuntimeModelObserved {
928928
model: model_after_stream.clone(),
929-
});
929+
},
930+
);
930931
self.persist_session_best_effort("model fallback");
931932
let _ = event_tx.send(ServerEvent::ModelChanged {
932933
id: 0,

crates/jcode-app-core/src/agent_tests.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ async fn run_turn_streaming_mpsc_emits_model_changed_on_midstream_switch() {
311311
);
312312
}
313313

314-
315314
#[tokio::test]
316315
async fn messages_for_provider_replays_persisted_native_compaction_in_auto_mode() {
317316
let provider: Arc<dyn Provider> = Arc::new(NativeAutoCompactionProvider);

crates/jcode-app-core/src/catchup.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,9 @@ fn tool_use_step(block: &ContentBlock) -> Option<String> {
421421
};
422422
let obj = input.as_object();
423423
match name.as_str() {
424-
"grep" | "ffs grep" | "glob" | "ffs glob" | "ls" | "codesearch"
425-
| "session_search" | "ffs outline" | "ffs symbol" | "ffs find" | "ffs dispatch"
426-
| "ffs callers" | "ffs callees" | "ffs refs" | "ffs flow" => {
424+
"grep" | "ffs grep" | "glob" | "ffs glob" | "ls" | "codesearch" | "session_search"
425+
| "ffs outline" | "ffs symbol" | "ffs find" | "ffs dispatch" | "ffs callers"
426+
| "ffs callees" | "ffs refs" | "ffs flow" => {
427427
Some("Searched code and session context".to_string())
428428
}
429429
"read" => Some(

crates/jcode-app-core/src/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
mod await_members_state;
22
mod background_tasks;
33
mod client_actions;
4-
pub(crate) mod compaction_hooks;
54
mod client_api;
65
mod client_comm;
76
mod client_comm_channels;
@@ -19,6 +18,7 @@ mod comm_control;
1918
mod comm_plan;
2019
mod comm_session;
2120
mod comm_sync;
21+
pub(crate) mod compaction_hooks;
2222
mod debug;
2323
mod debug_ambient;
2424
mod debug_command_exec;

crates/jcode-app-core/src/startup_profile.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,7 @@ pub fn init_workflow_spawn() {
8888
jcode_keywords::workflow::spawn::set_spawn_impl(Box::new(|spec| {
8989
jcode_keywords::workflow::SpawnResult {
9090
description: spec.description.clone(),
91-
output: format!(
92-
"[spawned: {}]",
93-
spec.description
94-
),
91+
output: format!("[spawned: {}]", spec.description),
9592
success: true,
9693
}
9794
}));

0 commit comments

Comments
 (0)