Skip to content

Commit ac14f0e

Browse files
Panniantongclaude
andcommitted
fix(web): add read() via Jina Reader + skill install fallback
- WebChannel.read(): reads any URL via Jina Reader (r.jina.ai), returns Markdown - _install_skill(): add fallback from importlib.resources to Path(__file__) for editable installs - Explicit UTF-8 encoding on all file read/write operations Inspired by PR #215, implemented correctly (Jina instead of raw requests). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 23d4d5c commit ac14f0e

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

agent_reach/channels/web.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# -*- coding: utf-8 -*-
22
"""Web — any URL via Jina Reader. Always available."""
33

4+
import urllib.request
45
from .base import Channel
56

7+
_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
8+
69

710
class WebChannel(Channel):
811
name = "web"
@@ -15,3 +18,15 @@ def can_handle(self, url: str) -> bool:
1518

1619
def check(self, config=None):
1720
return "ok", "通过 Jina Reader 读取任意网页(curl https://r.jina.ai/URL)"
21+
22+
def read(self, url: str) -> str:
23+
"""通过 Jina Reader 读取网页,返回 Markdown 全文。"""
24+
if not url.startswith(("http://", "https://")):
25+
url = "https://" + url
26+
jina_url = f"https://r.jina.ai/{url}"
27+
req = urllib.request.Request(
28+
jina_url,
29+
headers={"User-Agent": _UA, "Accept": "text/plain"},
30+
)
31+
with urllib.request.urlopen(req, timeout=30) as resp:
32+
return resp.read().decode("utf-8")

agent_reach/cli.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,17 @@ def _copy_skill_dir(target: str) -> bool:
334334
shutil.rmtree(target)
335335
os.makedirs(target, exist_ok=True)
336336

337-
# Get skill directory from package
338-
skill_pkg = importlib.resources.files("agent_reach").joinpath("skill")
337+
# Get skill directory from package (with fallback for editable installs)
338+
try:
339+
skill_pkg = importlib.resources.files("agent_reach").joinpath("skill")
340+
skill_md = skill_pkg.joinpath("SKILL.md").read_text(encoding="utf-8")
341+
except Exception:
342+
from pathlib import Path
343+
skill_pkg = Path(__file__).resolve().parent / "skill"
344+
skill_md = (skill_pkg / "SKILL.md").read_text(encoding="utf-8")
339345

340346
# Copy SKILL.md
341-
skill_md = skill_pkg.joinpath("SKILL.md").read_text()
342-
with open(os.path.join(target, "SKILL.md"), "w") as f:
347+
with open(os.path.join(target, "SKILL.md"), "w", encoding="utf-8") as f:
343348
f.write(skill_md)
344349

345350
# Copy references/ directory
@@ -348,9 +353,10 @@ def _copy_skill_dir(target: str) -> bool:
348353
os.makedirs(refs_target, exist_ok=True)
349354

350355
for ref_file in refs_pkg.iterdir():
351-
if ref_file.suffix == ".md":
352-
content = ref_file.read_text()
353-
with open(os.path.join(refs_target, ref_file.name), "w") as f:
356+
name = ref_file.name if hasattr(ref_file, 'name') else str(ref_file).split('/')[-1]
357+
if name.endswith(".md"):
358+
content = ref_file.read_text(encoding="utf-8") if hasattr(ref_file, 'read_text') else ref_file.read_text()
359+
with open(os.path.join(refs_target, name), "w", encoding="utf-8") as f:
354360
f.write(content)
355361

356362
return True

0 commit comments

Comments
 (0)