Process a single claudecode-type queue item: set up workspace, spawn Claude Code agent.
(item: &QueueItem)
| 235 | |
| 236 | /// Process a single claudecode-type queue item: set up workspace, spawn Claude Code agent. |
| 237 | fn process_claudecode_queue_item(item: &QueueItem) -> Result<(), String> { |
| 238 | // Resolve agent config (need workspace path, soul, instructions) |
| 239 | let agent = load_full_agent_config(item)?; |
| 240 | |
| 241 | // Resolve workspace path |
| 242 | let workspace_path = resolve_workspace_path(&agent, item)?; |
| 243 | |
| 244 | // Create workspace directory |
| 245 | std::fs::create_dir_all(&workspace_path) |
| 246 | .map_err(|e| format!("failed to create workspace: {}", e))?; |
| 247 | |
| 248 | // Write agent files into workspace |
| 249 | if let Some(soul) = &agent.soul { |
| 250 | if !soul.is_empty() { |
| 251 | std::fs::write(workspace_path.join("SOUL.md"), soul) |
| 252 | .map_err(|e| format!("write SOUL.md: {}", e))?; |
| 253 | } |
| 254 | } |
| 255 | if let Some(instructions) = &agent.instructions { |
| 256 | if !instructions.is_empty() { |
| 257 | std::fs::write(workspace_path.join("AGENTS.md"), instructions) |
| 258 | .map_err(|e| format!("write AGENTS.md: {}", e))?; |
| 259 | } |
| 260 | } |
| 261 | std::fs::write(workspace_path.join("context.json"), &item.row_data) |
| 262 | .map_err(|e| format!("write context.json: {}", e))?; |
| 263 | |
| 264 | // Build system prompt |
| 265 | let system_prompt = build_system_prompt( |
| 266 | &agent.soul, |
| 267 | &agent.instructions, |
| 268 | &agent.user_context, |
| 269 | &agent.memory, |
| 270 | ); |
| 271 | |
| 272 | // Build the prompt for Claude Code |
| 273 | let prompt = format!( |
| 274 | "Event: {} on table (oid={}), row pk={}.\n\n\ |
| 275 | Current row state (also in context.json):\n{}\n\n\ |
| 276 | Respond with a JSON object of columns to update, e.g. {{\"column\": \"value\"}}.\n\ |
| 277 | Or {{}} if no changes needed.\n\ |
| 278 | To update agent memory, include {{\"__memory\": {{...}}}}.", |
| 279 | item.event, item.table_oid.as_u32(), item.pk_value, item.row_data |
| 280 | ); |
| 281 | |
| 282 | // Spawn Claude Code agent via SDK |
| 283 | let mut options = claude_agent_sdk::ClaudeAgentOptions::builder() |
| 284 | .system_prompt(system_prompt.clone()) |
| 285 | .cwd(workspace_path) |
| 286 | .permission_mode(claude_agent_sdk::PermissionMode::AcceptEdits) |
| 287 | .build(); |
| 288 | options.model = Some(agent.model.clone()); |
| 289 | |
| 290 | let response = http::runtime().block_on(async { |
| 291 | let stream = claude_agent_sdk::query(&prompt, Some(options)) |
| 292 | .await |
| 293 | .map_err(|e| format!("Claude Code spawn error: {}", e))?; |
| 294 | pin!(stream); |
no test coverage detected