sgclaw: snapshot today's runtime and skill updates
This commit is contained in:
20
third_party/zeroclaw/src/agent/agent.rs
vendored
20
third_party/zeroclaw/src/agent/agent.rs
vendored
@@ -796,7 +796,8 @@ impl Agent {
|
||||
|
||||
let (text, calls) = self.tool_dispatcher.parse_response(&response);
|
||||
let calls = canonicalize_parsed_tool_calls(&self.tools, calls);
|
||||
response.tool_calls = canonicalize_provider_tool_calls(&self.tools, response.tool_calls);
|
||||
response.tool_calls =
|
||||
canonicalize_provider_tool_calls(&self.tools, response.tool_calls);
|
||||
if calls.is_empty() {
|
||||
let final_text = if text.is_empty() {
|
||||
response.text.unwrap_or_default()
|
||||
@@ -1065,7 +1066,8 @@ impl Agent {
|
||||
|
||||
let (text, calls) = self.tool_dispatcher.parse_response(&response);
|
||||
let calls = canonicalize_parsed_tool_calls(&self.tools, calls);
|
||||
response.tool_calls = canonicalize_provider_tool_calls(&self.tools, response.tool_calls);
|
||||
response.tool_calls =
|
||||
canonicalize_provider_tool_calls(&self.tools, response.tool_calls);
|
||||
if calls.is_empty() {
|
||||
let final_text = if text.is_empty() {
|
||||
response.text.unwrap_or_default()
|
||||
@@ -1207,7 +1209,8 @@ fn sanitize_final_text(text: &str) -> String {
|
||||
}
|
||||
|
||||
fn resolve_registered_tool_name(tools: &[Box<dyn Tool>], raw: &str) -> Option<String> {
|
||||
tools.iter()
|
||||
tools
|
||||
.iter()
|
||||
.find(|tool| {
|
||||
tool.name() == raw || crate::tools::provider_safe_tool_name(tool.name()) == raw
|
||||
})
|
||||
@@ -1218,7 +1221,8 @@ fn canonicalize_parsed_tool_calls(
|
||||
tools: &[Box<dyn Tool>],
|
||||
calls: Vec<ParsedToolCall>,
|
||||
) -> Vec<ParsedToolCall> {
|
||||
calls.into_iter()
|
||||
calls
|
||||
.into_iter()
|
||||
.map(|mut call| {
|
||||
if let Some(canonical_name) = resolve_registered_tool_name(tools, &call.name) {
|
||||
call.name = canonical_name;
|
||||
@@ -1232,7 +1236,8 @@ fn canonicalize_provider_tool_calls(
|
||||
tools: &[Box<dyn Tool>],
|
||||
calls: Vec<crate::providers::ToolCall>,
|
||||
) -> Vec<crate::providers::ToolCall> {
|
||||
calls.into_iter()
|
||||
calls
|
||||
.into_iter()
|
||||
.map(|mut call| {
|
||||
if let Some(canonical_name) = resolve_registered_tool_name(tools, &call.name) {
|
||||
call.name = canonical_name;
|
||||
@@ -1656,7 +1661,10 @@ mod tests {
|
||||
.expect("agent builder should succeed with valid config");
|
||||
|
||||
let (event_tx, _event_rx) = tokio::sync::mpsc::channel(8);
|
||||
let response = agent.turn_streamed("读取知乎热榜前10,并导出 excel 文件", event_tx).await.unwrap();
|
||||
let response = agent
|
||||
.turn_streamed("读取知乎热榜前10,并导出 excel 文件", event_tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
|
||||
3
third_party/zeroclaw/src/lib.rs
vendored
3
third_party/zeroclaw/src/lib.rs
vendored
@@ -71,7 +71,7 @@ pub mod routines;
|
||||
pub mod runtime;
|
||||
pub(crate) mod security;
|
||||
pub(crate) mod service;
|
||||
pub(crate) mod skills;
|
||||
pub mod skills;
|
||||
pub mod sop;
|
||||
pub mod tools;
|
||||
pub(crate) mod trust;
|
||||
@@ -83,6 +83,7 @@ pub mod verifiable_intent;
|
||||
pub mod plugins;
|
||||
|
||||
pub use config::Config;
|
||||
pub use security::{AutonomyLevel, SecurityPolicy};
|
||||
|
||||
/// Gateway management subcommands
|
||||
#[derive(Subcommand, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
||||
10
third_party/zeroclaw/src/providers/compatible.rs
vendored
10
third_party/zeroclaw/src/providers/compatible.rs
vendored
@@ -1943,9 +1943,8 @@ impl Provider for OpenAiCompatibleProvider {
|
||||
reasoning_effort: self.reasoning_effort_for_model(model),
|
||||
tool_stream: self
|
||||
.tool_stream_for_tools(tools.as_ref().is_some_and(|tools| !tools.is_empty())),
|
||||
tool_choice: self.tool_choice_for_tools(
|
||||
tools.as_ref().is_some_and(|tools| !tools.is_empty()),
|
||||
),
|
||||
tool_choice: self
|
||||
.tool_choice_for_tools(tools.as_ref().is_some_and(|tools| !tools.is_empty())),
|
||||
tools,
|
||||
max_tokens: self.max_tokens,
|
||||
};
|
||||
@@ -2099,9 +2098,8 @@ impl Provider for OpenAiCompatibleProvider {
|
||||
tool_stream: if options.enabled { Some(true) } else { None },
|
||||
stream: Some(options.enabled),
|
||||
tools: tools.clone(),
|
||||
tool_choice: self.tool_choice_for_tools(
|
||||
tools.as_ref().is_some_and(|tools| !tools.is_empty()),
|
||||
),
|
||||
tool_choice: self
|
||||
.tool_choice_for_tools(tools.as_ref().is_some_and(|tools| !tools.is_empty())),
|
||||
max_tokens: self.max_tokens,
|
||||
})
|
||||
} else {
|
||||
|
||||
14
third_party/zeroclaw/src/skills/mod.rs
vendored
14
third_party/zeroclaw/src/skills/mod.rs
vendored
@@ -816,12 +816,22 @@ pub fn skills_to_prompt_with_mode(
|
||||
let registered: Vec<_> = skill
|
||||
.tools
|
||||
.iter()
|
||||
.filter(|t| matches!(t.kind.as_str(), "shell" | "script" | "http" | "browser_script"))
|
||||
.filter(|t| {
|
||||
matches!(
|
||||
t.kind.as_str(),
|
||||
"shell" | "script" | "http" | "browser_script"
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let unregistered: Vec<_> = skill
|
||||
.tools
|
||||
.iter()
|
||||
.filter(|t| !matches!(t.kind.as_str(), "shell" | "script" | "http" | "browser_script"))
|
||||
.filter(|t| {
|
||||
!matches!(
|
||||
t.kind.as_str(),
|
||||
"shell" | "script" | "http" | "browser_script"
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if !registered.is_empty() {
|
||||
|
||||
34
third_party/zeroclaw/src/tools/read_skill.rs
vendored
34
third_party/zeroclaw/src/tools/read_skill.rs
vendored
@@ -154,7 +154,9 @@ pub async fn read_skill_bundle(location: &Path) -> std::io::Result<String> {
|
||||
let Some(skill_root) = location.parent() else {
|
||||
return Ok(primary);
|
||||
};
|
||||
let skill_root = skill_root.canonicalize().unwrap_or_else(|_| skill_root.to_path_buf());
|
||||
let skill_root = skill_root
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| skill_root.to_path_buf());
|
||||
let mut output = primary.clone();
|
||||
let mut appended = BTreeSet::new();
|
||||
let mut queued = BTreeSet::new();
|
||||
@@ -275,16 +277,22 @@ fn extract_reference_paths(content: &str) -> Vec<String> {
|
||||
}
|
||||
|
||||
fn looks_like_relative_reference_path(raw: &str) -> bool {
|
||||
if raw.is_empty() ||
|
||||
raw.starts_with('/') ||
|
||||
raw.starts_with("http://") ||
|
||||
raw.starts_with("https://") ||
|
||||
raw.starts_with('#')
|
||||
if raw.is_empty()
|
||||
|| raw.starts_with('/')
|
||||
|| raw.starts_with("http://")
|
||||
|| raw.starts_with("https://")
|
||||
|| raw.starts_with('#')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let candidate = raw.split('#').next().unwrap_or(raw).split('?').next().unwrap_or(raw);
|
||||
let candidate = raw
|
||||
.split('#')
|
||||
.next()
|
||||
.unwrap_or(raw)
|
||||
.split('?')
|
||||
.next()
|
||||
.unwrap_or(raw);
|
||||
let path = Path::new(candidate);
|
||||
if path
|
||||
.components()
|
||||
@@ -418,9 +426,15 @@ description = "Ship safely"
|
||||
|
||||
assert!(result.success);
|
||||
assert!(result.output.contains("# Zhihu Hotlist"));
|
||||
assert!(result.output.contains("## Referenced File: references/collection-flow.md"));
|
||||
assert!(result.output.contains("Collect rows from the hotlist first."));
|
||||
assert!(result.output.contains("## Referenced File: references/data-quality.md"));
|
||||
assert!(result
|
||||
.output
|
||||
.contains("## Referenced File: references/collection-flow.md"));
|
||||
assert!(result
|
||||
.output
|
||||
.contains("Collect rows from the hotlist first."));
|
||||
assert!(result
|
||||
.output
|
||||
.contains("## Referenced File: references/data-quality.md"));
|
||||
assert!(result.output.contains("Mark partial metrics explicitly."));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user