Skip to content

Commit 47f9b9c

Browse files
author
Yogthos
committed
feat: wire mid-turn steering for interjections
Replace the legacy stop-and-respawn interjection model with mid-run steering injection. User messages typed during an agent run are now injected at turn boundaries as LoopMessage::User wrapped with MID_TURN_STEER_WRAPPER, letting the model treat them as guidance within the same run instead of spawning a new run. Changes: - provider: spawn_runner gains steering_queue parameter, wires it into LoopSpawnConfig (replaces dead 'stays None' comment) - ui: interjection_queue converted from VecDeque to Arc<Mutex<VecDeque<String>>>, shared with spawn_runner at all call sites - ui: removed interject signal send from mid-run push path — steering handles injection without stopping the run - ui: updated comments and status messages to reflect 'inject at turn boundary' behavior - acp: passes None (no UI, no steering needed) Infrastructure built in prior commits (steering.rs factory, loop polling at run.rs:238/588, LoopSpawnConfig.steering_queue field) is now wired end-to-end.
1 parent 81ec468 commit 47f9b9c

4 files changed

Lines changed: 97 additions & 101 deletions

File tree

PLAN_LEARNING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ Hermes has four layers that work together. We port all of them, adapted:
3434
└─────────────────────────────────────────────────┘
3535
```
3636

37+
VERY IMPORTANT: when making a plan you MUST examine current features such as compression and memory,
38+
and make sure they are consolidated with the plan, do not create dead code or duplicated functionality,
39+
old functionality must be either integrated or replaced
40+
3741
### Per-Project Storage Layout
3842

3943
```

src/extras/acp/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ async fn run_prompt(
197197
)
198198
.await;
199199

200-
let runner = agent.spawn_runner(prompt_text.to_string(), vec![]);
200+
let runner = agent.spawn_runner(prompt_text.to_string(), vec![], None);
201201
let mut rx = runner.event_rx;
202202

203203
// F5: correlate rig tool-call ids with ACP ids so parallel

src/provider/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ impl AnyAgent {
511511
// event channel collecting text.
512512
let runner = self
513513
.clone()
514-
.spawn_runner(effective_prompt.clone(), Vec::new());
514+
.spawn_runner(effective_prompt.clone(), Vec::new(), None);
515515
let task = runner.task;
516516
let mut event_rx = runner.event_rx;
517517

@@ -651,7 +651,12 @@ impl AnyAgent {
651651
}
652652
}
653653

654-
pub fn spawn_runner(self, prompt: String, history: Vec<Message>) -> AgentRunner {
654+
pub fn spawn_runner(
655+
self,
656+
prompt: String,
657+
history: Vec<Message>,
658+
steering_queue: Option<std::sync::Arc<std::sync::Mutex<std::collections::VecDeque<String>>>>,
659+
) -> AgentRunner {
655660
use crate::agent::agent_loop::{
656661
LoopSpawnConfig, loop_tool_to_rig_definition, retrying_stream_fn,
657662
rig_history_system_prompt, rig_history_to_loop_messages, spawn_loop_runner,
@@ -703,16 +708,11 @@ impl AnyAgent {
703708
} else {
704709
Some(self.model_name.clone())
705710
};
711+
cfg.steering_queue = steering_queue;
706712
#[cfg(feature = "plugin")]
707713
{
708714
cfg.plugin_mgr = crate::plugin::hook::global();
709715
}
710-
// steering_queue stays None for h-6 — UI's existing
711-
// interjection_queue isn't shared yet. interject_tx →
712-
// signal.cancel() handles the legacy "stop the run"
713-
// case via the LoopRunner::into_agent_runner adapter.
714-
// A follow-up UI commit will share the queue so the
715-
// model observes interjections mid-run.
716716

717717
let loop_runner = spawn_loop_runner(cfg);
718718
loop_runner.into_agent_runner()

0 commit comments

Comments
 (0)