feat: restore zhihu browser skills

Reconnect the recovered Zhihu skill flows to the live browser runtime and resolve their resources relative to the executable so they work outside the repo root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
木炎
2026-03-27 14:29:38 +08:00
parent b87968632a
commit 6aad2ce48e
32 changed files with 7607 additions and 146 deletions

View File

@@ -3,7 +3,7 @@ mod common;
use std::fs;
use std::io::{Read, Write};
use std::net::TcpListener;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, OnceLock};
use std::thread;
use std::time::Duration;
@@ -11,9 +11,7 @@ use std::time::Duration;
use common::MockTransport;
use serde_json::{json, Value};
use sgclaw::agent::{
handle_browser_message,
handle_browser_message_with_context,
AgentRuntimeContext,
handle_browser_message, handle_browser_message_with_context, AgentRuntimeContext,
};
use sgclaw::compat::runtime::{execute_task, CompatTaskContext};
use sgclaw::config::DeepSeekSettings;
@@ -48,7 +46,7 @@ fn temp_workspace_root() -> PathBuf {
root
}
fn write_deepseek_config(root: &PathBuf, api_key: &str, base_url: &str, model: &str) -> PathBuf {
fn write_deepseek_config(root: &Path, api_key: &str, base_url: &str, model: &str) -> PathBuf {
let config_path = root.join("sgclaw_config.json");
fs::write(
&config_path,
@@ -94,7 +92,7 @@ fn start_fake_deepseek_server(
let payload = response.to_string();
let reply = format!(
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
payload.as_bytes().len(),
payload.len(),
payload
);
stream.write_all(reply.as_bytes()).unwrap();
@@ -281,7 +279,8 @@ fn compat_runtime_uses_zeroclaw_provider_path_and_executes_browser_actions() {
}
#[test]
fn handle_browser_message_prefers_compat_runtime_for_supported_instruction_when_deepseek_is_configured() {
fn handle_browser_message_prefers_compat_runtime_for_supported_instruction_when_deepseek_is_configured(
) {
let _guard = env_lock().lock().unwrap_or_else(|err| err.into_inner());
let first_response = json!({
@@ -643,11 +642,9 @@ fn compat_runtime_includes_prior_turns_in_follow_up_provider_request() {
assert_eq!(summary, "已在知乎搜索天气");
assert!(first_request_messages.iter().any(|message| {
message["role"] == json!("user")
&& message["content"] == json!("打开百度搜索天气")
message["role"] == json!("user") && message["content"] == json!("打开百度搜索天气")
}));
assert!(first_request_messages.iter().any(|message| {
message["role"] == json!("assistant")
&& message["content"] == json!("已在百度搜索天气")
message["role"] == json!("assistant") && message["content"] == json!("已在百度搜索天气")
}));
}