fix(rebase): resolve PR #266 conflicts against latest main
This commit is contained in:
parent
34306e32d8
commit
2d6ec2fb71
7 changed files with 142 additions and 51 deletions
|
|
@ -113,6 +113,7 @@ async fn auto_compact_history(
|
||||||
let summary_raw = provider
|
let summary_raw = provider
|
||||||
.chat_with_system(Some(summarizer_system), &summarizer_user, model, 0.2)
|
.chat_with_system(Some(summarizer_system), &summarizer_user, model, 0.2)
|
||||||
.await
|
.await
|
||||||
|
.map(|resp| resp.text_or_empty().to_string())
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
// Fallback to deterministic local truncation when summarization fails.
|
// Fallback to deterministic local truncation when summarization fails.
|
||||||
truncate_with_ellipsis(&transcript, COMPACTION_MAX_SUMMARY_CHARS)
|
truncate_with_ellipsis(&transcript, COMPACTION_MAX_SUMMARY_CHARS)
|
||||||
|
|
|
||||||
|
|
@ -721,6 +721,7 @@ pub async fn start_channels(config: Config) -> Result<()> {
|
||||||
composio_key,
|
composio_key,
|
||||||
&config.browser,
|
&config.browser,
|
||||||
&config.http_request,
|
&config.http_request,
|
||||||
|
&config.workspace_dir,
|
||||||
&config.agents,
|
&config.agents,
|
||||||
config.api_key.as_deref(),
|
config.api_key.as_deref(),
|
||||||
));
|
));
|
||||||
|
|
@ -951,7 +952,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::memory::{Memory, MemoryCategory, SqliteMemory};
|
use crate::memory::{Memory, MemoryCategory, SqliteMemory};
|
||||||
use crate::observability::NoopObserver;
|
use crate::observability::NoopObserver;
|
||||||
use crate::providers::{ChatMessage, Provider};
|
use crate::providers::{ChatMessage, ChatResponse, Provider, ToolCall};
|
||||||
use crate::tools::{Tool, ToolResult};
|
use crate::tools::{Tool, ToolResult};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
@ -1018,27 +1019,23 @@ mod tests {
|
||||||
message: &str,
|
message: &str,
|
||||||
_model: &str,
|
_model: &str,
|
||||||
_temperature: f64,
|
_temperature: f64,
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<ChatResponse> {
|
||||||
tokio::time::sleep(self.delay).await;
|
tokio::time::sleep(self.delay).await;
|
||||||
Ok(format!("echo: {message}"))
|
Ok(ChatResponse::with_text(format!("echo: {message}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ToolCallingProvider;
|
struct ToolCallingProvider;
|
||||||
|
|
||||||
fn tool_call_payload() -> String {
|
fn tool_call_payload() -> ChatResponse {
|
||||||
serde_json::json!({
|
ChatResponse {
|
||||||
"content": "",
|
text: Some(String::new()),
|
||||||
"tool_calls": [{
|
tool_calls: vec![ToolCall {
|
||||||
"id": "call_1",
|
id: "call_1".into(),
|
||||||
"type": "function",
|
name: "mock_price".into(),
|
||||||
"function": {
|
arguments: r#"{"symbol":"BTC"}"#.into(),
|
||||||
"name": "mock_price",
|
}],
|
||||||
"arguments": "{\"symbol\":\"BTC\"}"
|
}
|
||||||
}
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
.to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
|
|
@ -1049,7 +1046,7 @@ mod tests {
|
||||||
_message: &str,
|
_message: &str,
|
||||||
_model: &str,
|
_model: &str,
|
||||||
_temperature: f64,
|
_temperature: f64,
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<ChatResponse> {
|
||||||
Ok(tool_call_payload())
|
Ok(tool_call_payload())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1058,12 +1055,14 @@ mod tests {
|
||||||
messages: &[ChatMessage],
|
messages: &[ChatMessage],
|
||||||
_model: &str,
|
_model: &str,
|
||||||
_temperature: f64,
|
_temperature: f64,
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<ChatResponse> {
|
||||||
let has_tool_results = messages
|
let has_tool_results = messages
|
||||||
.iter()
|
.iter()
|
||||||
.any(|msg| msg.role == "user" && msg.content.contains("[Tool results]"));
|
.any(|msg| msg.role == "user" && msg.content.contains("[Tool results]"));
|
||||||
if has_tool_results {
|
if has_tool_results {
|
||||||
Ok("BTC is currently around $65,000 based on latest tool output.".to_string())
|
Ok(ChatResponse::with_text(
|
||||||
|
"BTC is currently around $65,000 based on latest tool output.",
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(tool_call_payload())
|
Ok(tool_call_payload())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,10 @@ fn split_message_for_telegram(message: &str) -> Vec<String> {
|
||||||
pos + 1
|
pos + 1
|
||||||
} else {
|
} else {
|
||||||
// Try space as fallback
|
// Try space as fallback
|
||||||
search_area.rfind(' ').unwrap_or(TELEGRAM_MAX_MESSAGE_LENGTH) + 1
|
search_area
|
||||||
|
.rfind(' ')
|
||||||
|
.unwrap_or(TELEGRAM_MAX_MESSAGE_LENGTH)
|
||||||
|
+ 1
|
||||||
}
|
}
|
||||||
} else if let Some(pos) = search_area.rfind(' ') {
|
} else if let Some(pos) = search_area.rfind(' ') {
|
||||||
pos + 1
|
pos + 1
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,8 @@ async fn run_heartbeat_worker(config: Config) -> Result<()> {
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
let prompt = format!("[Heartbeat Task] {task}");
|
let prompt = format!("[Heartbeat Task] {task}");
|
||||||
let temp = config.default_temperature;
|
let temp = config.default_temperature;
|
||||||
if let Err(e) = crate::agent::run(config.clone(), Some(prompt), None, None, temp).await
|
if let Err(e) =
|
||||||
|
crate::agent::run(config.clone(), Some(prompt), None, None, temp, false).await
|
||||||
{
|
{
|
||||||
crate::health::mark_component_error("heartbeat", e.to_string());
|
crate::health::mark_component_error("heartbeat", e.to_string());
|
||||||
tracing::warn!("Heartbeat task failed: {e}");
|
tracing::warn!("Heartbeat task failed: {e}");
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ async fn gateway_agent_reply(state: &AppState, message: &str) -> Result<String>
|
||||||
&mut history,
|
&mut history,
|
||||||
state.tools_registry.as_ref(),
|
state.tools_registry.as_ref(),
|
||||||
state.observer.as_ref(),
|
state.observer.as_ref(),
|
||||||
|
"gateway",
|
||||||
&state.model,
|
&state.model,
|
||||||
state.temperature,
|
state.temperature,
|
||||||
)
|
)
|
||||||
|
|
@ -262,6 +263,8 @@ pub async fn run_gateway(host: &str, port: u16, config: Config) -> Result<()> {
|
||||||
Arc::clone(&mem),
|
Arc::clone(&mem),
|
||||||
composio_key,
|
composio_key,
|
||||||
&config.browser,
|
&config.browser,
|
||||||
|
&config.http_request,
|
||||||
|
&config.workspace_dir,
|
||||||
&config.agents,
|
&config.agents,
|
||||||
config.api_key.as_deref(),
|
config.api_key.as_deref(),
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@ pub struct GitOperationsTool {
|
||||||
|
|
||||||
impl GitOperationsTool {
|
impl GitOperationsTool {
|
||||||
pub fn new(security: Arc<SecurityPolicy>, workspace_dir: std::path::PathBuf) -> Self {
|
pub fn new(security: Arc<SecurityPolicy>, workspace_dir: std::path::PathBuf) -> Self {
|
||||||
Self { security, workspace_dir }
|
Self {
|
||||||
|
security,
|
||||||
|
workspace_dir,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sanitize git arguments to prevent injection attacks
|
/// Sanitize git arguments to prevent injection attacks
|
||||||
|
|
@ -48,7 +51,10 @@ impl GitOperationsTool {
|
||||||
|
|
||||||
/// Check if an operation is read-only
|
/// Check if an operation is read-only
|
||||||
fn is_read_only(&self, operation: &str) -> bool {
|
fn is_read_only(&self, operation: &str) -> bool {
|
||||||
matches!(operation, "status" | "diff" | "log" | "show" | "branch" | "rev-parse")
|
matches!(
|
||||||
|
operation,
|
||||||
|
"status" | "diff" | "log" | "show" | "branch" | "rev-parse"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_git_command(&self, args: &[&str]) -> anyhow::Result<String> {
|
async fn run_git_command(&self, args: &[&str]) -> anyhow::Result<String> {
|
||||||
|
|
@ -67,7 +73,9 @@ impl GitOperationsTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn git_status(&self, _args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_status(&self, _args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let output = self.run_git_command(&["status", "--porcelain=2", "--branch"]).await?;
|
let output = self
|
||||||
|
.run_git_command(&["status", "--porcelain=2", "--branch"])
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Parse git status output into structured format
|
// Parse git status output into structured format
|
||||||
let mut result = serde_json::Map::new();
|
let mut result = serde_json::Map::new();
|
||||||
|
|
@ -105,7 +113,10 @@ impl GitOperationsTool {
|
||||||
result.insert("staged".to_string(), json!(staged));
|
result.insert("staged".to_string(), json!(staged));
|
||||||
result.insert("unstaged".to_string(), json!(unstaged));
|
result.insert("unstaged".to_string(), json!(unstaged));
|
||||||
result.insert("untracked".to_string(), json!(untracked));
|
result.insert("untracked".to_string(), json!(untracked));
|
||||||
result.insert("clean".to_string(), json!(staged.is_empty() && unstaged.is_empty() && untracked.is_empty()));
|
result.insert(
|
||||||
|
"clean".to_string(),
|
||||||
|
json!(staged.is_empty() && unstaged.is_empty() && untracked.is_empty()),
|
||||||
|
);
|
||||||
|
|
||||||
Ok(ToolResult {
|
Ok(ToolResult {
|
||||||
success: true,
|
success: true,
|
||||||
|
|
@ -116,7 +127,10 @@ impl GitOperationsTool {
|
||||||
|
|
||||||
async fn git_diff(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_diff(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let files = args.get("files").and_then(|v| v.as_str()).unwrap_or(".");
|
let files = args.get("files").and_then(|v| v.as_str()).unwrap_or(".");
|
||||||
let cached = args.get("cached").and_then(|v| v.as_bool()).unwrap_or(false);
|
let cached = args
|
||||||
|
.get("cached")
|
||||||
|
.and_then(|v| v.as_bool())
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
let mut git_args = vec!["diff", "--unified=3"];
|
let mut git_args = vec!["diff", "--unified=3"];
|
||||||
if cached {
|
if cached {
|
||||||
|
|
@ -191,12 +205,14 @@ impl GitOperationsTool {
|
||||||
let limit = args.get("limit").and_then(|v| v.as_u64()).unwrap_or(10) as usize;
|
let limit = args.get("limit").and_then(|v| v.as_u64()).unwrap_or(10) as usize;
|
||||||
let limit_str = limit.to_string();
|
let limit_str = limit.to_string();
|
||||||
|
|
||||||
let output = self.run_git_command(&[
|
let output = self
|
||||||
"log",
|
.run_git_command(&[
|
||||||
&format!("-{limit_str}"),
|
"log",
|
||||||
"--pretty=format:%H|%an|%ae|%ad|%s",
|
&format!("-{limit_str}"),
|
||||||
"--date=iso",
|
"--pretty=format:%H|%an|%ae|%ad|%s",
|
||||||
]).await?;
|
"--date=iso",
|
||||||
|
])
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut commits = Vec::new();
|
let mut commits = Vec::new();
|
||||||
|
|
||||||
|
|
@ -215,13 +231,16 @@ impl GitOperationsTool {
|
||||||
|
|
||||||
Ok(ToolResult {
|
Ok(ToolResult {
|
||||||
success: true,
|
success: true,
|
||||||
output: serde_json::to_string_pretty(&json!({ "commits": commits })).unwrap_or_default(),
|
output: serde_json::to_string_pretty(&json!({ "commits": commits }))
|
||||||
|
.unwrap_or_default(),
|
||||||
error: None,
|
error: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn git_branch(&self, _args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_branch(&self, _args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let output = self.run_git_command(&["branch", "--format=%(refname:short)|%(HEAD)"]).await?;
|
let output = self
|
||||||
|
.run_git_command(&["branch", "--format=%(refname:short)|%(HEAD)"])
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut branches = Vec::new();
|
let mut branches = Vec::new();
|
||||||
let mut current = String::new();
|
let mut current = String::new();
|
||||||
|
|
@ -244,18 +263,21 @@ impl GitOperationsTool {
|
||||||
output: serde_json::to_string_pretty(&json!({
|
output: serde_json::to_string_pretty(&json!({
|
||||||
"current": current,
|
"current": current,
|
||||||
"branches": branches
|
"branches": branches
|
||||||
})).unwrap_or_default(),
|
}))
|
||||||
|
.unwrap_or_default(),
|
||||||
error: None,
|
error: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn git_commit(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_commit(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let message = args.get("message")
|
let message = args
|
||||||
|
.get("message")
|
||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing 'message' parameter"))?;
|
.ok_or_else(|| anyhow::anyhow!("Missing 'message' parameter"))?;
|
||||||
|
|
||||||
// Sanitize commit message
|
// Sanitize commit message
|
||||||
let sanitized = message.lines()
|
let sanitized = message
|
||||||
|
.lines()
|
||||||
.map(|l| l.trim())
|
.map(|l| l.trim())
|
||||||
.filter(|l| !l.is_empty())
|
.filter(|l| !l.is_empty())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
|
@ -289,7 +311,8 @@ impl GitOperationsTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn git_add(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_add(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let paths = args.get("paths")
|
let paths = args
|
||||||
|
.get("paths")
|
||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing 'paths' parameter"))?;
|
.ok_or_else(|| anyhow::anyhow!("Missing 'paths' parameter"))?;
|
||||||
|
|
||||||
|
|
@ -310,7 +333,8 @@ impl GitOperationsTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn git_checkout(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_checkout(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let branch = args.get("branch")
|
let branch = args
|
||||||
|
.get("branch")
|
||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing 'branch' parameter"))?;
|
.ok_or_else(|| anyhow::anyhow!("Missing 'branch' parameter"))?;
|
||||||
|
|
||||||
|
|
@ -345,15 +369,22 @@ impl GitOperationsTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn git_stash(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
async fn git_stash(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||||
let action = args.get("action").and_then(|v| v.as_str()).unwrap_or("push");
|
let action = args
|
||||||
|
.get("action")
|
||||||
|
.and_then(|v| v.as_str())
|
||||||
|
.unwrap_or("push");
|
||||||
|
|
||||||
let output = match action {
|
let output = match action {
|
||||||
"push" | "save" => self.run_git_command(&["stash", "push", "-m", "auto-stash"]).await,
|
"push" | "save" => {
|
||||||
|
self.run_git_command(&["stash", "push", "-m", "auto-stash"])
|
||||||
|
.await
|
||||||
|
}
|
||||||
"pop" => self.run_git_command(&["stash", "pop"]).await,
|
"pop" => self.run_git_command(&["stash", "pop"]).await,
|
||||||
"list" => self.run_git_command(&["stash", "list"]).await,
|
"list" => self.run_git_command(&["stash", "list"]).await,
|
||||||
"drop" => {
|
"drop" => {
|
||||||
let index = args.get("index").and_then(|v| v.as_u64()).unwrap_or(0) as i32;
|
let index = args.get("index").and_then(|v| v.as_u64()).unwrap_or(0) as i32;
|
||||||
self.run_git_command(&["stash", "drop", &format!("stash@{{{index}}}")]).await
|
self.run_git_command(&["stash", "drop", &format!("stash@{{{index}}}")])
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
_ => anyhow::bail!("Unknown stash action: {action}. Use: push, pop, list, drop"),
|
_ => anyhow::bail!("Unknown stash action: {action}. Use: push, pop, list, drop"),
|
||||||
};
|
};
|
||||||
|
|
@ -470,7 +501,9 @@ impl Tool for GitOperationsTool {
|
||||||
return Ok(ToolResult {
|
return Ok(ToolResult {
|
||||||
success: false,
|
success: false,
|
||||||
output: String::new(),
|
output: String::new(),
|
||||||
error: Some("Action blocked: git write operations require higher autonomy level".into()),
|
error: Some(
|
||||||
|
"Action blocked: git write operations require higher autonomy level".into(),
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -606,7 +639,11 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!result.success);
|
assert!(!result.success);
|
||||||
// can_act() returns false for ReadOnly, so we get the "higher autonomy level" message
|
// can_act() returns false for ReadOnly, so we get the "higher autonomy level" message
|
||||||
assert!(result.error.as_deref().unwrap_or("").contains("higher autonomy"));
|
assert!(result
|
||||||
|
.error
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or("")
|
||||||
|
.contains("higher autonomy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
@ -632,7 +669,11 @@ mod tests {
|
||||||
|
|
||||||
let result = tool.execute(json!({})).await.unwrap();
|
let result = tool.execute(json!({})).await.unwrap();
|
||||||
assert!(!result.success);
|
assert!(!result.success);
|
||||||
assert!(result.error.as_deref().unwrap_or("").contains("Missing 'operation'"));
|
assert!(result
|
||||||
|
.error
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or("")
|
||||||
|
.contains("Missing 'operation'"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
@ -649,6 +690,10 @@ mod tests {
|
||||||
|
|
||||||
let result = tool.execute(json!({"operation": "push"})).await.unwrap();
|
let result = tool.execute(json!({"operation": "push"})).await.unwrap();
|
||||||
assert!(!result.success);
|
assert!(!result.success);
|
||||||
assert!(result.error.as_deref().unwrap_or("").contains("Unknown operation"));
|
assert!(result
|
||||||
|
.error
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or("")
|
||||||
|
.contains("Unknown operation"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,10 @@ pub fn all_tools_with_runtime(
|
||||||
Box::new(MemoryStoreTool::new(memory.clone())),
|
Box::new(MemoryStoreTool::new(memory.clone())),
|
||||||
Box::new(MemoryRecallTool::new(memory.clone())),
|
Box::new(MemoryRecallTool::new(memory.clone())),
|
||||||
Box::new(MemoryForgetTool::new(memory)),
|
Box::new(MemoryForgetTool::new(memory)),
|
||||||
Box::new(GitOperationsTool::new(security.clone(), workspace_dir.to_path_buf())),
|
Box::new(GitOperationsTool::new(
|
||||||
|
security.clone(),
|
||||||
|
workspace_dir.to_path_buf(),
|
||||||
|
)),
|
||||||
];
|
];
|
||||||
|
|
||||||
if browser_config.enabled {
|
if browser_config.enabled {
|
||||||
|
|
@ -184,7 +187,16 @@ mod tests {
|
||||||
};
|
};
|
||||||
let http = crate::config::HttpRequestConfig::default();
|
let http = crate::config::HttpRequestConfig::default();
|
||||||
|
|
||||||
let tools = all_tools(&security, mem, None, &browser, &http, tmp.path(), &HashMap::new(), None);
|
let tools = all_tools(
|
||||||
|
&security,
|
||||||
|
mem,
|
||||||
|
None,
|
||||||
|
&browser,
|
||||||
|
&http,
|
||||||
|
tmp.path(),
|
||||||
|
&HashMap::new(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
||||||
assert!(!names.contains(&"browser_open"));
|
assert!(!names.contains(&"browser_open"));
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +220,16 @@ mod tests {
|
||||||
};
|
};
|
||||||
let http = crate::config::HttpRequestConfig::default();
|
let http = crate::config::HttpRequestConfig::default();
|
||||||
|
|
||||||
let tools = all_tools(&security, mem, None, &browser, &http, tmp.path(), &HashMap::new(), None);
|
let tools = all_tools(
|
||||||
|
&security,
|
||||||
|
mem,
|
||||||
|
None,
|
||||||
|
&browser,
|
||||||
|
&http,
|
||||||
|
tmp.path(),
|
||||||
|
&HashMap::new(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
||||||
assert!(names.contains(&"browser_open"));
|
assert!(names.contains(&"browser_open"));
|
||||||
}
|
}
|
||||||
|
|
@ -334,7 +355,16 @@ mod tests {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let tools = all_tools(&security, mem, None, &browser, &http, tmp.path(), &agents, Some("sk-test"));
|
let tools = all_tools(
|
||||||
|
&security,
|
||||||
|
mem,
|
||||||
|
None,
|
||||||
|
&browser,
|
||||||
|
&http,
|
||||||
|
tmp.path(),
|
||||||
|
&agents,
|
||||||
|
Some("sk-test"),
|
||||||
|
);
|
||||||
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
||||||
assert!(names.contains(&"delegate"));
|
assert!(names.contains(&"delegate"));
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +383,16 @@ mod tests {
|
||||||
let browser = BrowserConfig::default();
|
let browser = BrowserConfig::default();
|
||||||
let http = crate::config::HttpRequestConfig::default();
|
let http = crate::config::HttpRequestConfig::default();
|
||||||
|
|
||||||
let tools = all_tools(&security, mem, None, &browser, &http, tmp.path(), &HashMap::new(), None);
|
let tools = all_tools(
|
||||||
|
&security,
|
||||||
|
mem,
|
||||||
|
None,
|
||||||
|
&browser,
|
||||||
|
&http,
|
||||||
|
tmp.path(),
|
||||||
|
&HashMap::new(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
let names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
|
||||||
assert!(!names.contains(&"delegate"));
|
assert!(!names.contains(&"delegate"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue