harness-evolver 3.0.2 → 3.0.3
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/setup/SKILL.md +25 -2
- package/tools/read_results.py +25 -0
- package/tools/run_eval.py +37 -0
- package/tools/setup.py +52 -0
package/package.json
CHANGED
package/skills/setup/SKILL.md
CHANGED
|
@@ -11,8 +11,31 @@ Set up the Harness Evolver v3 in a project. Explores the codebase, configures La
|
|
|
11
11
|
|
|
12
12
|
## Prerequisites
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Check for LangSmith API key — it can be in the environment, the credentials file, or .env:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
python3 -c "
|
|
18
|
+
import os, platform
|
|
19
|
+
key = os.environ.get('LANGSMITH_API_KEY', '')
|
|
20
|
+
if not key:
|
|
21
|
+
creds = os.path.expanduser('~/Library/Application Support/langsmith-cli/credentials') if platform.system() == 'Darwin' else os.path.expanduser('~/.config/langsmith-cli/credentials')
|
|
22
|
+
if os.path.exists(creds):
|
|
23
|
+
for line in open(creds):
|
|
24
|
+
if line.strip().startswith('LANGSMITH_API_KEY='):
|
|
25
|
+
key = line.strip().split('=',1)[1].strip()
|
|
26
|
+
if not key and os.path.exists('.env'):
|
|
27
|
+
for line in open('.env'):
|
|
28
|
+
if line.strip().startswith('LANGSMITH_API_KEY=') and not line.strip().startswith('#'):
|
|
29
|
+
key = line.strip().split('=',1)[1].strip().strip('\"').strip(\"'\")
|
|
30
|
+
print('OK' if key else 'MISSING')
|
|
31
|
+
"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If `MISSING`: "Set your LangSmith API key: `export LANGSMITH_API_KEY=lsv2_pt_...` or run `npx harness-evolver@latest` to configure."
|
|
35
|
+
|
|
36
|
+
The tools auto-load the key from the credentials file, but the env var takes precedence.
|
|
37
|
+
|
|
38
|
+
Python 3.10+ with `langsmith` and `openevals` packages must be installed:
|
|
16
39
|
|
|
17
40
|
```bash
|
|
18
41
|
pip install langsmith openevals 2>/dev/null || uv pip install langsmith openevals
|
package/tools/read_results.py
CHANGED
|
@@ -21,9 +21,33 @@ Requires: pip install langsmith
|
|
|
21
21
|
import argparse
|
|
22
22
|
import json
|
|
23
23
|
import os
|
|
24
|
+
import platform
|
|
24
25
|
import sys
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
def ensure_langsmith_api_key():
|
|
29
|
+
"""Load LANGSMITH_API_KEY from credentials file if not in env."""
|
|
30
|
+
if os.environ.get("LANGSMITH_API_KEY"):
|
|
31
|
+
return True
|
|
32
|
+
if platform.system() == "Darwin":
|
|
33
|
+
creds_path = os.path.expanduser("~/Library/Application Support/langsmith-cli/credentials")
|
|
34
|
+
else:
|
|
35
|
+
creds_path = os.path.expanduser("~/.config/langsmith-cli/credentials")
|
|
36
|
+
if os.path.exists(creds_path):
|
|
37
|
+
try:
|
|
38
|
+
with open(creds_path) as f:
|
|
39
|
+
for line in f:
|
|
40
|
+
line = line.strip()
|
|
41
|
+
if line.startswith("LANGSMITH_API_KEY="):
|
|
42
|
+
key = line.split("=", 1)[1].strip()
|
|
43
|
+
if key:
|
|
44
|
+
os.environ["LANGSMITH_API_KEY"] = key
|
|
45
|
+
return True
|
|
46
|
+
except OSError:
|
|
47
|
+
pass
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
|
|
27
51
|
def read_experiment(client, experiment_name):
|
|
28
52
|
"""Read results from a single LangSmith experiment."""
|
|
29
53
|
try:
|
|
@@ -184,6 +208,7 @@ def main():
|
|
|
184
208
|
parser.add_argument("--output", default=None, help="Output JSON path")
|
|
185
209
|
parser.add_argument("--format", default="json", choices=["json", "markdown"], help="Output format")
|
|
186
210
|
args = parser.parse_args()
|
|
211
|
+
ensure_langsmith_api_key()
|
|
187
212
|
|
|
188
213
|
from langsmith import Client
|
|
189
214
|
client = Client()
|
package/tools/run_eval.py
CHANGED
|
@@ -17,11 +17,47 @@ Requires: pip install langsmith openevals
|
|
|
17
17
|
import argparse
|
|
18
18
|
import json
|
|
19
19
|
import os
|
|
20
|
+
import platform
|
|
20
21
|
import subprocess
|
|
21
22
|
import sys
|
|
22
23
|
import tempfile
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
def ensure_langsmith_api_key():
|
|
27
|
+
"""Load LANGSMITH_API_KEY from credentials file if not in env."""
|
|
28
|
+
if os.environ.get("LANGSMITH_API_KEY"):
|
|
29
|
+
return True
|
|
30
|
+
if platform.system() == "Darwin":
|
|
31
|
+
creds_path = os.path.expanduser("~/Library/Application Support/langsmith-cli/credentials")
|
|
32
|
+
else:
|
|
33
|
+
creds_path = os.path.expanduser("~/.config/langsmith-cli/credentials")
|
|
34
|
+
if os.path.exists(creds_path):
|
|
35
|
+
try:
|
|
36
|
+
with open(creds_path) as f:
|
|
37
|
+
for line in f:
|
|
38
|
+
line = line.strip()
|
|
39
|
+
if line.startswith("LANGSMITH_API_KEY="):
|
|
40
|
+
key = line.split("=", 1)[1].strip()
|
|
41
|
+
if key:
|
|
42
|
+
os.environ["LANGSMITH_API_KEY"] = key
|
|
43
|
+
return True
|
|
44
|
+
except OSError:
|
|
45
|
+
pass
|
|
46
|
+
if os.path.exists(".env"):
|
|
47
|
+
try:
|
|
48
|
+
with open(".env") as f:
|
|
49
|
+
for line in f:
|
|
50
|
+
line = line.strip()
|
|
51
|
+
if line.startswith("LANGSMITH_API_KEY=") and not line.startswith("#"):
|
|
52
|
+
key = line.split("=", 1)[1].strip().strip("'\"")
|
|
53
|
+
if key:
|
|
54
|
+
os.environ["LANGSMITH_API_KEY"] = key
|
|
55
|
+
return True
|
|
56
|
+
except OSError:
|
|
57
|
+
pass
|
|
58
|
+
return False
|
|
59
|
+
|
|
60
|
+
|
|
25
61
|
def make_target(entry_point, cwd):
|
|
26
62
|
"""Create a target function that runs the agent from a specific directory."""
|
|
27
63
|
def target(inputs):
|
|
@@ -132,6 +168,7 @@ def main():
|
|
|
132
168
|
config = json.load(f)
|
|
133
169
|
|
|
134
170
|
os.environ["EVAL_TASK_TIMEOUT"] = str(args.timeout)
|
|
171
|
+
ensure_langsmith_api_key()
|
|
135
172
|
|
|
136
173
|
from langsmith import Client
|
|
137
174
|
client = Client()
|
package/tools/setup.py
CHANGED
|
@@ -25,12 +25,58 @@ Requires: pip install langsmith openevals
|
|
|
25
25
|
import argparse
|
|
26
26
|
import json
|
|
27
27
|
import os
|
|
28
|
+
import platform
|
|
28
29
|
import subprocess
|
|
29
30
|
import sys
|
|
30
31
|
import tempfile
|
|
31
32
|
from datetime import datetime, timezone
|
|
32
33
|
|
|
33
34
|
|
|
35
|
+
def ensure_langsmith_api_key():
|
|
36
|
+
"""Load LANGSMITH_API_KEY from credentials file if not in env.
|
|
37
|
+
|
|
38
|
+
The installer saves the key to the langsmith-cli credentials file,
|
|
39
|
+
but the SDK only reads the env var. This bridges the gap.
|
|
40
|
+
"""
|
|
41
|
+
if os.environ.get("LANGSMITH_API_KEY"):
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
# Platform-specific credentials path (matches langsmith-cli)
|
|
45
|
+
if platform.system() == "Darwin":
|
|
46
|
+
creds_path = os.path.expanduser("~/Library/Application Support/langsmith-cli/credentials")
|
|
47
|
+
else:
|
|
48
|
+
creds_path = os.path.expanduser("~/.config/langsmith-cli/credentials")
|
|
49
|
+
|
|
50
|
+
if os.path.exists(creds_path):
|
|
51
|
+
try:
|
|
52
|
+
with open(creds_path) as f:
|
|
53
|
+
for line in f:
|
|
54
|
+
line = line.strip()
|
|
55
|
+
if line.startswith("LANGSMITH_API_KEY="):
|
|
56
|
+
key = line.split("=", 1)[1].strip()
|
|
57
|
+
if key:
|
|
58
|
+
os.environ["LANGSMITH_API_KEY"] = key
|
|
59
|
+
return True
|
|
60
|
+
except OSError:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
# Also check .env in current directory
|
|
64
|
+
if os.path.exists(".env"):
|
|
65
|
+
try:
|
|
66
|
+
with open(".env") as f:
|
|
67
|
+
for line in f:
|
|
68
|
+
line = line.strip()
|
|
69
|
+
if line.startswith("LANGSMITH_API_KEY=") and not line.startswith("#"):
|
|
70
|
+
key = line.split("=", 1)[1].strip().strip("'\"")
|
|
71
|
+
if key:
|
|
72
|
+
os.environ["LANGSMITH_API_KEY"] = key
|
|
73
|
+
return True
|
|
74
|
+
except OSError:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
|
|
34
80
|
def check_dependencies():
|
|
35
81
|
"""Verify langsmith and openevals are installed."""
|
|
36
82
|
missing = []
|
|
@@ -294,6 +340,12 @@ def main():
|
|
|
294
340
|
print(f"Install with: pip install {' '.join(missing)}", file=sys.stderr)
|
|
295
341
|
sys.exit(1)
|
|
296
342
|
|
|
343
|
+
# Load API key from credentials file if not in env
|
|
344
|
+
if not ensure_langsmith_api_key():
|
|
345
|
+
print("LANGSMITH_API_KEY not found in environment, credentials file, or .env", file=sys.stderr)
|
|
346
|
+
print("Set it with: export LANGSMITH_API_KEY=lsv2_pt_...", file=sys.stderr)
|
|
347
|
+
sys.exit(1)
|
|
348
|
+
|
|
297
349
|
from langsmith import Client
|
|
298
350
|
client = Client()
|
|
299
351
|
|