Skip to content
This repository was archived by the owner on May 6, 2026. It is now read-only.

Commit 6b73206

Browse files
authored
Merge pull request #3 from SenseTime-FVG/add-sensenova-skills
Import SenseNova-Skills into hermes-agent and openclaw
2 parents 42be6b0 + 0a3674c commit 6b73206

877 files changed

Lines changed: 50895 additions & 62409 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
"""
2+
搜索 Skill 共享工具库。
3+
4+
提供标准 JSON 输出、CLI 脚手架、httpx helper 和配置读取。
5+
所有搜索脚本通过 sys.path 导入此模块。
6+
"""
7+
from __future__ import annotations
8+
9+
import argparse
10+
import json
11+
import os
12+
import sys
13+
from typing import Any
14+
15+
import httpx
16+
17+
# ---------------------------------------------------------------------------
18+
# 标准输出
19+
# ---------------------------------------------------------------------------
20+
21+
def make_result(
22+
success: bool,
23+
query: str,
24+
provider: str,
25+
items: list[dict[str, Any]],
26+
error: str | None = None,
27+
) -> dict[str, Any]:
28+
"""构造标准化的搜索结果。"""
29+
return {
30+
"success": success,
31+
"query": query,
32+
"provider": provider,
33+
"items": items,
34+
"error": error,
35+
}
36+
37+
38+
def make_item(
39+
title: str,
40+
url: str,
41+
snippet: str = "",
42+
**extra: Any,
43+
) -> dict[str, Any]:
44+
"""构造标准化的搜索结果条目。"""
45+
item: dict[str, Any] = {"title": title, "url": url, "snippet": snippet}
46+
for k, v in extra.items():
47+
if v not in (None, "", [], {}):
48+
item[k] = v
49+
return item
50+
51+
52+
def print_json(data: dict[str, Any]) -> None:
53+
"""将结果 JSON 输出到 stdout。"""
54+
json.dump(data, sys.stdout, ensure_ascii=False, indent=2)
55+
sys.stdout.write("\n")
56+
sys.stdout.flush()
57+
58+
59+
# ---------------------------------------------------------------------------
60+
# CLI 脚手架
61+
# ---------------------------------------------------------------------------
62+
63+
def build_parser(description: str) -> argparse.ArgumentParser:
64+
"""创建带有通用参数的 ArgumentParser。"""
65+
parser = argparse.ArgumentParser(description=description)
66+
parser.add_argument("query", help="搜索关键词")
67+
parser.add_argument("--limit", "-n", type=int, default=10, help="返回结果数量(默认 10)")
68+
return parser
69+
70+
71+
# ---------------------------------------------------------------------------
72+
# httpx helper
73+
# ---------------------------------------------------------------------------
74+
75+
_DEFAULT_TIMEOUT = 15
76+
_DEFAULT_UA = (
77+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
78+
"AppleWebKit/537.36 (KHTML, like Gecko) "
79+
"Chrome/125.0.0.0 Safari/537.36"
80+
)
81+
82+
83+
def get_client(
84+
timeout: int = _DEFAULT_TIMEOUT,
85+
headers: dict[str, str] | None = None,
86+
**kwargs: Any,
87+
) -> httpx.Client:
88+
"""返回预配置的 httpx.Client。"""
89+
default_headers = {
90+
"User-Agent": _DEFAULT_UA,
91+
"Accept": "application/json",
92+
}
93+
if headers:
94+
default_headers.update(headers)
95+
return httpx.Client(
96+
timeout=timeout,
97+
headers=default_headers,
98+
follow_redirects=True,
99+
**kwargs,
100+
)
101+
102+
103+
# ---------------------------------------------------------------------------
104+
# 配置读取
105+
# ---------------------------------------------------------------------------
106+
107+
def get_key(env_var: str, cli_arg: str | None = None) -> str | None:
108+
"""读取 API key:CLI 参数 > 环境变量。"""
109+
if cli_arg:
110+
return cli_arg
111+
return os.environ.get(env_var)
112+
113+
114+
# ---------------------------------------------------------------------------
115+
# 脚本入口辅助
116+
# ---------------------------------------------------------------------------
117+
118+
def run_search(
119+
provider: str,
120+
search_fn, # Callable[[str, int, ...], list[dict]]
121+
parser: argparse.ArgumentParser | None = None,
122+
extra_kwargs_fn=None, # Callable[[Namespace], dict] 从 args 提取额外参数
123+
) -> None:
124+
"""通用脚本入口:解析参数 → 执行搜索 → 输出 JSON。"""
125+
if parser is None:
126+
parser = build_parser(f"Search {provider}")
127+
args = parser.parse_args()
128+
129+
extra = {}
130+
if extra_kwargs_fn:
131+
extra = extra_kwargs_fn(args)
132+
133+
try:
134+
items = search_fn(args.query, args.limit, **extra)
135+
print_json(make_result(True, args.query, provider, items))
136+
except Exception as e:
137+
print_json(make_result(False, args.query, provider, [], str(e)))
138+
sys.exit(1)

0 commit comments

Comments
 (0)