Skip to content

Commit b066007

Browse files
123vivekrvick08
authored andcommitted
agents: remove sidecar execution path; always use system binary
Delete sidecar helpers and imports Replace conditional with direct spawn_agent_system Avoid sidecar env issues with Node
1 parent 686a4b2 commit b066007

File tree

1 file changed

+15
-228
lines changed

1 file changed

+15
-228
lines changed

src-tauri/src/commands/agents.rs

Lines changed: 15 additions & 228 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use std::io::{BufRead, BufReader};
1010
use std::process::Stdio;
1111
use std::sync::Mutex;
1212
use tauri::{AppHandle, Emitter, Manager, State};
13-
use tauri_plugin_shell::ShellExt;
14-
use tauri_plugin_shell::process::CommandEvent;
13+
// Sidecar support removed; using system binary execution only
1514
use tokio::io::{AsyncBufReadExt, BufReader as TokioBufReader};
1615
use tokio::process::Command;
1716

@@ -766,49 +765,20 @@ pub async fn execute_agent(
766765
"--dangerously-skip-permissions".to_string(),
767766
];
768767

769-
// Execute based on whether we should use sidecar or system binary
770-
if should_use_sidecar(&claude_path) {
771-
spawn_agent_sidecar(app, run_id, agent_id, agent.name.clone(), args, project_path, task, execution_model, db, registry).await
772-
} else {
773-
spawn_agent_system(app, run_id, agent_id, agent.name.clone(), claude_path, args, project_path, task, execution_model, db, registry).await
774-
}
775-
}
776-
777-
/// Determines whether to use sidecar or system binary execution for agents
778-
fn should_use_sidecar(claude_path: &str) -> bool {
779-
claude_path == "claude-code"
780-
}
781-
782-
/// Creates a sidecar command for agent execution
783-
fn create_agent_sidecar_command(
784-
app: &AppHandle,
785-
args: Vec<String>,
786-
project_path: &str,
787-
) -> Result<tauri_plugin_shell::process::Command, String> {
788-
let mut sidecar_cmd = app
789-
.shell()
790-
.sidecar("claude-code")
791-
.map_err(|e| format!("Failed to create sidecar command: {}", e))?;
792-
793-
// Add all arguments
794-
sidecar_cmd = sidecar_cmd.args(args);
795-
796-
// Set working directory
797-
sidecar_cmd = sidecar_cmd.current_dir(project_path);
798-
799-
// Pass through proxy environment variables if they exist (only uppercase)
800-
for (key, value) in std::env::vars() {
801-
if key == "HTTP_PROXY"
802-
|| key == "HTTPS_PROXY"
803-
|| key == "NO_PROXY"
804-
|| key == "ALL_PROXY"
805-
{
806-
debug!("Setting proxy env var for agent sidecar: {}={}", key, value);
807-
sidecar_cmd = sidecar_cmd.env(&key, &value);
808-
}
809-
}
810-
811-
Ok(sidecar_cmd)
768+
// Always use system binary execution (sidecar removed)
769+
spawn_agent_system(
770+
app,
771+
run_id,
772+
agent_id,
773+
agent.name.clone(),
774+
claude_path,
775+
args,
776+
project_path,
777+
task,
778+
execution_model,
779+
db,
780+
registry,
781+
).await
812782
}
813783

814784
/// Creates a system binary command for agent execution
@@ -832,189 +802,6 @@ fn create_agent_system_command(
832802
cmd
833803
}
834804

