Synced from monorepo
Changes: - Gate session-lifecycle heap steady state with a dhat soak - Unbreak merge lifecycle e2e after default model → grok-4.5 - Scan home-scope rules dirs at <root>/rules - Complete text-input paste and terminal parity - Gate project roles and personas - Use canonical editing in dialogs - Use canonical editing in search bars - Reject ambiguous MCP tool IDs - Harden Git operands for plugins - Simplify queue drain API - Pass RFC 9207 iss through MCP OAuth token exchange - Show leader roster when local agents map is empty - Use canonical editing in Persona views - Remove marketplace default-skills auto-install and purge old installs - Use canonical editing in extension forms - Add canonical dashboard text editing - Use canonical editing in settings - Add /summarize as a /recap alias - Restore previous agent when exiting dashboard - Use tool_choice auto for compaction - Settings toggle for snap-prompt-to-top on send - Update default models to grok-4.5 - Source login shell once for local bash (env + alias/function snapshot) - Template hardcoded param names in server-native tool descriptions - Fix System-Reminder XML tag injection in CLAUDE.md via agents_md - Fix remote workspace-server hardcoding LSP trust (repo code execution risk) - Clear orphaned tool-call updates at turn end - Suppress task wake after cancel - Send x-grok-client-identifier on direct API tool calls - Harden dashboard peek lease transitions - Host /btw side panel in live region (minimal mode) - Bound scroll presentation latency - Highlight multi-line constructs correctly in diffs and the file viewer - Block web_fetch non-public IPs; local opt-in is explicit-host only - Seed coding_data_retention_opt_out=false for OAuth e2es in pty-harness - Follow up clipboard delivery feedback - Use canonical editing in pickers - Route TextArea through canonical editor - Persistent "watching" status row; quieter turn markers - Gate sensitive edit targets - Expose agent registry counts and gate session churn on them - Default coding data sharing to opt-out until server preference applies - Wire chat attachment ids through gateway prompts - On auth refresh failure, issue retry - Forward preview provenance and computer lifecycle state - Document independent privacy controls and scope /privacy output - Strip SamplingError Display prefix on rate-limit UI copy - Stop dumping Cloudflare HTML into Retry failed - Disable in-place prompt edit (scroll jank on enter) - Strip forced ANSI color from gh pr view JSON - Plumb bash tool description onto ToolUsageCard wire
This commit is contained in:
parent
98c3b2438a
commit
7cfcb20d2b
292 changed files with 23315 additions and 9209 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "xai-grok-pager-bin"
|
||||
version = "0.2.102"
|
||||
version = "0.2.105"
|
||||
edition.workspace = true
|
||||
license = "Apache-2.0"
|
||||
authors = ["xAI"]
|
||||
|
|
|
|||
|
|
@ -950,6 +950,41 @@ fn shutdown_and_flush_telemetry(exit_code: i32) -> ! {
|
|||
xai_grok_telemetry::debug_log::flush();
|
||||
std::process::exit(exit_code);
|
||||
}
|
||||
async fn forward_stdio_line_to_leader(
|
||||
line: Vec<u8>,
|
||||
leader_tx: &tokio::sync::Mutex<tokio::sync::mpsc::UnboundedSender<String>>,
|
||||
replay_state: &std::sync::Mutex<StdioReplayState>,
|
||||
cancel: &CancellationToken,
|
||||
) {
|
||||
let line = String::from_utf8_lossy(&line);
|
||||
let mut trimmed = line.trim_end_matches(['\r', '\n']).to_string();
|
||||
if trimmed.is_empty() {
|
||||
return;
|
||||
}
|
||||
if trimmed.contains("\"initialize\"")
|
||||
|| trimmed.contains("\"session/load\"")
|
||||
|| trimmed.contains("\"session/new\"")
|
||||
{
|
||||
cache_outgoing_acp_state(&trimmed, replay_state);
|
||||
}
|
||||
let send_deadline = tokio::time::Instant::now() + std::time::Duration::from_secs(300);
|
||||
loop {
|
||||
{
|
||||
let tx = leader_tx.lock().await;
|
||||
match tx.send(trimmed) {
|
||||
Ok(()) => break,
|
||||
Err(tokio::sync::mpsc::error::SendError(v)) => trimmed = v,
|
||||
}
|
||||
}
|
||||
if cancel.is_cancelled() || tokio::time::Instant::now() >= send_deadline {
|
||||
tracing::error!(
|
||||
"stdio bridge: dropping client message after reconnect retries were exhausted"
|
||||
);
|
||||
break;
|
||||
}
|
||||
tokio::time::sleep(std::time::Duration::from_millis(250)).await;
|
||||
}
|
||||
}
|
||||
/// Emitted by both leader guards (server mode and leader-connect) so the two sites
|
||||
/// can't drift.
|
||||
const PLUGIN_DIR_LEADER_WARNING: &str = "grok: --plugin-dir is ignored in leader mode; run with --no-leader to \
|
||||
|
|
@ -967,16 +1002,11 @@ async fn run_agent_command(
|
|||
#[cfg(unix)]
|
||||
{
|
||||
use tokio::signal::unix::{SignalKind, signal};
|
||||
use xai_grok_pager::app::signal_handler::next_signal_code;
|
||||
let mut term = signal(SignalKind::terminate()).ok();
|
||||
let mut hup = signal(SignalKind::hangup()).ok();
|
||||
tokio::select! {
|
||||
_ = tokio::signal::ctrl_c() => { shutdown_and_flush_telemetry(130); } _ =
|
||||
async { if let Some(sig) = term.as_mut() { let _ = sig.recv(). await; }
|
||||
else { std::future::pending::< () > (). await; } } => {
|
||||
shutdown_and_flush_telemetry(143); } _ = async { if let Some(sig) = hup
|
||||
.as_mut() { let _ = sig.recv(). await; } else { std::future::pending::<
|
||||
() > (). await; } } => { shutdown_and_flush_telemetry(129); }
|
||||
}
|
||||
let code = next_signal_code(&mut term, &mut hup).await;
|
||||
shutdown_and_flush_telemetry(code);
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
|
|
@ -1061,7 +1091,6 @@ async fn run_agent_command(
|
|||
agent_config.resolve_runtime_fields(&xai_grok_shell::agent::config::RuntimeResolutionContext {
|
||||
raw_config: &raw_config,
|
||||
remote_settings: remote_settings.as_ref(),
|
||||
cwd: None,
|
||||
is_headless: !is_leader,
|
||||
cli_subagents: None,
|
||||
cli_web_search_model: None,
|
||||
|
|
@ -1164,23 +1193,9 @@ async fn run_agent_command(
|
|||
tokio::select! {
|
||||
biased; _ = cancel_stdin.cancelled() => break, maybe_line =
|
||||
stdin_lines.recv() => { let Some(line) = maybe_line else {
|
||||
break }; let line = String::from_utf8_lossy(& line); let
|
||||
trimmed = line.trim_end_matches(['\r', '\n']).to_string(); if
|
||||
trimmed.is_empty() { continue; } if trimmed
|
||||
.contains("\"initialize\"") || trimmed
|
||||
.contains("\"session/load\"") || trimmed
|
||||
.contains("\"session/new\"") { cache_outgoing_acp_state(&
|
||||
trimmed, & replay_state_stdin); } let send_deadline =
|
||||
tokio::time::Instant::now() +
|
||||
std::time::Duration::from_secs(300); loop { { let tx =
|
||||
leader_tx_stdin.lock(). await; if tx.send(trimmed.clone())
|
||||
.is_ok() { break; } } if cancel_stdin.is_cancelled() ||
|
||||
tokio::time::Instant::now() >= send_deadline {
|
||||
tracing::error!("stdio bridge: dropping client message after \
|
||||
reconnect retries were exhausted");
|
||||
break; }
|
||||
tokio::time::sleep(std::time::Duration::from_millis(250)).
|
||||
await; } }
|
||||
break }; forward_stdio_line_to_leader(line, &
|
||||
leader_tx_stdin, & replay_state_stdin, & cancel_stdin,).
|
||||
await; }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue