fix: restore zhihu ws routing before direct submit

Keep ws-backed submit flows routing Zhihu natural-language requests through orchestration before direct submit so sg_claw service console behavior stays consistent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
木炎
2026-04-12 21:14:35 +08:00
parent d230ff0389
commit 447457b7d3
2 changed files with 135 additions and 60 deletions

View File

@@ -253,6 +253,36 @@ pub fn run_submit_task<T: Transport + 'static>(
}; };
return sink.send(&completion); return sink.send(&completion);
} }
if RuntimeEngine::new(settings.runtime_profile).browser_surface_enabled()
&& crate::compat::orchestration::should_use_primary_orchestration(
&instruction,
task_context.page_url.as_deref(),
task_context.page_title.as_deref(),
)
{
let _ = send_mode_log(sink, "zeroclaw_process_message_primary");
match crate::compat::orchestration::execute_task_with_sgclaw_settings(
transport,
browser_tool.clone(),
&instruction,
&task_context,
&context.workspace_root,
&settings,
) {
Ok(summary) => {
return sink.send(&AgentMessage::TaskComplete {
success: true,
summary,
});
}
Err(err) => {
return sink.send(&AgentMessage::TaskComplete {
success: false,
summary: err.to_string(),
});
}
}
}
if settings if settings
.direct_submit_skill .direct_submit_skill
.as_deref() .as_deref()
@@ -289,36 +319,6 @@ pub fn run_submit_task<T: Transport + 'static>(
} }
} }
} }
if RuntimeEngine::new(settings.runtime_profile).browser_surface_enabled()
&& crate::compat::orchestration::should_use_primary_orchestration(
&instruction,
task_context.page_url.as_deref(),
task_context.page_title.as_deref(),
)
{
let _ = send_mode_log(sink, "zeroclaw_process_message_primary");
match crate::compat::orchestration::execute_task_with_sgclaw_settings(
transport,
browser_tool.clone(),
&instruction,
&task_context,
&context.workspace_root,
&settings,
) {
Ok(summary) => {
return sink.send(&AgentMessage::TaskComplete {
success: true,
summary,
});
}
Err(err) => {
return sink.send(&AgentMessage::TaskComplete {
success: false,
summary: err.to_string(),
});
}
}
}
let _ = send_mode_log(sink, "compat_llm_primary"); let _ = send_mode_log(sink, "compat_llm_primary");
match crate::compat::runtime::execute_task_with_sgclaw_settings( match crate::compat::runtime::execute_task_with_sgclaw_settings(
transport, transport,
@@ -443,6 +443,36 @@ pub fn run_submit_task_with_browser_backend<T: Transport + 'static>(
}; };
return sink.send(&completion); return sink.send(&completion);
} }
if RuntimeEngine::new(settings.runtime_profile).browser_surface_enabled()
&& crate::compat::orchestration::should_use_primary_orchestration(
&instruction,
task_context.page_url.as_deref(),
task_context.page_title.as_deref(),
)
{
let _ = send_mode_log(sink, "zeroclaw_process_message_primary");
match crate::compat::orchestration::execute_task_with_browser_backend(
sink,
browser_backend.clone(),
&instruction,
&task_context,
&context.workspace_root,
&settings,
) {
Ok(summary) => {
return sink.send(&AgentMessage::TaskComplete {
success: true,
summary,
});
}
Err(err) => {
return sink.send(&AgentMessage::TaskComplete {
success: false,
summary: err.to_string(),
});
}
}
}
if settings if settings
.direct_submit_skill .direct_submit_skill
.as_deref() .as_deref()
@@ -479,36 +509,6 @@ pub fn run_submit_task_with_browser_backend<T: Transport + 'static>(
} }
} }
} }
if RuntimeEngine::new(settings.runtime_profile).browser_surface_enabled()
&& crate::compat::orchestration::should_use_primary_orchestration(
&instruction,
task_context.page_url.as_deref(),
task_context.page_title.as_deref(),
)
{
let _ = send_mode_log(sink, "zeroclaw_process_message_primary");
match crate::compat::orchestration::execute_task_with_browser_backend(
sink,
browser_backend.clone(),
&instruction,
&task_context,
&context.workspace_root,
&settings,
) {
Ok(summary) => {
return sink.send(&AgentMessage::TaskComplete {
success: true,
summary,
});
}
Err(err) => {
return sink.send(&AgentMessage::TaskComplete {
success: false,
summary: err.to_string(),
});
}
}
}
let _ = send_mode_log(sink, "compat_llm_primary"); let _ = send_mode_log(sink, "compat_llm_primary");
match crate::compat::runtime::execute_task_with_browser_backend( match crate::compat::runtime::execute_task_with_browser_backend(
sink, sink,

View File

@@ -38,6 +38,7 @@ fn write_config(
model: &str, model: &str,
skills_dir: Option<&str>, skills_dir: Option<&str>,
browser_ws_url: Option<&str>, browser_ws_url: Option<&str>,
direct_submit_skill: Option<&str>,
) -> PathBuf { ) -> PathBuf {
let config_path = root.join("sgclaw_config.json"); let config_path = root.join("sgclaw_config.json");
let mut payload = json!({ let mut payload = json!({
@@ -52,6 +53,9 @@ fn write_config(
if let Some(browser_ws_url) = browser_ws_url { if let Some(browser_ws_url) = browser_ws_url {
payload["browserWsUrl"] = json!(browser_ws_url); payload["browserWsUrl"] = json!(browser_ws_url);
} }
if let Some(direct_submit_skill) = direct_submit_skill {
payload["directSubmitSkill"] = json!(direct_submit_skill);
}
fs::write(&config_path, serde_json::to_string_pretty(&payload).unwrap()).unwrap(); fs::write(&config_path, serde_json::to_string_pretty(&payload).unwrap()).unwrap();
config_path config_path
} }
@@ -726,6 +730,76 @@ fn direct_skill_mode_logs_direct_skill_primary() {
); );
} }
#[test]
fn production_submit_task_with_ws_and_direct_submit_config_routes_zhihu_before_direct_submit() {
let _guard = env_lock().lock().unwrap_or_else(|err| err.into_inner());
std::env::set_var("SGCLAW_DISABLE_POST_EXPORT_OPEN", "1");
std::env::remove_var("DEEPSEEK_API_KEY");
std::env::remove_var("DEEPSEEK_BASE_URL");
std::env::remove_var("DEEPSEEK_MODEL");
let workspace_root = temp_workspace_root();
let (ws_url, _frames, ws_handle) = start_browser_ws_server();
let config_path = write_config(
&workspace_root,
"deepseek-test-key",
"http://127.0.0.1:9",
"deepseek-chat",
Some(real_skill_lib_root().to_str().unwrap()),
Some(&ws_url),
Some("fault-details-report.collect_fault_details"),
);
let transport = Arc::new(MockTransport::new(vec![]));
let browser_tool = BrowserPipeTool::new(
transport.clone(),
test_policy(),
vec![1, 2, 3, 4, 5, 6, 7, 8],
)
.with_response_timeout(Duration::from_secs(1));
let runtime_context = AgentRuntimeContext::new(Some(config_path), workspace_root);
handle_browser_message_with_context(
transport.as_ref(),
&browser_tool,
&runtime_context,
BrowserMessage::SubmitTask {
instruction: "打开知乎热榜获取前10条数据并导出 Excel".to_string(),
conversation_id: String::new(),
messages: vec![],
page_url: String::new(),
page_title: String::new(),
},
)
.unwrap();
ws_handle.join().unwrap();
let sent = transport.sent_messages();
let mode_logs = direct_submit_mode_logs(&sent);
let completion = direct_submit_completion(&sent).expect("task completion");
assert!(
mode_logs
.iter()
.any(|mode| mode == "zeroclaw_process_message_primary"),
"expected orchestration mode log before direct submit: {sent:?}"
);
assert!(
!mode_logs.iter().any(|mode| mode == "direct_skill_primary"),
"unexpected direct submit mode log for zhihu ws submit: {sent:?}"
);
assert!(completion.0, "expected zhihu ws submit to succeed: {sent:?}");
assert!(
!completion
.1
.contains("direct submit skill requires page_url so expected_domain can be derived"),
"unexpected direct-submit page_url failure: {sent:?}"
);
std::env::remove_var("SGCLAW_DISABLE_POST_EXPORT_OPEN");
}
#[test] #[test]
fn production_submit_task_routes_zhihu_through_ws_backend_without_helper_bootstrap() { fn production_submit_task_routes_zhihu_through_ws_backend_without_helper_bootstrap() {
let _guard = env_lock().lock().unwrap_or_else(|err| err.into_inner()); let _guard = env_lock().lock().unwrap_or_else(|err| err.into_inner());
@@ -744,6 +818,7 @@ fn production_submit_task_routes_zhihu_through_ws_backend_without_helper_bootstr
"deepseek-chat", "deepseek-chat",
Some(real_skill_lib_root().to_str().unwrap()), Some(real_skill_lib_root().to_str().unwrap()),
Some(&ws_url), Some(&ws_url),
None,
); );
let transport = Arc::new(MockTransport::new(vec![])); let transport = Arc::new(MockTransport::new(vec![]));