全中文输出 + 积极正向的状态提示

所有 doctor 输出和渠道描述改为中文。
状态提示从'不支持/需要配置'的语气改为'配置一下就能用'。

Before:  Reddit posts — Need config: reddit_proxy
After:   Reddit 帖子和评论 — 配个代理就能用

Before:  XiaoHongShu — Need config: xhs_cookie
After:   小红书笔记 — 导入浏览器 Cookie 就能用
This commit is contained in:
Panniantong 2026-02-24 09:14:41 +01:00
parent 904f8dfb49
commit 2098dacd37
13 changed files with 54 additions and 44 deletions

View file

@ -108,25 +108,25 @@ agent-eyes configure proxy http://用户名:密码@IP:端口
```
$ agent-eyes doctor
👁️ Agent Eyes Status
👁️ Agent Eyes 状态
========================================
Ready (no setup needed):
✅ GitHub repos and code — Public repos only
✅ Twitter/X posts — Full access (search + timeline + threads)
✅ YouTube video transcripts — yt-dlp
⚠️ Bilibili video info — May be blocked on servers
✅ RSS and Atom feeds — feedparser
Web pages (any URL) — Jina Reader API
装好即用:
✅ GitHub 仓库和代码 — 公开仓库可用。配置 github_token 可访问私有仓库
✅ Twitter/X 推文 — 可读取推文。安装 birdx + 配置 Cookie 可解锁搜索和发推
✅ YouTube 视频字幕 — yt-dlp
⚠️ B站视频信息和字幕 — 服务器 IP 可能被封,配置代理即可解决
✅ RSS/Atom 订阅源 — feedparser
网页(任意 URL — Jina Reader API
🔍 Search (need free Exa API key):
Semantic web search
🔍 搜索(免费 Exa Key 即可解锁):
全网语义搜索 — 注册 exa.ai 获取免费 Key配置一下就能用
🔧 Optional (advanced setup):
⬜ Reddit posts and comments — Need proxy
XiaoHongShu (小红书) — Need cookies
🔧 配置后可用:
⬜ Reddit 帖子和评论 — 配个代理就能用
小红书笔记 — 导入浏览器 Cookie 就能用
Status: 6/9 channels active
状态6/9 个渠道可用
```
---

View file

@ -118,14 +118,14 @@ class Channel(ABC):
# Check required tools
for tool in self.requires_tools:
if not shutil.which(tool):
return "off", f"Install: pip install {tool}"
return "off", f"需要安装:pip install {tool}"
# Check required config
for key in self.requires_config:
if config and not config.get(key):
return "off", f"Need config: {key}. Run: agent-eyes setup"
return "off", f"需要配置 {key},运行 agent-eyes setup"
return "ok", f"{', '.join(self.backends) if self.backends else 'built-in'}"
return "ok", f"{''.join(self.backends) if self.backends else '内置'}"
async def search(self, query: str, config=None, **kwargs) -> List[SearchResult]:
"""Search this platform. Override if supported."""

View file

@ -12,7 +12,7 @@ from .base import Channel, ReadResult
class BilibiliChannel(Channel):
name = "bilibili"
description = "Bilibili video info and subtitles"
description = "B站视频信息和字幕"
backends = ["Bilibili API"]
tier = 0
@ -23,7 +23,7 @@ class BilibiliChannel(Channel):
def check(self, config=None):
proxy = config.get("bilibili_proxy") if config else None
if proxy:
return "ok", "Via proxy"
return "ok", "已配置代理,完整可用"
# Detect if we're on a server (same logic as cli._detect_environment)
import os
indicators = [
@ -34,8 +34,8 @@ class BilibiliChannel(Channel):
]
is_server = any(indicators)
if is_server:
return "warn", "May be blocked on servers. Fix: agent-eyes configure proxy URL"
return "ok", "Local access"
return "warn", "服务器 IP 可能被封,配置代理即可解决:agent-eyes configure proxy URL"
return "ok", "本地直连可用"
async def read(self, url: str, config=None) -> ReadResult:
# Proxy support (Bilibili blocks server IPs)

View file

@ -13,7 +13,7 @@ from typing import List
class ExaSearchChannel(Channel):
name = "exa_search"
description = "Semantic web search (powers Reddit/Twitter search too)"
description = "全网语义搜索(同时支持 Reddit/Twitter 搜索)"
backends = ["Exa API"]
requires_config = ["exa_api_key"]
tier = 1

View file

@ -13,7 +13,7 @@ from typing import List
class GitHubChannel(Channel):
name = "github"
description = "GitHub repos and code"
description = "GitHub 仓库和代码"
backends = ["GitHub API"]
tier = 0
@ -29,8 +29,8 @@ class GitHubChannel(Channel):
def check(self, config=None):
token = config.get("github_token") if config else None
if token:
return "ok", "Full access (authenticated)"
return "ok", "Public repos only. Set github_token for private repos + higher rate limits"
return "ok", "已认证,可访问私有仓库"
return "ok", "公开仓库可用。配置 github_token 可访问私有仓库"
def can_handle(self, url: str) -> bool:
domain = urlparse(url).netloc.lower()

