Each tool call gets its own block; no more overwriting the previous tool.

45221e515076 · AtlantisPleb · · parent b3173303774a

Each tool call gets its own block; no more overwriting the previous tool.

- `Control::Tool` now always pushes a fresh `Role::Tool` entry instead of
  reusing the last one, so a new `delegate` call (e.g., opencode) cannot
  overwrite an earlier devin block.
- `runtime.rs` no longer sends the speculative pre-run `Control::Tool` header;
  only the actual ACP `tool_call` event creates the one-line header.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

Not deployed through the forge lane

No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.

Changed files

  • modified crates/coder-lite/src/interactive.rs
  • modified crates/coder-lite/src/runtime.rs

Diff

2 files changed, +5 -24

crates/coder-lite/src/interactive.rs modified +5 -18

@@ -83,24 +83,11 @@ pub async fn run_tui() -> Result<(), Box<dyn std::error::Error>> {

83 83
                }
84 84
                Control::Done => ui.loading = false,
85 85
                Control::Tool { agent, title } => {
86
                    if let Some(last) = ui.entries.last_mut() {
87
                        if last.role == Role::Tool {
88
                            last.text = format!("delegate {}: {}", agent, title);
89
                            last.output = Some(String::new());
90
                        } else {
91
                            ui.entries.push(Entry {
92
                                role: Role::Tool,
93
                                text: format!("delegate {}: {}", agent, title),
94
                                output: Some(String::new()),
95
                            });
96
                        }
97
                    } else {
98
                        ui.entries.push(Entry {
99
                            role: Role::Tool,
100
                            text: format!("delegate {}: {}", agent, title),
101
                            output: Some(String::new()),
102
                            });
103
                    }
86
                    ui.entries.push(Entry {
87
                        role: Role::Tool,
88
                        text: format!("delegate {}: {}", agent, title),
89
                        output: Some(String::new()),
90
                    });
104 91
                    ui.scroll_override = None;
105 92
                }
106 93
                Control::ToolText(chunk) => {
crates/coder-lite/src/runtime.rs modified -6

@@ -125,12 +125,6 @@ impl CoderRuntimeSession {

125 125
126 126
            if let Some((call_id, agent_id, task)) = pending_tool.take() {
127 127
                if let Some(agent) = self.agents.iter().find(|a| a.id == agent_id).cloned() {
128
                    let title = task.chars().take(80).collect::<String>();
129
                    let _ = tx.send(Control::Tool {
130
                        agent: agent_id.clone(),
131
                        title: title.clone(),
132
                    });
133
134 128
                    let cwd = env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
135 129
                    let result = {
136 130
                        let tx = tx.clone();

This page updates live while a promote is in flight · changelog