Refactor tool execution pipeline

This commit is contained in:
2026-06-21 14:30:40 +08:00
parent 3e5f0658b3
commit 99c1e9cd6c
81 changed files with 3587 additions and 5317 deletions
+105
View File
@@ -0,0 +1,105 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "amap"
version = "0.1.0"
dependencies = [
"serde_json",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "amap"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "amap"
path = "src/main.rs"
[dependencies]
serde_json = "1.0"
+17
View File
@@ -0,0 +1,17 @@
name: amap_geocode
desc: 将文字地址转换为经纬度坐标。输入地址名称返回坐标。用于"天安门的坐标是什么"等需要将地名转为坐标的场景,通常作为其他地图工具的前置步骤
type: http
tool: amap
command: geocode
path: /target/release/amap
risk_level: low
timeout_secs: 15
env:
- AMAP_KEY
params:
- name: address
required: true
desc: 详细地址名称,如"北京市朝阳区天安门"、"合肥火车站"。越详细越精确
- name: city
required: false
desc: 城市名称,可选。限定地理编码的城市范围
+14
View File
@@ -0,0 +1,14 @@
name: amap_map_link
desc: 生成高德地图可视化链接。输入中心点坐标返回可分享的地图标记链接。用于"把这个位置发给我"等需要可视化展示的场景
type: http
tool: amap
command: map_link
path: /target/release/amap
risk_level: low
timeout_secs: 15
env:
- AMAP_KEY
params:
- name: center
required: false
desc: 地图中心点经纬度坐标,格式"经度,纬度",默认天安门坐标
@@ -0,0 +1,20 @@
name: amap_poi_search
desc: 搜索指定城市内的POI地点(餐饮、酒店、景点、商场、加油站、银行等)。返回名称和地址。用于"附近有什么好吃的""北京有什么景点"等问题
type: http
tool: amap
command: poi_search
path: /target/release/amap
risk_level: low
timeout_secs: 15
env:
- AMAP_KEY
params:
- name: keywords
required: true
desc: 搜索关键词,如"咖啡厅"、"银行"、"加油站"。支持POI类型名称
- name: city
required: false
desc: 城市名称,限定搜索范围。不填则在当前城市搜索
- name: radius
required: false
desc: 搜索半径(米),如 500、1000、3000。默认 1000 米
@@ -0,0 +1,14 @@
name: amap_reverse_geocode
desc: 将经纬度坐标转换为详细文字地址。输入"经度,纬度"返回结构化地址。用于"这个坐标是哪里"等反向查询
type: http
tool: amap
command: reverse_geocode
path: /target/release/amap
risk_level: low
timeout_secs: 15
env:
- AMAP_KEY
params:
- name: location
required: true
desc: 经纬度坐标,格式为"经度,纬度",如"116.397,39.908"
@@ -0,0 +1,20 @@
name: amap_route_plan
desc: 规划两点之间的出行路线。支持驾车(driving)、步行(walking)、骑行(riding)、公交(transit)四种方式。返回距离和预计耗时。用于"从家到公司怎么走""走过去要多久"等问题
type: http
tool: amap
command: route_plan
path: /target/release/amap
risk_level: low
timeout_secs: 15
env:
- AMAP_KEY
params:
- name: origin
required: true
desc: 起点经纬度坐标,格式"经度,纬度"。可先用 amap_geocode 将地名转为坐标
- name: destination
required: true
desc: 终点经纬度坐标,格式"经度,纬度"。可先用 amap_geocode 将地名转为坐标
- name: type
required: false
desc: 出行方式:driving(驾车)、walking(步行)、riding(骑行)、transit(公交)。默认 driving
@@ -0,0 +1,17 @@
name: amap_travel_plan
desc: 为指定城市生成旅游规划。自动搜索城市内的热门景点、美食、住宿等POI。用于"北京三日游怎么安排""合肥有什么好玩的"等旅游咨询
type: http
tool: amap
command: travel_plan
path: /target/release/amap
risk_level: low
timeout_secs: 15
env:
- AMAP_KEY
params:
- name: city
required: true
desc: 目标城市名称,如"北京"、"杭州"、"成都"
- name: interests
required: false
desc: 感兴趣的关键词,逗号分隔,如"景点,美食,酒店"。默认"景点,美食"
+50
View File
@@ -0,0 +1,50 @@
fn main() {
let input: serde_json::Value = serde_json::from_reader(std::io::stdin()).unwrap();
let mode = std::env::args().nth(2).unwrap_or_default();
let p = &input["params"];
let key = match std::env::var("AMAP_KEY") {
Ok(k) if !k.is_empty() => k,
_ => {
println!(r#"{{"type":"result","content":"错误: 缺少环境变量 AMAP_KEY(高德地图 API Key),请在 .env 中设置"}}"#);
return;
}
};
if input.get("response").is_none() && input.get("db_response").is_none() {
let (url, desc) = match mode.as_str() {
"poi_search" => (format!("https://restapi.amap.com/v5/place/text?keywords={}&city={}&key={key}",
p["keywords"].as_str().unwrap_or(""), p["city"].as_str().unwrap_or("")), format!("搜索: {}", p["keywords"].as_str().unwrap_or(""))),
"geocode" => (format!("https://restapi.amap.com/v3/geocode/geo?address={}&city={}&key={key}",
p["address"].as_str().unwrap_or(""), p["city"].as_str().unwrap_or("")), format!("编码: {}", p["address"].as_str().unwrap_or(""))),
"reverse_geocode" => (format!("https://restapi.amap.com/v3/geocode/regeo?location={}&key={key}",
p["location"].as_str().unwrap_or("")), "逆编码".into()),
"route_plan" => (format!("https://restapi.amap.com/v5/direction/{}?origin={}&destination={}&key={key}",
p["type"].as_str().unwrap_or("driving"), p["origin"].as_str().unwrap_or(""), p["destination"].as_str().unwrap_or("")), "路径规划".into()),
"travel_plan" => (format!("https://restapi.amap.com/v5/place/text?keywords={}&city={}&key={key}",
p["interests"].as_str().unwrap_or(""), p["city"].as_str().unwrap_or("")), format!("旅游: {}", p["city"].as_str().unwrap_or(""))),
"map_link" => (format!("https://uri.amap.com/marker?position={}",
p["center"].as_str().unwrap_or("116.397,39.908")), "地图链接".into()),
_ => { println!(r#"{{"type":"result","content":"未知模式"}}"#); return; }
};
println!("{}", serde_json::json!({"type":"http","method":"GET","url":url,"desc":desc}));
} else {
let b = &input["response"]["body"];
let content = match mode.as_str() {
"poi_search"|"travel_plan" => {
let n = b["pois"].as_array().map(|a| a.len()).unwrap_or(0);
let items: Vec<String> = b["pois"].as_array().unwrap_or(&vec![]).iter().take(5)
.map(|x| format!("{} ({})", x["name"].as_str().unwrap_or(""), x["address"].as_str().unwrap_or(""))).collect();
format!("找到 {n} 个:\n{}", items.join("\n"))
}
"geocode" => {
let empty = vec![]; let g = b["geocodes"].as_array().unwrap_or(&empty);
g.first().map(|x| format!("{}{}", x["formatted_address"].as_str().unwrap_or(""), x["location"].as_str().unwrap_or(""))).unwrap_or("未找到".into())
}
"reverse_geocode" => b["regeocode"]["formatted_address"].as_str().unwrap_or("未找到").into(),
"route_plan" => format!("距离: {}m, 耗时: {}s", b["route"]["distance"].as_str().unwrap_or("?"), b["route"]["duration"].as_str().unwrap_or("?")),
"map_link" => "地图链接已生成".into(),
_ => format!("{b}"),
};
println!("{}", serde_json::json!({"type":"result","content":content}));
}
}
Executable
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# 构建所有工具
set -e
cd "$(dirname "$0")"
TOOLS=(datetime weather amap web_search fetch_page memories)
echo "=== 构建工具 ==="
for tool in "${TOOLS[@]}"; do
echo " $tool..."
(cd "$tool" && cargo build --release --quiet)
done
echo "=== 完成 ==="
for tool in "${TOOLS[@]}"; do
ls -lh "$tool/target/release/$tool" 2>/dev/null
done
+382
View File
@@ -0,0 +1,382 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "bumpalo"
version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "cc"
version = "1.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "datetime"
version = "0.1.0"
dependencies = [
"chrono",
"serde_json",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "futures-core"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"slab",
]
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
dependencies = [
"cfg-if",
"futures-util",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "log"
version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasm-bindgen"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
dependencies = [
"unicode-ident",
]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "datetime"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "datetime"
path = "src/main.rs"
[dependencies]
chrono = "0.4"
serde_json = "1.0"
@@ -0,0 +1,8 @@
name: get_current_datetime
desc: 获取当前系统本地日期时间,返回年月日、星期、时区。用于"现在几点""今天几号""星期几"等问题
type: stdio
tool: datetime
path: /target/release/datetime
risk_level: low
timeout_secs: 3
params: []
+14
View File
@@ -0,0 +1,14 @@
//! datetime — 本地时间
use chrono::Local;
fn main() {
let _ = std::io::stdin().read_line(&mut String::new());
let now = Local::now();
let out = serde_json::json!({
"type": "result",
"content": format!("当前时间: {}\n星期: {}\n时区: {}",
now.format("%Y-%m-%d %H:%M:%S"), now.format("%A"), now.offset())
});
println!("{out}");
}
+105
View File
@@ -0,0 +1,105 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "fetch_page"
version = "0.1.0"
dependencies = [
"serde_json",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "fetch_page"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "fetch_page"
path = "src/main.rs"
[dependencies]
serde_json = "1.0"
@@ -0,0 +1,11 @@
name: fetch_page
desc: 抓取指定URL网页并自动提取纯文本正文内容,过滤广告、导航、脚本等无关元素。返回最多30行文本。用于"帮我看看这个网页说了什么"等需要阅读网页内容的场景
type: http
tool: fetch_page
path: /target/release/fetch_page
risk_level: low
timeout_secs: 30
params:
- name: url
required: true
desc: 网页URL
+15
View File
@@ -0,0 +1,15 @@
fn main() {
let input: serde_json::Value = serde_json::from_reader(std::io::stdin()).unwrap();
if input.get("response").is_none() && input.get("db_response").is_none() {
let url = input["params"]["url"].as_str().unwrap_or("");
if url.is_empty() { println!(r#"{{"type":"result","content":"缺少url"}}"#); return; }
println!("{}", serde_json::json!({"type":"http","method":"GET","url":url,"desc":format!("抓取 {url}")}));
} else {
let html = input["response"]["body"].as_str().unwrap_or("");
let mut r = String::new(); let mut tag = false;
for c in html.chars() { if c=='<' { tag=true; } else if c=='>' { tag=false; } else if !tag { r.push(c); } }
let text = r.replace("&nbsp;"," ").replace("&lt;","<").replace("&gt;",">").replace("&amp;","&");
let lines: Vec<&str> = text.lines().filter(|l| !l.trim().is_empty()).take(30).collect();
println!("{}", serde_json::json!({"type":"result","content":lines.join("\n")}));
}
}
+219
View File
@@ -0,0 +1,219 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "dirs"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys",
]
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libredox"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "memories"
version = "0.1.0"
dependencies = [
"dirs",
"serde",
"serde_json",
]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "memories"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "memories"
path = "src/main.rs"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dirs = "6.0"
@@ -0,0 +1,14 @@
name: delete_memory
desc: 按ID删除指定的长期记忆。用于"忘记我住哪里""删除那条记录"等清除记忆的请求
type: stdio
tool: memories
command: delete
path: /target/release/memories
risk_level: high
timeout_secs: 5
env:
- IAS_MEMORY_DIR
params:
- name: memory_id
required: true
desc: 记忆ID
+14
View File
@@ -0,0 +1,14 @@
name: get_memory
desc: 按ID查看指定的单条记忆详情。用于需要确认某条具体记忆内容的场景
type: stdio
tool: memories
command: get
path: /target/release/memories
risk_level: low
timeout_secs: 3
env:
- IAS_MEMORY_DIR
params:
- name: memory_id
required: true
desc: 记忆的数字ID,从 read_memories 返回结果中获取
@@ -0,0 +1,11 @@
name: read_memories
desc: 读取用户的所有长期记忆。返回之前记录的个人偏好、习惯、重要信息等。用于"你还记得我住哪吗""我之前说过喜欢什么"等回忆类问题
type: stdio
tool: memories
command: list
path: /target/release/memories
risk_level: low
timeout_secs: 3
env:
- IAS_MEMORY_DIR
params:
@@ -0,0 +1,17 @@
name: update_memory
desc: 按ID更新指定记忆的内容。用于"我搬家了,更新地址""把我名字改成XX"等修改记忆的请求
type: stdio
tool: memories
command: update
path: /target/release/memories
risk_level: high
timeout_secs: 5
env:
- IAS_MEMORY_DIR
params:
- name: memory_id
required: true
desc: 记忆ID
- name: content
required: true
desc: 更新后的新内容,覆盖原记忆
@@ -0,0 +1,14 @@
name: write_memory
desc: 记录一条新的长期记忆。当用户透露个人偏好、习惯、重要信息时使用此工具
type: stdio
tool: memories
command: add
path: /target/release/memories
risk_level: high
timeout_secs: 5
env:
- IAS_MEMORY_DIR
params:
- name: content
required: true
desc: 要记录的记忆内容,用自然语言描述。如"用户住在合肥包河区联投新安里A区"
+37
View File
@@ -0,0 +1,37 @@
//! memories — 长期记忆管理(通过主进程 DB 代理)
fn main() {
let input: serde_json::Value = serde_json::from_reader(std::io::stdin()).unwrap();
let mode = std::env::args().nth(2).unwrap_or_else(|| "list".to_string());
let params = &input["params"];
if input.get("db_response").is_none() {
// 发出 DB 请求
match mode.as_str() {
"list" => println!("{}", serde_json::json!({"type":"db","operation":"read_memories","desc":"读取记忆"})),
"add" => {
let c = params["content"].as_str().unwrap_or("");
if c.is_empty() { println!(r#"{{"type":"result","content":"缺少content"}}"#); return; }
println!("{}", serde_json::json!({"type":"db","operation":"write_memory","params":{"content":c},"desc":format!("记录: {c}")}));
}
"get" => {
let id = params["memory_id"].as_u64().unwrap_or(0);
println!("{}", serde_json::json!({"type":"db","operation":"read_memories","params":{"memory_id":id},"desc":"读取记忆"}));
}
"delete" => {
let id = params["memory_id"].as_u64().unwrap_or(0);
println!("{}", serde_json::json!({"type":"db","operation":"delete_memory","params":{"memory_id":id},"desc":format!("删除记忆 {id}")}));
}
"update" => {
let id = params["memory_id"].as_u64().unwrap_or(0);
let c = params["content"].as_str().unwrap_or("");
println!("{}", serde_json::json!({"type":"db","operation":"update_memory","params":{"memory_id":id,"content":c},"desc":format!("更新记忆 {id}")}));
}
_ => println!(r#"{{"type":"result","content":"未知操作"}}"#),
}
} else {
// 处理 DB 响应
let result = input["db_response"]["result"].as_str().unwrap_or("");
println!("{}", serde_json::json!({"type":"result","content":result}));
}
}
+105
View File
@@ -0,0 +1,105 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "weather"
version = "0.1.0"
dependencies = [
"serde_json",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "weather"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "weather"
path = "src/main.rs"
[dependencies]
serde_json = "1.0"
@@ -0,0 +1,14 @@
name: weather_forecast
desc: 查询指定城市未来7天的每日天气预报(白天/夜间天气、最高/最低温度)。用于"明天天气""这周天气"等问题
type: http
tool: weather
command: forecast
path: /target/release/weather
risk_level: low
timeout_secs: 10
env:
- QWEATHER_KEY
params:
- name: location
required: true
desc: 城市名称,如"北京"、"上海"、"合肥"。支持地级市和县级市
@@ -0,0 +1,14 @@
name: weather_hourly
desc: 查询指定城市未来24小时逐小时天气(温度、天气状况、风力、降水概率)。用于"今晚会下雨吗""下午几点最热"等精确时间天气问题
type: http
tool: weather
command: hourly
path: /target/release/weather
risk_level: low
timeout_secs: 10
env:
- QWEATHER_KEY
params:
- name: location
required: true
desc: 城市名称,如"北京"、"上海"、"合肥"。支持地级市和县级市
+14
View File
@@ -0,0 +1,14 @@
name: weather_now
desc: 查询指定城市的实时天气(温度、体感温度、风向风力、湿度、气压、能见度)。用于回答"今天天气怎么样""北京多少度"等即时天气问题
type: http
tool: weather
command: now
path: /target/release/weather
risk_level: low
timeout_secs: 10
env:
- QWEATHER_KEY
params:
- name: location
required: true
desc: 城市名称,如"北京"、"上海"、"合肥"。支持地级市和县级市
+49
View File
@@ -0,0 +1,49 @@
//! weather — 和风天气
const HOST: &str = "https://devapi.qweather.com/v7";
fn main() {
let input: serde_json::Value = serde_json::from_reader(std::io::stdin()).unwrap();
let mode = std::env::args().nth(2).unwrap_or_else(|| "now".to_string());
let loc = input["params"]["location"].as_str().unwrap_or("北京");
let key = match std::env::var("QWEATHER_KEY") {
Ok(k) if !k.is_empty() => k,
_ => {
println!(r#"{{"type":"result","content":"错误: 缺少环境变量 QWEATHER_KEY(和风天气 API Key),请在 .env 中设置"}}"#);
return;
}
};
if input.get("response").is_none() && input.get("db_response").is_none() {
let (path, desc) = match mode.as_str() {
"now" => ("weather/now", "实时天气"),
"forecast" => ("weather/7d", "7天预报"),
"hourly" => ("weather/24h", "24h逐时"),
_ => { println!(r#"{{"type":"result","content":"未知模式"}}"#); return; }
};
println!("{}", serde_json::json!({
"type":"http","method":"GET",
"url":format!("{HOST}/{path}?location={loc}&key={key}"),
"desc":desc
}));
} else {
let body = &input["response"]["body"];
let ok = body["code"].as_str() == Some("200");
let content = if !ok { "查询失败".into() } else { match mode.as_str() {
"now" => format!("{} {}°C(体感{}°C) {}{}级 湿度{}%",
body["now"]["text"].as_str().unwrap_or("?"), body["now"]["temp"].as_str().unwrap_or("?"),
body["now"]["feelsLike"].as_str().unwrap_or("?"), body["now"]["windDir"].as_str().unwrap_or("?"),
body["now"]["windScale"].as_str().unwrap_or("?"), body["now"]["humidity"].as_str().unwrap_or("?")),
"forecast" => body["daily"].as_array().unwrap_or(&vec![]).iter().take(7)
.map(|d| format!("{}: {}~{}°C", d["fxDate"].as_str().unwrap_or(""),
d["tempMin"].as_str().unwrap_or(""), d["tempMax"].as_str().unwrap_or("")))
.collect::<Vec<_>>().join("\n"),
"hourly" => body["hourly"].as_array().unwrap_or(&vec![]).iter().take(12)
.map(|h| format!("{}: {} {}°C", h["fxTime"].as_str().unwrap_or(""),
h["text"].as_str().unwrap_or(""), h["temp"].as_str().unwrap_or("")))
.collect::<Vec<_>>().join("\n"),
_ => String::new(),
}};
println!("{}", serde_json::json!({"type":"result","content":content}));
}
}
+105
View File
@@ -0,0 +1,105 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "web_search"
version = "0.1.0"
dependencies = [
"serde_json",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "web_search"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "web_search"
path = "src/main.rs"
[dependencies]
serde_json = "1.0"
@@ -0,0 +1,15 @@
name: web_search
desc: 联网搜索互联网最新信息。支持 AI 摘要,返回标题、URL和内容摘要。用于查询实时资讯、最新事实、热点新闻等。需要 TAVILY_API_KEY
type: http
tool: web_search
path: /target/release/web_search
risk_level: low
timeout_secs: 30
env:
- TAVILY_API_KEY
params:
- name: query
required: true
desc: 搜索关键词,如"Rust 2024 edition 新特性"、"今天比特币价格"
- name: max_results
desc: 返回的最大搜索结果数量(1-20),默认5条
+22
View File
@@ -0,0 +1,22 @@
fn main() {
let input: serde_json::Value = serde_json::from_reader(std::io::stdin()).unwrap();
if input.get("response").is_none() && input.get("db_response").is_none() {
let q = input["params"]["query"].as_str().unwrap_or("");
if q.is_empty() { println!(r#"{{"type":"result","content":"缺少query"}}"#); return; }
let n = input["params"]["max_results"].as_u64().unwrap_or(5);
let body = serde_json::json!({"query":q,"max_results":n,"include_answer":true});
println!("{}", serde_json::json!({
"type":"http","method":"POST","url":"https://api.tavily.com/search",
"body":body.to_string(),"desc":format!("搜索: {q}")
}));
} else {
let b = &input["response"]["body"];
let mut o = String::new();
if let Some(a) = b["answer"].as_str() { o.push_str(&format!("📝 {a}\n\n")); }
for (i,r) in b["results"].as_array().unwrap_or(&vec![]).iter().enumerate() {
o.push_str(&format!("{}. {} - {}\n", i+1, r["title"].as_str().unwrap_or(""), r["url"].as_str().unwrap_or("")));
}
if o.is_empty() { o = "未找到结果".into(); }
println!("{}", serde_json::json!({"type":"result","content":o}));
}
}