fix: resolve 6 remaining defects (P2-18, P2-21, P3-04, P3-05, P3-06, P3-02)
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
- P2-18: TOTP QR code local generation via qrcode lib (no external service) - P2-21: Suspend foreign LLM providers (OpenAI/Anthropic/Gemini) for early stage - P3-04: get_progress() now calculates actual percentage from completed/total steps - P3-05: saveSaaSSession calls now have .catch() error logging - P3-06: SaaS relay chatStream passes session_key/agent_id to backend - P3-02: Whiteboard unification plan document created Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -458,6 +458,8 @@ impl KernelConfig {
|
||||
LlmConfig::openai(api_key).with_model(model)
|
||||
}
|
||||
}
|
||||
// P2-21: Gemini 暂停支持 — 前期不使用非国内大模型
|
||||
// 保留代码,但前端已标记为暂停,不再可选
|
||||
"gemini" => LlmConfig::new(
|
||||
base_url.unwrap_or("https://generativelanguage.googleapis.com/v1beta"),
|
||||
api_key,
|
||||
|
||||
@@ -86,6 +86,7 @@ impl PipelineExecutor {
|
||||
let run_id = run_id.to_string();
|
||||
|
||||
// Create run record
|
||||
let total_steps = pipeline.spec.steps.len();
|
||||
let run = PipelineRun {
|
||||
id: run_id.clone(),
|
||||
pipeline_id: pipeline_id.clone(),
|
||||
@@ -95,6 +96,7 @@ impl PipelineExecutor {
|
||||
step_results: HashMap::new(),
|
||||
outputs: None,
|
||||
error: None,
|
||||
total_steps,
|
||||
started_at: Utc::now(),
|
||||
ended_at: None,
|
||||
};
|
||||
@@ -466,12 +468,26 @@ impl PipelineExecutor {
|
||||
pub async fn get_progress(&self, run_id: &str) -> Option<PipelineProgress> {
|
||||
let run = self.runs.read().await.get(run_id)?.clone();
|
||||
|
||||
let (current_step, percentage) = if run.step_results.is_empty() {
|
||||
("starting".to_string(), 0)
|
||||
} else if let Some(step) = &run.current_step {
|
||||
(step.clone(), 50)
|
||||
} else {
|
||||
let (current_step, percentage) = if run.total_steps == 0 {
|
||||
// Empty pipeline or unknown total
|
||||
match run.status {
|
||||
RunStatus::Completed => ("completed".to_string(), 100),
|
||||
_ => ("starting".to_string(), 0),
|
||||
}
|
||||
} else if run.status == RunStatus::Completed {
|
||||
("completed".to_string(), 100)
|
||||
} else if let Some(step) = &run.current_step {
|
||||
// P3-04: Calculate actual percentage from completed steps
|
||||
let completed = run.step_results.len();
|
||||
let pct = ((completed as f64 / run.total_steps as f64) * 100.0).min(99.0) as u8;
|
||||
(step.clone(), pct)
|
||||
} else if run.step_results.is_empty() {
|
||||
("starting".to_string(), 0)
|
||||
} else {
|
||||
// Not running, not completed (failed/cancelled)
|
||||
let completed = run.step_results.len();
|
||||
let pct = ((completed as f64 / run.total_steps as f64) * 100.0) as u8;
|
||||
("stopped".to_string(), pct)
|
||||
};
|
||||
|
||||
Some(PipelineProgress {
|
||||
|
||||
@@ -465,6 +465,10 @@ pub struct PipelineRun {
|
||||
/// Error message (if failed)
|
||||
pub error: Option<String>,
|
||||
|
||||
/// Total number of steps (P3-04: for granular progress)
|
||||
#[serde(default)]
|
||||
pub total_steps: usize,
|
||||
|
||||
/// Start time
|
||||
pub started_at: chrono::DateTime<chrono::Utc>,
|
||||
|
||||
|
||||
@@ -200,9 +200,16 @@ pub async fn chat_completions(
|
||||
state.cache.relay_enqueue(&ctx.account_id);
|
||||
|
||||
// 异步派发操作日志(非阻塞,不占用关键路径 DB 连接)
|
||||
// P3-06: Include session_key/agent_id in log for traceability
|
||||
let log_meta = serde_json::json!({
|
||||
"model": model_name,
|
||||
"stream": stream,
|
||||
"session_key": req.get("session_key").and_then(|v| v.as_str()),
|
||||
"agent_id": req.get("agent_id").and_then(|v| v.as_str()),
|
||||
});
|
||||
state.dispatch_log_operation(
|
||||
&ctx.account_id, "relay.request", "relay_task", &task.id,
|
||||
Some(serde_json::json!({"model": model_name, "stream": stream})), ctx.client_ip.as_deref(),
|
||||
Some(log_meta), ctx.client_ip.as_deref(),
|
||||
).await;
|
||||
|
||||
// 执行中转:根据解析结果选择执行路径
|
||||
|
||||
@@ -13,6 +13,12 @@ pub struct RelayChatRequest {
|
||||
pub max_tokens: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub stream: bool,
|
||||
/// P3-06: Client session key for continuity
|
||||
#[serde(default, rename = "session_key")]
|
||||
pub session_key: Option<String>,
|
||||
/// P3-06: Agent ID for context routing
|
||||
#[serde(default, rename = "agent_id")]
|
||||
pub agent_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user