Integrate Codex patterns: task scheduler, TUI, sessions, compaction

Add Codex-inspired patterns for improved agent architecture:

**Task Scheduler (Phase 1 & 4)**
- New Task enum with Job, ToolExec, Background variants
- TaskHandler trait for custom background tasks
- Scheduler.spawn_subtask() and spawn_batch() for parallel execution
- Worker executes multiple tools in parallel via futures::join_all

**Tool Approval System (Phase 6)**
- Tool.requires_approval() method (default false for sandboxed tools)
- HttpTool marked as requiring approval (external network)
- MCP protocol annotations: destructive_hint, side_effects_hint

**Ratatui TUI CLI (Phase 2)**
- Replace blocking stdin with event-driven TUI
- ChatComposer with history navigation and tab completion
- ApprovalOverlay modal with y/n/a keyboard shortcuts
- Raw mode with proper terminal cleanup

**Session/Turn Model (Phase 3)**
- Session, Thread, Turn structs for conversation tracking
- Submission enum for user input, approvals, undo, interrupt
- UndoManager with checkpoint-based undo/redo

**Context Compaction (Phase 5)**
- ContextMonitor with token estimation and threshold checks
- CompactionStrategy: Summarize, Truncate, MoveToWorkspace
- ContextCompactor writes summaries to workspace daily logs

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
Illia Polosukhin
2026-02-02 23:41:57 -08:00
co-authored by Claude Opus 4.5
parent d047c23b2d
commit 09032d69cb
26 changed files with 3944 additions and 272 deletions
+8 -10
View File
@@ -299,12 +299,11 @@ impl LeakDetector {
// Scan each header value
for (name, value) in headers {
self.scan_and_clean(value).map_err(|e| {
LeakDetectionError::SecretLeakBlocked {
self.scan_and_clean(value)
.map_err(|e| LeakDetectionError::SecretLeakBlocked {
pattern: format!("header:{}", name),
preview: e.to_string(),
}
})?;
})?;
}
// Scan body if present and valid UTF-8
@@ -688,7 +687,10 @@ mod tests {
// Attempt to exfiltrate in custom header
let result = detector.scan_http_request(
"https://api.example.com/data",
&[("X-Custom".to_string(), "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".to_string())],
&[(
"X-Custom".to_string(),
"ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".to_string(),
)],
None,
);
assert!(result.is_err());
@@ -700,11 +702,7 @@ mod tests {
// Attempt to exfiltrate in request body
let body = b"{\"stolen\": \"sk-proj-test1234567890abcdefghij\"}";
let result = detector.scan_http_request(
"https://api.example.com/webhook",
&[],
Some(body),
);
let result = detector.scan_http_request("https://api.example.com/webhook", &[], Some(body));
assert!(result.is_err());
}
}