fix: resolve 17 P2 defects and 5 P3 defects from pre-launch audit
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Batch fix covering multiple modules:
- P2-01: HandRegistry Semaphore-based max_concurrent enforcement
- P2-03: Populate toolCount/metricCount from Hand trait methods
- P2-06: heartbeat_update_config minimum interval validation
- P2-07: ReflectionResult used_fallback marker for rule-based fallback
- P2-08/09: identity_propose_change parameter naming consistency
- P2-10: ClassroomMetadata is_placeholder flag for LLM failure
- P2-11: classroomStore userDidCloseDuringGeneration intent tracking
- P2-12: workflowStore pipeline_create sends actionType
- P2-13/14: PipelineInfo step_count + PipelineStepInfo for proper step mapping
- P2-15: Pipe transform support in context.resolve (8 transforms)
- P2-16: Mustache {{...}} → \${...} auto-normalization
- P2-17: SaaSLogin password placeholder 6→8
- P2-19: serialize_skill_md + update_skill preserve tools field
- P2-22: ToolOutputGuard sensitive patterns from warn→block
- P2-23: Mutex::unwrap() → unwrap_or_else in relay/service.rs
- P3-01/03/07/08/09: Various P3 fixes
- DEFECT_LIST.md: comprehensive status sync (43/51 fixed, 8 remaining)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -179,6 +179,9 @@ pub struct ClassroomMetadata {
|
||||
pub source_document: Option<String>,
|
||||
pub model: Option<String>,
|
||||
pub version: String,
|
||||
/// P2-10: Whether content was generated from placeholder fallback (not LLM)
|
||||
#[serde(default)]
|
||||
pub is_placeholder: bool,
|
||||
pub custom: serde_json::Map<String, serde_json::Value>,
|
||||
}
|
||||
|
||||
@@ -325,6 +328,7 @@ impl GenerationPipeline {
|
||||
let outline = if let Some(driver) = &self.driver {
|
||||
self.generate_outline_with_llm(driver.as_ref(), &prompt, request).await?
|
||||
} else {
|
||||
tracing::warn!("[P2-10] No LLM driver available, using placeholder outline");
|
||||
self.generate_outline_placeholder(request)
|
||||
};
|
||||
|
||||
@@ -397,14 +401,15 @@ impl GenerationPipeline {
|
||||
// Stage 0: Agent profiles
|
||||
let agents = self.generate_agent_profiles(&request).await;
|
||||
|
||||
// Stage 1: Outline
|
||||
// Stage 1: Outline — track if placeholder was used (P2-10)
|
||||
let is_placeholder = self.driver.is_none();
|
||||
let outline = self.generate_outline(&request).await?;
|
||||
|
||||
// Stage 2: Scenes
|
||||
let scenes = self.generate_scenes(&outline).await?;
|
||||
|
||||
// Build classroom
|
||||
self.build_classroom(request, outline, scenes, agents)
|
||||
self.build_classroom(request, outline, scenes, agents, is_placeholder)
|
||||
}
|
||||
|
||||
// --- LLM integration methods ---
|
||||
@@ -787,6 +792,7 @@ Use Chinese if the topic is in Chinese. Include metaphors that relate to everyda
|
||||
_outline: Vec<OutlineItem>,
|
||||
scenes: Vec<GeneratedScene>,
|
||||
agents: Vec<AgentProfile>,
|
||||
is_placeholder: bool,
|
||||
) -> Result<Classroom> {
|
||||
let total_duration: u32 = scenes.iter()
|
||||
.map(|s| s.content.duration_seconds)
|
||||
@@ -814,6 +820,7 @@ Use Chinese if the topic is in Chinese. Include metaphors that relate to everyda
|
||||
source_document: request.document.map(|_| "user_document".to_string()),
|
||||
model: None,
|
||||
version: "2.0.0".to_string(),
|
||||
is_placeholder, // P2-10: mark placeholder content
|
||||
custom: serde_json::Map::new(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -201,7 +201,17 @@ impl Kernel {
|
||||
|
||||
let context = HandContext::default();
|
||||
let start = std::time::Instant::now();
|
||||
let hand_result = self.hands.execute(hand_id, &context, input).await;
|
||||
|
||||
// P2-02: Apply timeout to execute_hand_with_source (same as execute_hand)
|
||||
let timeout_secs = self.hands.get_config(hand_id)
|
||||
.await
|
||||
.map(|c| if c.timeout_secs > 0 { c.timeout_secs } else { context.timeout_secs })
|
||||
.unwrap_or(context.timeout_secs);
|
||||
|
||||
let hand_result = tokio::time::timeout(
|
||||
std::time::Duration::from_secs(timeout_secs),
|
||||
self.hands.execute(hand_id, &context, input),
|
||||
).await;
|
||||
let duration = start.elapsed();
|
||||
|
||||
// Check if cancelled during execution
|
||||
@@ -217,6 +227,23 @@ impl Kernel {
|
||||
self.running_hand_runs.remove(&run_id);
|
||||
|
||||
let completed_at = chrono::Utc::now().to_rfc3339();
|
||||
// Handle timeout result
|
||||
let hand_result = match hand_result {
|
||||
Ok(result) => result,
|
||||
Err(_) => {
|
||||
// Timeout elapsed
|
||||
cancel_flag.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
run.status = HandRunStatus::Failed;
|
||||
run.error = Some(format!("Hand execution timed out after {}s", timeout_secs));
|
||||
run.duration_ms = Some(duration.as_millis() as u64);
|
||||
run.completed_at = Some(completed_at);
|
||||
self.memory.update_hand_run(&run).await?;
|
||||
return Err(zclaw_types::ZclawError::Internal(
|
||||
format!("Hand '{}' timed out after {}s", hand_id, timeout_secs)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
match &hand_result {
|
||||
Ok(res) => {
|
||||
run.status = HandRunStatus::Completed;
|
||||
|
||||
Reference in New Issue
Block a user