Synced from monorepo
Synced from monorepo Changes: - Refresh tool search when the managed MCP catalog is re-fetched - Prevent duplicate leader process spawn and startup hang from stale leaders - Document marketplaces, plugins, and organization controls - Stamp session ID on image generation direct-to-API requests - Fix auto mode blocked documentation - Auto mode considers recent user intent - Expose deploy archive, taken-down, limit, and in-progress reasons on the chat API - Fail-closed auth refresh contract for shell clients - Emit a chat-supplied per-session turn index in turn hooks - Show bash mode chrome in minimal mode - Add metrics for true-noop and stationarity stops - Include voice interim text on prompt submit - Silently end turn on true-noop thrash - Quiet copy toast when clipboard delivery is confirmed - Fix session fork truncating at the wrong prompt in rewound sessions - Make the idle "still running" watcher cue clickable to open the tasks pane - Default web search model to grok-4.5 - Let plugin subagents inherit parent MCP servers - Gate no-op end-turn reminder on system reminders - Add gateway bridge lifecycle telemetry - Allow editing finalized text while voice is open - Relocate token carrier to turn-commit events and plumb per-turn origin context - Raise workflow scratch quotas and make failed runs resumable - Workflows overlay: auto-progress phases, live agent status, and drop budget meter Source-Revision: 9b8d35b46d959c042ea9aa31cbbebbd1f0c5c527
This commit is contained in:
parent
69f0ba880a
commit
6e38642082
103 changed files with 4964 additions and 1261 deletions
|
|
@ -1881,6 +1881,27 @@ impl AppView {
|
|||
|| self.voice_listening()
|
||||
|| self.voice_state.pending_cold_start()
|
||||
}
|
||||
/// Commit interim on real send keys only (not multiline bare Enter).
|
||||
fn maybe_commit_voice_interim_before_submit_key(&mut self, key: &crossterm::event::KeyEvent) {
|
||||
if self.registry.matches_id(ActionId::InterjectPrompt, key) {
|
||||
let _ = crate::voice::commit_interim_into_prompt(self);
|
||||
return;
|
||||
}
|
||||
let multiline = match self.active_view {
|
||||
ActiveView::Agent(id) => self.agents.get(&id).is_some_and(|a| a.multiline_mode),
|
||||
ActiveView::AgentDashboard => self.dashboard.as_ref().is_some_and(|d| d.multiline_mode),
|
||||
_ => false,
|
||||
};
|
||||
let is_send = if multiline {
|
||||
crate::input::is_mod_enter(key)
|
||||
} else {
|
||||
matches!(key.code, KeyCode::Enter)
|
||||
|| self.registry.matches_id(ActionId::SendPrompt, key)
|
||||
};
|
||||
if is_send {
|
||||
let _ = crate::voice::commit_interim_into_prompt(self);
|
||||
}
|
||||
}
|
||||
/// The active agent's view, when an agent tab is focused.
|
||||
///
|
||||
/// Always the root agent, even when a subagent view is focused within the
|
||||
|
|
@ -2623,6 +2644,11 @@ impl AppView {
|
|||
if let Some(outcome) = self.voice_esc_outcome(key_event) {
|
||||
return outcome;
|
||||
}
|
||||
if let Event::Key(key) = ev
|
||||
&& key.kind != KeyEventKind::Release
|
||||
{
|
||||
self.maybe_commit_voice_interim_before_submit_key(key);
|
||||
}
|
||||
if self.screen_mode.is_minimal()
|
||||
&& let Event::Key(key) = ev
|
||||
&& key.kind != KeyEventKind::Release
|
||||
|
|
@ -2669,6 +2695,11 @@ impl AppView {
|
|||
if let Some(outcome) = self.voice_esc_outcome(key_event) {
|
||||
return outcome;
|
||||
}
|
||||
if let Event::Key(key) = ev
|
||||
&& key.kind != KeyEventKind::Release
|
||||
{
|
||||
self.maybe_commit_voice_interim_before_submit_key(key);
|
||||
}
|
||||
let attached_raw = self.dashboard.as_ref().and_then(|d| d.attached_agent);
|
||||
let attached = attached_raw.filter(|id| self.agents.contains_key(id));
|
||||
if attached_raw.is_some()
|
||||
|
|
@ -9919,6 +9950,7 @@ pub(crate) mod tests {
|
|||
model: None,
|
||||
state: "running".to_owned(),
|
||||
tokens_used: 0,
|
||||
duration_ms: 0,
|
||||
}],
|
||||
agent_budget: None,
|
||||
agents_used: 0,
|
||||
|
|
|
|||
Loading…
Reference in a new issue