-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_encode.py
More file actions
146 lines (116 loc) · 4.56 KB
/
test_encode.py
File metadata and controls
146 lines (116 loc) · 4.56 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
import pytest
from memevolve.components.encode import ExperienceEncoder
import sys
# sys.path.insert(0, 'src') # No longer needed with package structure
@pytest.fixture
def encoder():
"""Create an ExperienceEncoder instance for testing."""
from dotenv import load_dotenv
load_dotenv() # Ensure .env is loaded
# Let the encoder handle environment variable loading and fallback internally
return ExperienceEncoder()
def test_encoder_initialization(encoder):
import os
expected_base_url = os.getenv("MEMEVOLVE_MEMORY_BASE_URL") or os.getenv(
"MEMEVOLVE_UPSTREAM_BASE_URL")
assert encoder.base_url == expected_base_url
assert encoder.api_key == os.getenv("MEMEVOLVE_MEMORY_API_KEY", "")
assert encoder.client is None
def test_encoder_client_not_initialized(encoder):
with pytest.raises(RuntimeError, match="Memory API client not initialized"):
encoder.encode_experience({"id": "test"})
def test_save_and_load_units(encoder, tmp_path):
units = [
{
"type": "lesson",
"content": "Test content",
"metadata": {"key": "value"},
"tags": ["test"]
}
]
filename = tmp_path / "test_units.json"
encoder.save_units(units, str(filename))
loaded = encoder.load_units(str(filename))
assert len(loaded) == 1
assert loaded[0]["type"] == "lesson"
def test_load_nonexistent_file(encoder):
result = encoder.load_units("nonexistent.json")
assert result == []
def test_batch_encoding_trajectory():
"""Test batch encoding functionality."""
import os
from dotenv import load_dotenv
load_dotenv()
encoder = ExperienceEncoder(
base_url=os.getenv("MEMEVOLVE_MEMORY_BASE_URL")
)
# Test batch encoding with empty trajectory
result = encoder.encode_trajectory_batch([])
assert result == []
# Test batch encoding with sample trajectory
trajectory = [
{"id": "exp1", "action": "search", "result": "found item"},
{"id": "exp2", "action": "sort", "result": "sorted array"},
{"id": "exp3", "action": "filter", "result": "filtered data"}
]
# This will attempt to call LLM, but should handle gracefully
result = encoder.encode_trajectory_batch(
trajectory, max_workers=2, batch_size=2)
# Note: This test may fail if LLM is not available, but tests the interface
assert isinstance(result, list)
def test_tool_encoding_prompt_structure():
"""Test that tool encoding is included in the prompt."""
import os
from dotenv import load_dotenv
load_dotenv()
encoder = ExperienceEncoder(
base_url=os.getenv("MEMEVOLVE_MEMORY_BASE_URL")
)
# Check that the prompt includes tool as an option
# We can't easily test the full encoding without LLM, but we can check prompt is constructed
experience = {"id": "test", "action": "algorithm",
"result": "binary search"}
# The encode_experience method will fail without LLM client, but let's check the prompt is constructed
# This is more of an integration test that would need mocking
assert encoder.base_url is not None
def test_clean_memory_api_response():
"""Test Memory API response cleaning functionality."""
import os
from dotenv import load_dotenv
load_dotenv()
encoder = ExperienceEncoder(
base_url=os.getenv("MEMEVOLVE_MEMORY_BASE_URL")
)
# Test markdown code block removal
markdown_response = '''```json
{
"type": "lesson",
"content": "Test content",
"metadata": {},
"tags": ["test"]
}
```'''
cleaned = encoder._clean_memory_api_response(markdown_response)
assert cleaned.startswith('{')
assert '"type": "lesson"' in cleaned
assert not cleaned.startswith('```')
# Test plain JSON (should pass through)
plain_json = '{"type": "tool", "content": "Test tool"}'
cleaned_plain = encoder._clean_memory_api_response(plain_json)
assert cleaned_plain == plain_json
# Test JSON with extra text
mixed_response = 'Here is the JSON: {"type": "skill", "content": "Test skill"} and some extra text'
cleaned_mixed = encoder._clean_memory_api_response(mixed_response)
assert cleaned_mixed == '{"type": "skill", "content": "Test skill"}'
# Test invalid response
try:
encoder._clean_memory_api_response("No JSON here")
assert False, "Should have raised ValueError"
except ValueError:
pass # Expected
# Test empty response
try:
encoder._clean_memory_api_response("")
assert False, "Should have raised ValueError"
except ValueError:
pass # Expected