835-
/// Spawn agent using sidecar command
836-
async fn spawn_agent_sidecar(
837-
app: AppHandle,
838-
run_id: i64,
839-
agent_id: i64,
840-
agent_name: String,
841-
args: Vec<String>,
842-
project_path: String,
843-
task: String,
844-
execution_model: String,
845-
db: State<'_, AgentDb>,
846-
registry: State<'_, crate::process::ProcessRegistryState>,
847-
) -> Result<i64, String> {
848-
// Build the sidecar command
849-
let sidecar_cmd = create_agent_sidecar_command(&app, args, &project_path)?;
850-
851-
// Spawn the process
852-
info!("🚀 Spawning Claude sidecar process...");
853-
let (mut receiver, child) = sidecar_cmd.spawn().map_err(|e| {
854-
error!("❌ Failed to spawn Claude sidecar process: {}", e);
855-
format!("Failed to spawn Claude sidecar: {}", e)
856-
})?;
857-
858-
// Get the PID from child
859-
let pid = child.pid();
860-
let now = chrono::Utc::now().to_rfc3339();
861-
info!("✅ Claude sidecar process spawned successfully with PID: {}", pid);
862-
863-
// Update the database with PID and status
864-
{
865-
let conn = db.0.lock().map_err(|e| e.to_string())?;
866-
conn.execute(
867-
"UPDATE agent_runs SET status = 'running', pid = ?1, process_started_at = ?2 WHERE id = ?3",
868-
params![pid as i64, now, run_id],
869-
).map_err(|e| e.to_string())?;
870-
info!("📝 Updated database with running status and PID");
871-
}
872-
873-
// Get app directory for database path
874-
let app_dir = app
875-
.path()
876-
.app_data_dir()
877-
.expect("Failed to get app data dir");
878-
let db_path = app_dir.join("agents.db");
879-
880-
// Shared state for collecting session ID and live output
881-
let session_id = std::sync::Arc::new(Mutex::new(String::new()));
882-
let live_output = std::sync::Arc::new(Mutex::new(String::new()));
883-
let _start_time = std::time::Instant::now();
884-
885-
// Register the process in the registry
886-
registry
887-
.0
888-
.register_sidecar_process(
889-
run_id,
890-
agent_id,
891-
agent_name,
892-
pid as u32,
893-
project_path.clone(),
894-
task.clone(),
895-
execution_model.clone(),
896-
)
897-
.map_err(|e| format!("Failed to register sidecar process: {}", e))?;
898-
info!("📋 Registered sidecar process in registry");
899-
900-
// Handle sidecar events
901-
let app_handle = app.clone();
902-
let session_id_clone = session_id.clone();
903-
let live_output_clone = live_output.clone();
904-
let registry_clone = registry.0.clone();
905-
let first_output = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
906-
let first_output_clone = first_output.clone();
907-
let db_path_for_sidecar = db_path.clone();
908-
909-
tokio::spawn(async move {
910-
info!("📖 Starting to read Claude sidecar events...");
911-
let mut line_count = 0;
912-
913-
while let Some(event) = receiver.recv().await {
914-
match event {
915-
CommandEvent::Stdout(line_bytes) => {
916-
let line = String::from_utf8_lossy(&line_bytes);
917-
line_count += 1;
918-
919-
// Log first output
920-
if !first_output_clone.load(std::sync::atomic::Ordering::Relaxed) {
921-
info!(
922-
"🎉 First output received from Claude sidecar process! Line: {}",
923-
line
924-
);
925-
first_output_clone.store(true, std::sync::atomic::Ordering::Relaxed);
926-
}
927-
928-
if line_count <= 5 {
929-
info!("sidecar stdout[{}]: {}", line_count, line);
930-
} else {
931-
debug!("sidecar stdout[{}]: {}", line_count, line);
932-
}
933-
934-
// Store live output
935-
if let Ok(mut output) = live_output_clone.lock() {
936-
output.push_str(&line);
937-
output.push('\n');
938-
}
939-
940-
// Also store in process registry
941-
let _ = registry_clone.append_live_output(run_id, &line);
942-
943-
// Extract session ID from JSONL output
944-
if let Ok(json) = serde_json::from_str::<JsonValue>(&line) {
945-
if json.get("type").and_then(|t| t.as_str()) == Some("system") &&
946-
json.get("subtype").and_then(|s| s.as_str()) == Some("init") {
947-
if let Some(sid) = json.get("session_id").and_then(|s| s.as_str()) {
948-
if let Ok(mut current_session_id) = session_id_clone.lock() {
949-
if current_session_id.is_empty() {
950-
*current_session_id = sid.to_string();
951-
info!("🔑 Extracted session ID: {}", sid);
952-
953-
// Update database immediately with session ID
954-
if let Ok(conn) = Connection::open(&db_path_for_sidecar) {
955-
match conn.execute(
956-
"UPDATE agent_runs SET session_id = ?1 WHERE id = ?2",
957-
params![sid, run_id],
958-
) {
959-
Ok(rows) => {
960-
if rows > 0 {
961-
info!("✅ Updated agent run {} with session ID immediately", run_id);
962-
}
963-
}
964-
Err(e) => {
965-
error!("❌ Failed to update session ID immediately: {}", e);
966-
}
967-
}
968-
}
969-
}
970-
}
971-
}
972-
}
973-
}
974-
975-
// Emit the line to the frontend
976-
let _ = app_handle.emit(&format!("agent-output:{}", run_id), &line);
977-
let _ = app_handle.emit("agent-output", &line);
978-
}
979-
CommandEvent::Stderr(line_bytes) => {
980-
let line = String::from_utf8_lossy(&line_bytes);
981-
error!("sidecar stderr: {}", line);
982-
let _ = app_handle.emit(&format!("agent-error:{}", run_id), &line);
983-
let _ = app_handle.emit("agent-error", &line);
984-
}
985-
CommandEvent::Terminated(payload) => {
986-
info!("Claude sidecar process terminated with code: {:?}", payload.code);
987-
988-
// Get the session ID
989-
let extracted_session_id = if let Ok(sid) = session_id.lock() {
990-
sid.clone()
991-
} else {
992-
String::new()
993-
};
994-
995-
// Update database with completion
996-
if let Ok(conn) = Connection::open(&db_path) {
997-
let _ = conn.execute(
998-
"UPDATE agent_runs SET session_id = ?1, status = 'completed', completed_at = CURRENT_TIMESTAMP WHERE id = ?2",
999-
params![extracted_session_id, run_id],
1000-
);
1001-
}
1002-
1003-
let success = payload.code.unwrap_or(1) == 0;
1004-
let _ = app.emit("agent-complete", success);
1005-
let _ = app.emit(&format!("agent-complete:{}", run_id), success);
1006-
break;
1007-
}
1008-
_ => {}
1009-
}
1010-
}
1011-
1012-
info!("📖 Finished reading Claude sidecar events. Total lines: {}", line_count);
1013-
});
1014-
1015-
Ok(run_id)
1016-
}
1017-
1018805
/// Spawn agent using system binary command
1019806
async fn spawn_agent_system(
1020807
app: AppHandle,

0 commit comments

Comments
 (0)