Repository navigation
Expand file tree
/
Copy pathtest_native.py
More file actions
205 lines (161 loc) · 6.6 KB
/
Copy pathtest_native.py
File metadata and controls
205 lines (161 loc) · 6.6 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/env python3
"""
Test the Pyodide shims in native Python.
Simulates the Pyodide environment by setting PYODIDE=1, then verifies
that the patched hermes-agent code runs correctly with the shims.
Run this AFTER apply_patches.py has created the patched tree.
Usage:
python test_native.py [--hermes-dir ./hermes-agent]
"""
import argparse
import os
import sys
def test_shims_import():
"""Test that pyodide_shims imports and detects environment."""
print("1. Testing pyodide_shims import...")
import pyodide_shims
print(f" IN_PYODIDE = {pyodide_shims.IN_PYODIDE}")
# When PYODIDE=1, shims should be active
if os.environ.get("PYODIDE") == "1":
assert pyodide_shims.IN_PYODIDE, "Should detect PYODIDE=1"
print(" ✓ Detected simulated Pyodide environment")
else:
print(" ✓ Running in native mode (shims inactive)")
def test_threading_shim():
"""Test that Thread shim runs synchronously."""
print("\n2. Testing threading shim...")
import threading
results = []
def worker(x):
results.append(x * 2)
t = threading.Thread(target=worker, args=(21,))
t.start()
t.join()
if os.environ.get("PYODIDE") == "1":
# In shim mode, result should already be available (sync execution)
assert results == [42], f"Expected [42], got {results}"
assert not t.is_alive(), "Thread should not be alive after sync execution"
print(" ✓ Thread ran synchronously, result = 42")
else:
# In native mode, thread ran normally
assert results == [42], f"Expected [42], got {results}"
print(" ✓ Thread ran normally, result = 42")
def test_threadpool_shim():
"""Test that ThreadPoolExecutor shim works."""
print("\n3. Testing ThreadPoolExecutor shim...")
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
future = pool.submit(lambda x: x ** 2, 7)
result = future.result(timeout=5)
assert result == 49, f"Expected 49, got {result}"
print(f" ✓ ThreadPoolExecutor result = {result}")
def test_run_sync():
"""Test the async bridging helper."""
print("\n4. Testing run_sync (async bridging)...")
import asyncio
from pyodide_shims import run_sync
async def async_add(a, b):
return a + b
result = run_sync(async_add(3, 4))
assert result == 7, f"Expected 7, got {result}"
print(f" ✓ run_sync(async_add(3, 4)) = {result}")
def test_openai_client_creation():
"""Test that make_openai_client works (without actually calling an API)."""
print("\n5. Testing OpenAI client creation...")
try:
import httpx
from pyodide_shims import make_openai_client
# In native mode, this just creates a normal client
# In PYODIDE mode, it would inject the fetch transport
# Either way it shouldn't crash
client = make_openai_client(api_key="test-key", base_url="http://localhost:1/v1")
print(f" ✓ Client created: {type(client).__name__}")
except ImportError as e:
print(f" ⚠ Skipped (missing dep): {e}")
def test_hermes_imports(hermes_dir):
"""Test that the patched hermes-agent modules import correctly."""
print("\n6. Testing patched hermes-agent imports...")
sys.path.insert(0, str(hermes_dir))
# These should all import without errors
modules = [
("hermes_constants", "Constants"),
("toolsets", "Toolsets"),
("tools.registry", "Tool registry"),
("tools.interrupt", "Interrupt"),
("tools.fuzzy_match", "Fuzzy match"),
]
for mod_name, label in modules:
try:
__import__(mod_name)
print(f" ✓ {label} ({mod_name})")
except Exception as e:
print(f" ✗ {label} ({mod_name}): {e}")
# These need more deps but should at least not crash on the patched parts
try:
from agent.display import KawaiiSpinner, build_tool_preview
spinner = KawaiiSpinner("testing...", spinner_type="dots")
spinner.start()
spinner.update_text("still testing")
spinner.stop("done!")
print(" ✓ KawaiiSpinner (no-op version)")
except Exception as e:
print(f" ✗ KawaiiSpinner: {e}")
try:
from tools.interrupt import set_interrupt, is_interrupted
set_interrupt(True)
assert is_interrupted()
set_interrupt(False)
assert not is_interrupted()
print(" ✓ Interrupt mechanism")
except Exception as e:
print(f" ✗ Interrupt: {e}")
def test_tool_registry(hermes_dir):
"""Test that the tool registry works with patched code."""
print("\n7. Testing tool registry...")
sys.path.insert(0, str(hermes_dir))
from tools.registry import ToolRegistry
reg = ToolRegistry()
reg.register(
name="test_tool",
toolset="test",
schema={"name": "test_tool", "description": "A test tool", "parameters": {}},
handler=lambda args, **kw: '{"result": "ok"}',
)
defs = reg.get_definitions({"test_tool"})
assert len(defs) == 1
assert defs[0]["function"]["name"] == "test_tool"
print(f" ✓ Registered and retrieved 1 tool definition")
result = reg.dispatch("test_tool", {})
assert '"result"' in result
print(f" ✓ Dispatched tool call, got: {result}")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--hermes-dir", type=str,
default=os.path.join(os.path.dirname(__file__), "hermes-agent"))
parser.add_argument("--simulate-pyodide", action="store_true",
help="Set PYODIDE=1 to test shims as if in Pyodide")
args = parser.parse_args()
if args.simulate_pyodide:
os.environ["PYODIDE"] = "1"
print("🔧 Simulating Pyodide environment (PYODIDE=1)\n")
else:
print("🐍 Running in native Python mode\n")
# Import shims first (this applies monkey-patches if PYODIDE=1)
sys.path.insert(0, os.path.dirname(__file__))
import pyodide_shims
test_shims_import()
test_threading_shim()
test_threadpool_shim()
test_run_sync()
test_openai_client_creation()
hermes_dir = os.path.abspath(args.hermes_dir)
if os.path.isdir(hermes_dir) and os.path.exists(os.path.join(hermes_dir, "run_agent.py")):
test_hermes_imports(hermes_dir)
test_tool_registry(hermes_dir)
else:
print(f"\n⚠ Skipping hermes-agent import tests ({hermes_dir} not found)")
print(f" Run apply_patches.py first to create the patched tree.")
print(f"\n{'=' * 60}")
print("✅ All tests passed!")
if __name__ == "__main__":
main()