View file

@ -12,7 +12,7 @@ from .base import Channel, ReadResult
class RedditChannel(Channel):
name = "reddit"
description = "Reddit posts and comments"
description = "Reddit 帖子和评论"
backends = ["Reddit JSON API"]
requires_config = ["reddit_proxy"]
tier = 2

View file

@ -12,7 +12,7 @@ from .base import Channel, ReadResult
class RSSChannel(Channel):
name = "rss"
description = "RSS and Atom feeds"
description = "RSS/Atom 订阅源"
backends = ["feedparser"]
tier = 0

View file

@ -16,7 +16,7 @@ import requests
class TwitterChannel(Channel):
name = "twitter"
description = "Twitter/X posts"
description = "Twitter/X 推文"
backends = ["birdx", "Jina Reader"]
tier = 0 # Single tweet reading is zero-config
@ -27,8 +27,8 @@ class TwitterChannel(Channel):
def check(self, config=None):
# Basic reading always works (Jina fallback)
if shutil.which("birdx"):
return "ok", "Full access (search + timeline + threads)"
return "ok", "Read-only (single tweets via Jina). Install birdx for search + timelines"
return "ok", "搜索、时间线、发推全部可用"
return "ok", "可读取推文。安装 birdx + 配置 Cookie 可解锁搜索和发推"
return "ok", "Jina Reader (single tweets only)"
async def read(self, url: str, config=None) -> ReadResult:

View file

@ -11,7 +11,7 @@ from .base import Channel, ReadResult
class WebChannel(Channel):
name = "web"
description = "Web pages (any URL)"
description = "网页(任意 URL"
backends = ["Jina Reader API"]
tier = 0

View file

@ -14,7 +14,7 @@ from .base import Channel, ReadResult
class XiaoHongShuChannel(Channel):
name = "xiaohongshu"
description = "XiaoHongShu (小红书) notes"
description = "小红书笔记"
backends = ["XHS Web API"]
requires_config = ["xhs_cookie"]
tier = 2

View file

@ -16,7 +16,7 @@ from .base import Channel, ReadResult
class YouTubeChannel(Channel):
name = "youtube"
description = "YouTube video transcripts"
description = "YouTube 视频字幕"
backends = ["yt-dlp"]
requires_tools = ["yt-dlp"]
tier = 0

View file

@ -27,7 +27,7 @@ def check_all(config: Config) -> Dict[str, dict]:
def format_report(results: Dict[str, dict]) -> str:
"""Format results as a readable text report."""
lines = []
lines.append("👁️ Agent Eyes Status")
lines.append("👁️ Agent Eyes 状态")
lines.append("=" * 40)
ok_count = sum(1 for r in results.values() if r["status"] == "ok")
@ -35,7 +35,7 @@ def format_report(results: Dict[str, dict]) -> str:
# Tier 0 — zero config
lines.append("")
lines.append("Ready (no setup needed):")
lines.append("装好即用:")
for key, r in results.items():
if r["tier"] == 0:
if r["status"] == "ok":
@ -49,23 +49,33 @@ def format_report(results: Dict[str, dict]) -> str:
tier1 = {k: r for k, r in results.items() if r["tier"] == 1}
if tier1:
lines.append("")
lines.append("🔍 Search (need free Exa API key):")
lines.append("🔍 搜索(免费 Exa Key 即可解锁):")
for key, r in tier1.items():
icon = "" if r["status"] == "ok" else ""
lines.append(f" {icon} {r['name']}")
if r["status"] == "ok":
lines.append(f"{r['name']}")
else:
lines.append(f"{r['name']} — 注册 exa.ai 获取免费 Key配置一下就能用")
# Tier 2 — optional setup
tier2 = {k: r for k, r in results.items() if r["tier"] == 2}
if tier2:
lines.append("")
lines.append("🔧 Optional (advanced setup):")
lines.append("🔧 配置后可用:")
for key, r in tier2.items():
icon = "" if r["status"] == "ok" else ""
lines.append(f" {icon} {r['name']}{r['message']}")
if r["status"] == "ok":
lines.append(f"{r['name']}{r['message']}")
else:
# Friendly message about what to configure
if "proxy" in str(r.get("message", "")):
lines.append(f"{r['name']} — 配个代理就能用agent-eyes configure proxy URL")
elif "cookie" in str(r.get("message", "")):
lines.append(f"{r['name']} — 导入浏览器 Cookie 就能用agent-eyes configure --from-browser chrome")
else:
lines.append(f"{r['name']}{r['message']}")
lines.append("")
lines.append(f"Status: {ok_count}/{total} channels active")
lines.append(f"状态:{ok_count}/{total} 个渠道可用")
if ok_count < total:
lines.append("Run `agent-eyes setup` to unlock more!")
lines.append("运行 `agent-eyes setup` 解锁更多渠道")
return "\n".join(lines)

View file

@ -33,4 +33,4 @@ class TestDoctor:
report = format_report(results)
assert "Agent Eyes" in report
assert "" in report
assert "channels active" in report
assert "渠道可用" in report