Skip to content

Commit b00dac5

Browse files
authored
Merge pull request #62 from 100monkeys-ai/copilot/refactor-error-extraction-logic
Refactor error extraction, fix misclassified error variants, ceiling division for judge timeout, and remove dead code
2 parents 8c49c41 + 8353fb5 commit b00dac5

File tree

4 files changed

+46
-27
lines changed

4 files changed

+46
-27
lines changed

cli/src/daemon/client.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,33 @@ fn is_error_event(event: &serde_json::Value) -> bool {
394394
)
395395
}
396396

397+
fn extract_iteration_error_message(event: &serde_json::Value) -> &str {
398+
// Precedence:
399+
// 1. event.data.error.message (when error is an object)
400+
// 2. event.data.error as a string
401+
// 3. event.error as a string
402+
// 4. Fallback: "Unknown error"
403+
if let Some(err_obj) = event.get("data").and_then(|d| d.get("error")).and_then(|e| e.as_object()) {
404+
if let Some(msg) = err_obj.get("message").and_then(|m| m.as_str()) {
405+
return msg;
406+
}
407+
}
408+
409+
if let Some(msg) = event
410+
.get("data")
411+
.and_then(|d| d.get("error"))
412+
.and_then(|e| e.as_str())
413+
{
414+
return msg;
415+
}
416+
417+
if let Some(msg) = event.get("error").and_then(|e| e.as_str()) {
418+
return msg;
419+
}
420+
421+
"Unknown error"
422+
}
423+
397424
fn print_event(event: &serde_json::Value, verbose: bool) {
398425
use colored::Colorize;
399426

@@ -454,15 +481,7 @@ fn print_event(event: &serde_json::Value, verbose: bool) {
454481
}
455482
"IterationFailed" => {
456483
let iteration = event["iteration_number"].as_u64().unwrap_or(0);
457-
let error = if let Some(err_obj) = event["data"]["error"].as_object() {
458-
err_obj["message"]
459-
.as_str()
460-
.unwrap_or(event["data"]["error"].as_str().unwrap_or("Unknown error"))
461-
} else {
462-
event["data"]["error"]
463-
.as_str()
464-
.unwrap_or(event["error"].as_str().unwrap_or(""))
465-
};
484+
let error = extract_iteration_error_message(event);
466485
println!(
467486
"{} {} {} {} - {}",
468487
format!("[{}]", timestamp).dimmed(),

orchestrator/core/src/application/tool_invocation_service.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,7 @@ impl ToolInvocationService {
235235

236236
// Enforce SecurityContext constraints (e.g. subcommand_allowlist for cmd.run)
237237
if let Err(violation) = security_context.evaluate(&tool_name, &args) {
238-
return Err(SmcpSessionError::SignatureVerificationFailed(format!(
239-
"Policy violation: {:?}",
240-
violation
241-
)));
238+
return Err(SmcpSessionError::PolicyViolation(violation));
242239
}
243240

244241
// --- Inner-Loop Semantic Pre-Execution Validation (ADR-049) ---
@@ -330,7 +327,9 @@ impl ToolInvocationService {
330327
})?;
331328

332329
let poll_interval_ms = 500u64;
333-
let max_attempts = (*timeout_seconds * 1000) / poll_interval_ms;
330+
let timeout_ms = timeout_seconds.saturating_mul(1000);
331+
let max_attempts =
332+
timeout_ms.saturating_add(poll_interval_ms.saturating_sub(1)) / poll_interval_ms;
334333
let mut attempts = 0;
335334

336335
loop {
@@ -346,7 +345,10 @@ impl ToolInvocationService {
346345
.get_execution(exec_id)
347346
.await
348347
.map_err(|e| {
349-
SmcpSessionError::SignatureVerificationFailed(e.to_string())
348+
SmcpSessionError::InternalError(format!(
349+
"Failed to get judge execution {}: {}",
350+
exec_id, e
351+
))
350352
})?;
351353

352354
match exec.status {

orchestrator/core/src/domain/smcp_session.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ pub enum SmcpSessionError {
105105
SignatureVerificationFailed(String),
106106
/// A semantic judge agent did not respond within the allotted timeout window.
107107
JudgeTimeout(String),
108+
/// An unexpected internal error occurred (e.g. infrastructure or service failure).
109+
InternalError(String),
108110
}
109111

110112
impl std::fmt::Display for SmcpSessionError {
@@ -118,6 +120,7 @@ impl std::fmt::Display for SmcpSessionError {
118120
write!(f, "Signature verification failed: {}", e)
119121
}
120122
Self::JudgeTimeout(msg) => write!(f, "Judge timed out: {}", msg),
123+
Self::InternalError(msg) => write!(f, "Internal error: {}", msg),
121124
}
122125
}
123126
}
@@ -215,7 +218,7 @@ impl SmcpSession {
215218
security_context,
216219
status: SessionStatus::Active,
217220
created_at: now,
218-
expires_at: now + chrono::TimeDelta::hours(SESSION_TTL_HOURS),
221+
expires_at: now + chrono::Duration::hours(SESSION_TTL_HOURS),
219222
}
220223
}
221224

orchestrator/core/src/infrastructure/temporal_event_listener.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,10 @@ impl TemporalEventListener {
385385
};
386386

387387
let code_diff = crate::domain::execution::CodeDiff {
388+
// NOTE: RefinementApplied code diffs are persisted under the canonical
389+
// validation feedback artifact path. The file_path here is intentionally
390+
// set to VALIDATION_FEEDBACK_FILE_NAME to indicate where in the workspace
391+
// this diff content should be stored/loaded.
388392
file_path: VALIDATION_FEEDBACK_FILE_NAME.to_string(),
389393
diff: diff_str,
390394
};
@@ -418,13 +422,6 @@ impl TemporalEventListener {
418422
let domain_event = TemporalEventMapper::to_domain_event(&payload)
419423
.context("Failed to map Temporal event to domain event")?;
420424

421-
// Definition-time event — no execution_id exists.
422-
// Publish to the event bus so subscribers are notified, then return early.
423-
if let WorkflowEvent::WorkflowRegistered { .. } = &domain_event {
424-
self.event_bus.publish_workflow_event(domain_event.clone());
425-
return Ok(String::new());
426-
}
427-
428425
// All remaining workflow events are execution-scoped and carry an execution_id.
429426
let execution_id_obj = match &domain_event {
430427
WorkflowEvent::WorkflowExecutionStarted { execution_id, .. }
@@ -439,13 +436,11 @@ impl TemporalEventListener {
439436
WorkflowEvent::WorkflowRegistered { .. } => {
440437
return Err(anyhow!(
441438
"WorkflowRegistered event unexpectedly reached execution-scoped handling; \
442-
this variant should be handled before deriving an execution_id"
439+
this variant should be handled by TemporalEventMapper::to_domain_event"
443440
));
444441
}
445442
};
446443

447-
let execution_id_str = execution_id_obj.0.to_string();
448-
449444
// Step 2: Persist event to the repository for event sourcing
450445
self.execution_repository
451446
.append_event(
@@ -462,7 +457,7 @@ impl TemporalEventListener {
462457
self.event_bus.publish_workflow_event(domain_event.clone());
463458

464459
// Step 4: Return execution ID for response
465-
Ok(execution_id_str)
460+
Ok(execution_id_obj.0.to_string())
466461
}
467462
}
468463

0 commit comments

Comments
 (0)