-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
121 lines (102 loc) · 3.63 KB
/
Copy path__init__.py
File metadata and controls
121 lines (102 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from __future__ import annotations
import json
import os
import subprocess
import tempfile
from pathlib import Path
from typing import Any
SUPPORTED_SUFFIXES = {".json", ".jsonl", ".csv", ".tsv"}
def register(ctx: Any) -> None:
from tools.registry import registry
original = registry.get_entry("read_file")
if original is None:
return
def optimized_read_file(args: dict[str, Any], **kwargs: Any) -> str:
replacement = _selected_read_path(args, kwargs.get("task_id") or "default")
if replacement is None:
return original.handler(args, **kwargs)
rewritten = dict(args)
rewritten["path"] = replacement
return original.handler(rewritten, **kwargs)
ctx.register_tool(
name="read_file",
toolset=original.toolset,
schema=original.schema,
handler=optimized_read_file,
check_fn=original.check_fn,
requires_env=original.requires_env,
description=original.description,
emoji=original.emoji,
override=True,
)
def _selected_read_path(args: dict[str, Any], task_id: str) -> str | None:
path = args.get("path")
if not isinstance(path, str):
return None
if "offset" in args or "limit" in args:
return None
if Path(path).suffix.lower() not in SUPPORTED_SUFFIXES:
return None
repo_root = os.environ.get("CONTEXT_SELECTOR_REPO_ROOT")
if not repo_root:
return None
repo = Path(repo_root).expanduser().resolve()
if not (repo / "selector.py").is_file():
return None
try:
source_path = _resolve_hermes_path(path, task_id)
selected = _run_selector(repo, source_path)
if selected is None:
return None
if _line_count(selected) > 500:
return None
return str(selected)
except Exception:
return None
def _resolve_hermes_path(path: str, task_id: str) -> Path:
try:
from tools.file_tools import _resolve_path_for_task
return Path(_resolve_path_for_task(path, task_id)).resolve()
except Exception:
raw = Path(path).expanduser()
if raw.is_absolute():
return raw.resolve()
base = Path(os.environ.get("TERMINAL_CWD") or os.getcwd())
return (base / raw).resolve()
def _run_selector(repo: Path, source_path: Path) -> Path | None:
with tempfile.TemporaryDirectory(prefix="context-selector-hermes-hook-") as tmp:
report_out = Path(tmp) / "selector-report.json"
proc = subprocess.run(
[
"python3",
str(repo / "selector.py"),
"--cwd",
str(source_path.parent),
"--adapter",
"hermes-read-file-plugin",
"--model",
os.environ.get("CONTEXT_SELECTOR_MODEL", "unknown"),
"--report-out",
str(report_out),
"--verify-report",
str(source_path),
],
cwd=repo,
text=True,
capture_output=True,
check=True,
)
report = json.loads(proc.stdout)
results = report.get("results")
if not isinstance(results, list) or len(results) != 1:
return None
result = results[0]
if not isinstance(result, dict) or not result.get("selected"):
return None
read_path = result.get("read_path")
if not isinstance(read_path, str):
return None
return Path(read_path)
def _line_count(path: Path) -> int:
with path.open("r", encoding="utf-8", errors="replace") as handle:
return sum(1 for _ in handle)