Synced from monorepo
Changes: - Detect the herdr multiplexer - Mark /gboom as non-production code - Bound peak memory when loading a large session - Add a subagent lifecycle soak bounding threads, fds, and heap - Stream inherited replay to bound fork memory - Copy full plan from plan approval with y - Stop armed signature verification from deleting the managed-deny smoke policy - Add source-tagged terminal version telemetry - Show the UI instantly and fetch models and settings in the background - Session test helpers - computer_reason on the ConversationHistoryDone trailer
This commit is contained in:
parent
47348d13ec
commit
b41c75a578
92 changed files with 9410 additions and 3788 deletions
|
|
@ -1,8 +1,8 @@
|
|||
//! Fork-path benchmark and profiling workbench.
|
||||
//!
|
||||
//! Synthesizes a session whose `updates.jsonl` matches a configurable target
|
||||
//! size (realistic mixed update shapes: user/agent chunks, tool calls with
|
||||
//! large results), then measures `StorageAdapter::copy_session_data` — the
|
||||
//! size (production byte/line shape: user and agent chunks plus one bulky
|
||||
//! trailing chunk), then measures `StorageAdapter::copy_session_data`, the
|
||||
//! path that materializes the whole file and produced multi-GB RSS spikes on
|
||||
//! large production sessions. Also the substrate for allocation/CPU profiling
|
||||
//! (`cargo flamegraph --bench fork_copy`, dhat) and future peak-RSS bounds.
|
||||
|
|
@ -13,74 +13,14 @@
|
|||
use std::hint::black_box;
|
||||
use std::time::Duration;
|
||||
|
||||
use acp::{ContentBlock, ContentChunk, TextContent};
|
||||
use agent_client_protocol as acp;
|
||||
use criterion::{
|
||||
BenchmarkId, Criterion, SamplingMode, Throughput, criterion_group, criterion_main,
|
||||
};
|
||||
use tempfile::TempDir;
|
||||
use xai_grok_shell::session::info::Info;
|
||||
use xai_grok_shell::session::storage::{
|
||||
CopySessionOptions, JsonlStorageAdapter, SessionUpdate, StorageAdapter,
|
||||
};
|
||||
|
||||
/// One synthetic "turn": a user chunk, agent chunks, and a bulky tool result,
|
||||
/// so line-size distribution and parse cost resemble production sessions.
|
||||
fn turn_updates(info: &Info, turn: usize) -> Vec<SessionUpdate> {
|
||||
let text = |s: String| ContentChunk::new(ContentBlock::Text(TextContent::new(s)));
|
||||
let notify =
|
||||
|u| SessionUpdate::Acp(Box::new(acp::SessionNotification::new(info.id.clone(), u)));
|
||||
let mut updates = vec![notify(acp::SessionUpdate::UserMessageChunk(text(format!(
|
||||
"prompt {turn}: check the build and summarize failures"
|
||||
))))];
|
||||
for i in 0..8 {
|
||||
updates.push(notify(acp::SessionUpdate::AgentMessageChunk(text(format!(
|
||||
"agent chunk {turn}/{i}: analyzing module {i} for regressions and drafting a fix plan"
|
||||
)))));
|
||||
}
|
||||
// ~4 KB tool-result payload: the dominant byte source in real sessions.
|
||||
updates.push(notify(acp::SessionUpdate::AgentMessageChunk(text(
|
||||
format!("tool result {turn}: {}", "x".repeat(4096)),
|
||||
))));
|
||||
updates
|
||||
}
|
||||
|
||||
/// Build a session dir whose `updates.jsonl` is at least `target_bytes`.
|
||||
fn synthesize_session(root: &TempDir, target_bytes: u64) -> Info {
|
||||
let adapter = JsonlStorageAdapter::with_root(root.path().to_path_buf());
|
||||
let info = Info {
|
||||
id: acp::SessionId::new("fork-bench-src"),
|
||||
cwd: "/bench/workspace".to_string(),
|
||||
};
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("bench runtime");
|
||||
rt.block_on(async {
|
||||
adapter
|
||||
.init_session(&info, acp::ModelId::new("bench-model"))
|
||||
.await
|
||||
.expect("init session");
|
||||
let updates_path = adapter.updates_file_path(&info).expect("updates path");
|
||||
let mut turn = 0usize;
|
||||
loop {
|
||||
for update in turn_updates(&info, turn) {
|
||||
adapter.append_update(&info, &update).await.expect("append");
|
||||
}
|
||||
turn += 1;
|
||||
// Stat every 32 turns; sizes only grow.
|
||||
if turn % 32 == 0
|
||||
&& std::fs::metadata(&updates_path)
|
||||
.map(|m| m.len())
|
||||
.unwrap_or(0)
|
||||
>= target_bytes
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
info
|
||||
}
|
||||
use xai_grok_shell::session::storage::{CopySessionOptions, JsonlStorageAdapter, StorageAdapter};
|
||||
use xai_grok_shell::session::testkit::synth::synthesize_to_target_bytes;
|
||||
|
||||
fn bench_fork_copy(c: &mut Criterion) {
|
||||
let target_mb: u64 = std::env::var("FORK_BENCH_MB")
|
||||
|
|
@ -88,7 +28,7 @@ fn bench_fork_copy(c: &mut Criterion) {
|
|||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(16);
|
||||
let root = TempDir::new().expect("tempdir");
|
||||
let source = synthesize_session(&root, target_mb * 1024 * 1024);
|
||||
let source = synthesize_to_target_bytes(root.path(), target_mb * 1024 * 1024);
|
||||
let adapter = JsonlStorageAdapter::with_root(root.path().to_path_buf());
|
||||
let updates_len = std::fs::metadata(adapter.updates_file_path(&source).expect("updates path"))
|
||||
.expect("updates.jsonl")
|
||||
|
|
|
|||
Loading…
Reference in a new issue