@acedatacloud/skills 2026.630.2 → 2026.702.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/ai-chat/SKILL.md +1 -1
- package/skills/zhihu/SKILL.md +82 -15
- package/skills/zhihu/scripts/search.py +234 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acedatacloud/skills",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.702.0",
|
|
4
4
|
"description": "Agent Skills for AceDataCloud AI services — music, image, video generation, LLM chat, web search. Compatible with Claude Code, GitHub Copilot, Gemini CLI, OpenAI Codex, and 30+ AI coding agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
package/skills/ai-chat/SKILL.md
CHANGED
|
@@ -58,7 +58,7 @@ models include:
|
|
|
58
58
|
|--------|------------------|
|
|
59
59
|
| OpenAI / reasoning | `gpt-5.5`, `gpt-5.5-pro`, `gpt-5.4`, `gpt-5.4-pro`, `gpt-5.2`, `gpt-5.1`, `gpt-5`, `gpt-5-mini`, `gpt-5-nano`, `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano`, `gpt-4o`, `gpt-4o-mini`, `o1`, `o3`, `o4-mini` |
|
|
60
60
|
| OpenAI free-tier chat-completions | `gpt-5.5:free`, `gpt-5:free`, `gpt-4.1:free`, `gpt-4o:free`, `gpt-4o-mini:free`, `gpt-oss:free` |
|
|
61
|
-
| Claude | `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6`, `claude-opus-4-5-20251101`, `claude-sonnet-4-6`, `claude-sonnet-4-5-20250929`, `claude-sonnet-4-20250514`, `claude-haiku-4-5-20251001`, `claude-3-7-sonnet-20250219` |
|
|
61
|
+
| Claude | `claude-fable-5`, `claude-sonnet-5`, `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6`, `claude-opus-4-5-20251101`, `claude-sonnet-4-6`, `claude-sonnet-4-5-20250929`, `claude-sonnet-4-20250514`, `claude-haiku-4-5-20251001`, `claude-3-7-sonnet-20250219` |
|
|
62
62
|
| Gemini | `gemini-3.1-pro`, `gemini-3.1-pro-preview`, `gemini-3.1-flash-image-preview`, `gemini-3.1-flash-lite-preview`, `gemini-3-pro-preview`, `gemini-2.5-flash-lite`, `gemini-2.0-flash-lite` |
|
|
63
63
|
| Grok | `grok-4`, `grok-4-0709`, `grok-3`, `grok-3-fast` |
|
|
64
64
|
| DeepSeek | `deepseek-r1`, `deepseek-r1-0528`, `deepseek-v3`, `deepseek-v3-250324`, `deepseek-v3.2-exp`, `deepseek-v4-flash` |
|
package/skills/zhihu/SKILL.md
CHANGED
|
@@ -1,35 +1,102 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zhihu
|
|
3
|
-
description:
|
|
3
|
+
description: Search Zhihu & the web, get trending topics, and read/publish on Zhihu (知乎) — search Zhihu content or the entire web via the official Developer Platform API, get hot topics (热榜), list published articles & answers with stats, inspect content, publish articles, and answer questions. Use when the user mentions 知乎 / Zhihu, 搜索知乎, 全网搜索, 热榜, "我的知乎文章/回答", reading stats, 发文, or 回答问题.
|
|
4
4
|
when_to_use: |
|
|
5
|
-
Trigger for anything
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
Trigger for anything involving Zhihu (知乎):
|
|
6
|
+
- Searching Zhihu content (站内搜索) or the entire web (全网搜索)
|
|
7
|
+
- Getting Zhihu trending topics (热榜)
|
|
8
|
+
- Reading the user's own articles/answers with stats
|
|
9
|
+
- Publishing articles or answering questions (gated behind confirmation)
|
|
10
|
+
Search commands use the Zhihu Developer Platform API (Bearer token auth).
|
|
11
|
+
Read/write commands use the user's login cookies (BYOC).
|
|
11
12
|
connections: [zhihu]
|
|
12
13
|
allowed_tools: [Bash]
|
|
13
14
|
license: Apache-2.0
|
|
14
15
|
metadata:
|
|
15
16
|
author: acedatacloud
|
|
16
|
-
version: "
|
|
17
|
+
version: "2.0"
|
|
17
18
|
---
|
|
18
19
|
|
|
19
|
-
# zhihu — read & publish on Zhihu
|
|
20
|
+
# zhihu — search, read & publish on Zhihu
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
own editor uses, authenticated by the login cookie they captured with the ACE
|
|
23
|
-
extension. No browser, no third-party deps — just `urllib`.
|
|
22
|
+
Two authentication layers, two scripts:
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
| Script | Auth | Capabilities |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `scripts/search.py` | `ZHIHU_DEVELOPER_TOKEN` (Bearer) | Search Zhihu, search the web, get hot topics |
|
|
27
|
+
| `scripts/blog.py` | `ZHIHU_COOKIES` (login cookie) | Read/write own articles & answers |
|
|
26
28
|
|
|
29
|
+
No browser, no third-party deps — just `urllib`.
|
|
30
|
+
|
|
31
|
+
The connector injects credentials as env vars:
|
|
32
|
+
|
|
33
|
+
- `ZHIHU_DEVELOPER_TOKEN` — Zhihu Developer Platform access secret (Bearer token).
|
|
34
|
+
Used for search and hot-list queries. **Secret — never echo or print it.**
|
|
27
35
|
- `ZHIHU_COOKIES` — a JSON array of `{name, value, domain, path, ...}` cookies.
|
|
28
|
-
**Secret — never echo or print it.**
|
|
36
|
+
Used for reading/writing the user's own content. **Secret — never echo or print it.**
|
|
37
|
+
|
|
38
|
+
## Search CLI (search.py)
|
|
39
|
+
|
|
40
|
+
[`scripts/search.py`](scripts/search.py) — search Zhihu and the web. Requires
|
|
41
|
+
only `ZHIHU_DEVELOPER_TOKEN` (no cookies needed).
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
SEARCH=$SKILL_DIR/scripts/search.py
|
|
45
|
+
|
|
46
|
+
# Search Zhihu content (站内搜索) — questions, answers, articles
|
|
47
|
+
python3 $SEARCH search "Python 爬虫"
|
|
48
|
+
python3 $SEARCH search "Python 爬虫" --count 5
|
|
49
|
+
|
|
50
|
+
# Search the entire web (全网搜索) — all indexed sites
|
|
51
|
+
python3 $SEARCH global "AI Agent"
|
|
52
|
+
python3 $SEARCH global "AI Agent" --count 15
|
|
53
|
+
|
|
54
|
+
# Filter by site or time
|
|
55
|
+
python3 $SEARCH global "React" --filter 'host=="github.com"'
|
|
56
|
+
python3 $SEARCH global "新闻" --filter 'publish_time>=1720000000'
|
|
57
|
+
python3 $SEARCH global "技术" --filter 'host=="github.com" AND publish_time>=1720000000'
|
|
58
|
+
python3 $SEARCH global "实时新闻" --db realtime
|
|
59
|
+
|
|
60
|
+
# Get Zhihu trending topics (热榜)
|
|
61
|
+
python3 $SEARCH hot
|
|
62
|
+
python3 $SEARCH hot --limit 10
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Search commands
|
|
66
|
+
|
|
67
|
+
| Goal | Command |
|
|
68
|
+
|---|---|
|
|
69
|
+
| Search Zhihu (max 10 results) | `python3 $SEARCH search "<query>" --count N` |
|
|
70
|
+
| Search entire web (max 20) | `python3 $SEARCH global "<query>" --count N` |
|
|
71
|
+
| Filter by site | `--filter 'host=="example.com"'` |
|
|
72
|
+
| Filter by time | `--filter 'publish_time>=<unix_ts>'` |
|
|
73
|
+
| Search only realtime/static index | `--db realtime` or `--db static` |
|
|
74
|
+
| Zhihu trending topics (max 30) | `python3 $SEARCH hot --limit N` |
|
|
75
|
+
|
|
76
|
+
### Search result fields
|
|
77
|
+
|
|
78
|
+
**zhihu_search** returns: title, type (Article/Answer), content_id, url,
|
|
79
|
+
excerpt, vote_up (赞同), comments, author, authority level, edit_time.
|
|
80
|
+
|
|
81
|
+
**global_search** returns the same fields plus has_more indicator. The `url`
|
|
82
|
+
includes utm tracking params from Zhihu's platform.
|
|
83
|
+
|
|
84
|
+
**hot_list** returns: rank, title, url, summary, thumbnail.
|
|
85
|
+
|
|
86
|
+
### global_search Filter syntax
|
|
87
|
+
|
|
88
|
+
- `host=="example.com"` — filter by domain (note: `host=="zhihu.com"` not
|
|
89
|
+
supported — use `search` command instead)
|
|
90
|
+
- `publish_time>=1720000000` — filter by publish time (unix seconds)
|
|
91
|
+
- Logical operators: `AND`, `OR` (must be uppercase)
|
|
92
|
+
- Parentheses for grouping: `(host=="a.com" OR host=="b.com") AND publish_time>=T`
|
|
93
|
+
|
|
94
|
+
---
|
|
29
95
|
|
|
30
|
-
## CLI
|
|
96
|
+
## Blog CLI (blog.py)
|
|
31
97
|
|
|
32
98
|
The skill ships [`scripts/blog.py`](scripts/blog.py) — self-contained, stdlib only.
|
|
99
|
+
Requires `ZHIHU_COOKIES` (login cookie).
|
|
33
100
|
|
|
34
101
|
```sh
|
|
35
102
|
BLOG=$SKILL_DIR/scripts/blog.py
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
zhihu search — search Zhihu and the web via the Zhihu Developer Platform API.
|
|
4
|
+
Standard-library only (urllib), no third-party deps.
|
|
5
|
+
|
|
6
|
+
Auth: Bearer token via ``ZHIHU_DEVELOPER_TOKEN`` env var.
|
|
7
|
+
Does NOT require login cookies — independent of blog.py.
|
|
8
|
+
|
|
9
|
+
Endpoints:
|
|
10
|
+
zhihu_search — search Zhihu content (questions/answers/articles)
|
|
11
|
+
global_search — search the entire web with optional filters
|
|
12
|
+
hot_list — current Zhihu trending topics
|
|
13
|
+
|
|
14
|
+
Quick examples:
|
|
15
|
+
python3 $SKILL_DIR/scripts/search.py search "Python 爬虫"
|
|
16
|
+
python3 $SKILL_DIR/scripts/search.py search "Python 爬虫" --count 5
|
|
17
|
+
python3 $SKILL_DIR/scripts/search.py global "AI Agent" --count 10
|
|
18
|
+
python3 $SKILL_DIR/scripts/search.py global "React" --filter 'host=="github.com"'
|
|
19
|
+
python3 $SKILL_DIR/scripts/search.py global "新闻" --db realtime
|
|
20
|
+
python3 $SKILL_DIR/scripts/search.py hot
|
|
21
|
+
python3 $SKILL_DIR/scripts/search.py hot --limit 10
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import argparse
|
|
27
|
+
import json
|
|
28
|
+
import os
|
|
29
|
+
import sys
|
|
30
|
+
import time
|
|
31
|
+
import urllib.error
|
|
32
|
+
import urllib.parse
|
|
33
|
+
import urllib.request
|
|
34
|
+
|
|
35
|
+
BASE_URL = "https://developer.zhihu.com/api/v1/content"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def out(obj) -> None:
|
|
39
|
+
json.dump(obj, sys.stdout, ensure_ascii=False, indent=2)
|
|
40
|
+
sys.stdout.write("\n")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def die(msg: str, code: int = 1) -> None:
|
|
44
|
+
sys.stderr.write(f"ERROR: {msg}\n")
|
|
45
|
+
sys.exit(code)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_token() -> str:
|
|
49
|
+
token = os.environ.get("ZHIHU_DEVELOPER_TOKEN", "").strip()
|
|
50
|
+
if not token:
|
|
51
|
+
die(
|
|
52
|
+
"ZHIHU_DEVELOPER_TOKEN not set. "
|
|
53
|
+
"Set this env var to your Zhihu Developer Platform access secret."
|
|
54
|
+
)
|
|
55
|
+
return token
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def api_get(endpoint: str, params: dict | None = None) -> dict:
|
|
59
|
+
"""GET request to the Zhihu Developer Platform API."""
|
|
60
|
+
token = get_token()
|
|
61
|
+
url = f"{BASE_URL}/{endpoint}"
|
|
62
|
+
if params:
|
|
63
|
+
# Filter out None values
|
|
64
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
65
|
+
if params:
|
|
66
|
+
url += "?" + urllib.parse.urlencode(params)
|
|
67
|
+
|
|
68
|
+
headers = {
|
|
69
|
+
"Authorization": f"Bearer {token}",
|
|
70
|
+
"X-Request-Timestamp": str(int(time.time())),
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
req = urllib.request.Request(url, headers=headers, method="GET")
|
|
75
|
+
try:
|
|
76
|
+
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
77
|
+
return json.loads(resp.read().decode())
|
|
78
|
+
except urllib.error.HTTPError as e:
|
|
79
|
+
body = e.read().decode() if e.fp else ""
|
|
80
|
+
die(f"HTTP {e.code}: {body[:500]}")
|
|
81
|
+
except urllib.error.URLError as e:
|
|
82
|
+
die(f"Network error: {e.reason}")
|
|
83
|
+
return {}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _fmt_zhihu_item(item: dict) -> dict:
|
|
87
|
+
"""Format a zhihu_search result item for display."""
|
|
88
|
+
return {
|
|
89
|
+
"title": item.get("Title", ""),
|
|
90
|
+
"type": item.get("ContentType", ""),
|
|
91
|
+
"content_id": item.get("ContentID", ""),
|
|
92
|
+
"url": item.get("Url", ""),
|
|
93
|
+
"excerpt": item.get("ContentText", "")[:200],
|
|
94
|
+
"vote_up": item.get("VoteUpCount", 0),
|
|
95
|
+
"comments": item.get("CommentCount", 0),
|
|
96
|
+
"author": item.get("AuthorName", ""),
|
|
97
|
+
"authority": item.get("AuthorityLevel", ""),
|
|
98
|
+
"edit_time": item.get("EditTime", 0),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _fmt_global_item(item: dict) -> dict:
|
|
103
|
+
"""Format a global_search result item for display."""
|
|
104
|
+
return {
|
|
105
|
+
"title": item.get("Title", ""),
|
|
106
|
+
"type": item.get("ContentType", ""),
|
|
107
|
+
"content_id": item.get("ContentID", ""),
|
|
108
|
+
"url": item.get("Url", ""),
|
|
109
|
+
"excerpt": item.get("ContentText", "")[:300],
|
|
110
|
+
"vote_up": item.get("VoteUpCount", 0),
|
|
111
|
+
"comments": item.get("CommentCount", 0),
|
|
112
|
+
"author": item.get("AuthorName", ""),
|
|
113
|
+
"authority": item.get("AuthorityLevel", ""),
|
|
114
|
+
"edit_time": item.get("EditTime", 0),
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _fmt_hot_item(item: dict, rank: int) -> dict:
|
|
119
|
+
"""Format a hot_list result item for display."""
|
|
120
|
+
return {
|
|
121
|
+
"rank": rank,
|
|
122
|
+
"title": item.get("Title", ""),
|
|
123
|
+
"url": item.get("Url", ""),
|
|
124
|
+
"summary": item.get("Summary", ""),
|
|
125
|
+
"thumbnail": item.get("ThumbnailUrl", ""),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def cmd_search(args):
|
|
130
|
+
"""Search Zhihu content (站内搜索)."""
|
|
131
|
+
params = {"Query": args.query, "Count": args.count}
|
|
132
|
+
resp = api_get("zhihu_search", params)
|
|
133
|
+
|
|
134
|
+
if resp.get("Code") != 0:
|
|
135
|
+
die(f"API error: Code={resp.get('Code')} Message={resp.get('Message')}")
|
|
136
|
+
|
|
137
|
+
data = resp.get("Data", {})
|
|
138
|
+
items = data.get("Items") or []
|
|
139
|
+
|
|
140
|
+
result = {
|
|
141
|
+
"query": args.query,
|
|
142
|
+
"count": len(items),
|
|
143
|
+
"results": [_fmt_zhihu_item(it) for it in items],
|
|
144
|
+
}
|
|
145
|
+
if data.get("EmptyReason"):
|
|
146
|
+
result["empty_reason"] = data["EmptyReason"]
|
|
147
|
+
|
|
148
|
+
out(result)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def cmd_global(args):
|
|
152
|
+
"""Search the entire web (全网搜索)."""
|
|
153
|
+
params: dict = {"Query": args.query, "Count": args.count}
|
|
154
|
+
if args.filter:
|
|
155
|
+
params["Filter"] = args.filter
|
|
156
|
+
if args.db:
|
|
157
|
+
params["SearchDB"] = args.db
|
|
158
|
+
|
|
159
|
+
resp = api_get("global_search", params)
|
|
160
|
+
|
|
161
|
+
if resp.get("Code") != 0:
|
|
162
|
+
die(f"API error: Code={resp.get('Code')} Message={resp.get('Message')}")
|
|
163
|
+
|
|
164
|
+
data = resp.get("Data", {})
|
|
165
|
+
items = data.get("Items") or []
|
|
166
|
+
|
|
167
|
+
result = {
|
|
168
|
+
"query": args.query,
|
|
169
|
+
"has_more": data.get("HasMore", False),
|
|
170
|
+
"count": len(items),
|
|
171
|
+
"results": [_fmt_global_item(it) for it in items],
|
|
172
|
+
}
|
|
173
|
+
out(result)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def cmd_hot(args):
|
|
177
|
+
"""Get current Zhihu trending topics (热榜)."""
|
|
178
|
+
params = {"Limit": args.limit}
|
|
179
|
+
resp = api_get("hot_list", params)
|
|
180
|
+
|
|
181
|
+
if resp.get("Code") != 0:
|
|
182
|
+
die(f"API error: Code={resp.get('Code')} Message={resp.get('Message')}")
|
|
183
|
+
|
|
184
|
+
data = resp.get("Data", {})
|
|
185
|
+
items = data.get("Items") or []
|
|
186
|
+
|
|
187
|
+
result = {
|
|
188
|
+
"total": data.get("Total", len(items)),
|
|
189
|
+
"items": [_fmt_hot_item(it, i + 1) for i, it in enumerate(items)],
|
|
190
|
+
}
|
|
191
|
+
out(result)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def main() -> None:
|
|
195
|
+
parser = argparse.ArgumentParser(
|
|
196
|
+
prog="zhihu-search",
|
|
197
|
+
description="Search Zhihu and the web via the Zhihu Developer Platform API",
|
|
198
|
+
)
|
|
199
|
+
sub = parser.add_subparsers(dest="command")
|
|
200
|
+
|
|
201
|
+
# search (zhihu_search)
|
|
202
|
+
p_search = sub.add_parser("search", help="Search Zhihu content (站内搜索)")
|
|
203
|
+
p_search.add_argument("query", help="Search query")
|
|
204
|
+
p_search.add_argument("--count", type=int, default=10, help="Results count (max 10)")
|
|
205
|
+
|
|
206
|
+
# global (global_search)
|
|
207
|
+
p_global = sub.add_parser("global", help="Search the entire web (全网搜索)")
|
|
208
|
+
p_global.add_argument("query", help="Search query")
|
|
209
|
+
p_global.add_argument("--count", type=int, default=10, help="Results count (max 20)")
|
|
210
|
+
p_global.add_argument(
|
|
211
|
+
"--filter",
|
|
212
|
+
help='Advanced filter expression, e.g. host=="example.com" AND publish_time>=1700000000',
|
|
213
|
+
)
|
|
214
|
+
p_global.add_argument(
|
|
215
|
+
"--db",
|
|
216
|
+
choices=["all", "realtime", "static"],
|
|
217
|
+
help="Index to search: all (default), realtime, static",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# hot (hot_list)
|
|
221
|
+
p_hot = sub.add_parser("hot", help="Get Zhihu trending topics (热榜)")
|
|
222
|
+
p_hot.add_argument("--limit", type=int, default=30, help="Number of items (max 30)")
|
|
223
|
+
|
|
224
|
+
args = parser.parse_args()
|
|
225
|
+
if not args.command:
|
|
226
|
+
parser.print_help()
|
|
227
|
+
sys.exit(1)
|
|
228
|
+
|
|
229
|
+
dispatch = {"search": cmd_search, "global": cmd_global, "hot": cmd_hot}
|
|
230
|
+
dispatch[args.command](args)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
if __name__ == "__main__":
|
|
234
|
+
main()
|