-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest_engine_integration.py
More file actions
237 lines (171 loc) · 6.09 KB
/
test_engine_integration.py
File metadata and controls
237 lines (171 loc) · 6.09 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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
"""Test AgentEngine integration"""
import asyncio
from loom import AgentConfig, ModelRef, create_agent, tool
from loom.providers.base import CompletionParams, LLMProvider
from loom.runtime.engine import AgentEngine, EngineConfig
@tool(description="Add two numbers")
def add(a: int, b: int) -> int:
"""Add two numbers together"""
return a + b
@tool(description="Multiply two numbers")
def multiply(a: int, b: int) -> int:
"""Multiply two numbers"""
return a * b
async def test_engine_basic():
"""Test basic engine execution without provider"""
print("\n=== Test 1: Basic Engine (No Provider) ===")
agent = create_agent(
AgentConfig(
model=ModelRef.anthropic("claude-sonnet-4"),
instructions="You are a helpful assistant",
)
)
result = await agent.run("Hello, world!")
print(f"Status: {result.state}")
print(f"Output: {result.output}")
print(f"Duration: {result.duration_ms}ms")
assert result.state.value in ["completed", "failed"]
print("✓ Basic engine test passed")
async def test_engine_with_tools():
"""Test engine with tools"""
print("\n=== Test 2: Engine with Tools ===")
agent = create_agent(
AgentConfig(
model=ModelRef.anthropic("claude-sonnet-4"),
instructions="You are a calculator",
tools=[add, multiply],
)
)
assert len(agent.config.tools) == 2
print(f"✓ Registered {len(agent.config.tools)} tools")
from loom.tools.schema import Tool as EngineToolSchema
converted = agent._convert_tool_to_schema(agent._compiled_tools[0])
assert isinstance(converted, EngineToolSchema)
print("✓ Tool conversion works")
async def test_runtime_fallback():
"""Test fallback behavior when no provider is available"""
print("\n=== Test 3: Fallback Behavior ===")
agent = create_agent(
AgentConfig(
model=ModelRef.anthropic("claude-sonnet-4"),
instructions="You are a helpful assistant",
)
)
result = await agent.run("Test")
print(f"Status: {result.state}")
print(f"Output: {result.output}")
assert result.state.value in ["completed", "failed"]
print("✓ Runtime fallback works")
async def test_engine_components():
"""Test engine components directly"""
print("\n=== Test 4: Engine Components ===")
# Mock provider for testing
class MockProvider(LLMProvider):
async def _complete(self, _messages: list, _params: CompletionParams | None = None) -> str:
return "Mock response: Task completed successfully"
def stream(self, _messages: list, _params: CompletionParams | None = None):
async def _gen():
yield "Mock"
yield " response"
return _gen()
provider = MockProvider()
config = EngineConfig(
max_iterations=10,
max_tokens=100000,
enable_heartbeat=False,
enable_safety=True,
enable_memory=False,
)
engine = AgentEngine(provider=provider, config=config)
# Test execution
result = await engine.execute(
goal="Test goal",
instructions="Test instructions",
context={"test": "value"},
)
print(f"Result status: {result.get('status')}")
print(f"Result output: {result.get('output')}")
print(f"Iterations: {result.get('iterations')}")
assert result.get("status") in ["success", "max_iterations"]
print("✓ Engine components work")
async def test_context_manager():
"""Test context manager integration"""
print("\n=== Test 5: Context Manager ===")
from loom.context import ContextManager
ctx = ContextManager(max_tokens=100000)
# Test rho calculation
rho = ctx.rho
print(f"Initial ρ: {rho:.4f}")
assert 0 <= rho <= 1
# Test compression check
strategy = ctx.should_compress()
print(f"Compression strategy: {strategy}")
# Test renewal check
should_renew = ctx.should_renew()
print(f"Should renew: {should_renew}")
print("✓ Context manager works")
async def test_tool_registry():
"""Test tool registry"""
print("\n=== Test 6: Tool Registry ===")
from loom.tools.registry import ToolRegistry
from loom.tools.schema import Tool, ToolDefinition
registry = ToolRegistry()
# Create test tool
definition = ToolDefinition(
name="test_tool",
description="Test tool",
is_read_only=True,
)
async def handler(**_kwargs):
return "test result"
tool = Tool(definition=definition, handler=handler)
# Register
registry.register(tool)
assert registry.get("test_tool") is not None
# List
tools = registry.list_tools()
assert len(tools) == 1
assert tools[0].name == "test_tool"
print("✓ Tool registry works")
async def test_veto_authority():
"""Test veto authority"""
print("\n=== Test 7: Veto Authority ===")
from loom.safety.veto import VetoAuthority, VetoRule
veto = VetoAuthority()
# Add rule
rule = VetoRule(
name="no_delete",
predicate=lambda tool, _args: tool == "delete_file",
reason="Deletion not allowed",
)
veto.add_rule(rule)
# Test veto
vetoed, reason = veto.check_tool("delete_file", {})
assert vetoed
assert "not allowed" in reason.lower()
# Test allowed tool
vetoed, reason = veto.check_tool("read_file", {})
assert not vetoed
print(f"✓ Veto authority works (vetoed: {len(veto.veto_log)} calls)")
async def main():
"""Run all tests"""
print("=" * 60)
print("Testing AgentEngine Integration")
print("=" * 60)
try:
await test_engine_basic()
await test_engine_with_tools()
await test_runtime_fallback()
await test_engine_components()
await test_context_manager()
await test_tool_registry()
await test_veto_authority()
print("\n" + "=" * 60)
print("✅ All tests passed!")
print("=" * 60)
except Exception as e:
print(f"\n❌ Test failed: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
asyncio.run(main())