Skip to content

Commit 0e6ad20

Browse files
committed
temp
1 parent cd46089 commit 0e6ad20

8 files changed

Lines changed: 281 additions & 0 deletions

tests/e2e/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""End-to-end tests runnable as standalone scripts.
2+
3+
Run from repo root, e.g.:
4+
python tests/e2e/test_middle_out_basic.py
5+
"""
6+

tests/e2e/_client.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import os
2+
import sys
3+
from pathlib import Path
4+
5+
6+
def _import_client():
7+
try:
8+
from acontext import AcontextClient # type: ignore
9+
10+
return AcontextClient
11+
except ModuleNotFoundError:
12+
repo_root = Path(__file__).resolve().parents[2]
13+
sdk_src = repo_root / "src" / "client" / "acontext-py" / "src"
14+
sys.path.insert(0, str(sdk_src))
15+
from acontext import AcontextClient # type: ignore
16+
17+
return AcontextClient
18+
19+
20+
AcontextClient = _import_client()
21+
22+
BASE_URL = os.environ.get("BASE_URL", "http://localhost:8080")
23+
24+
if "API_KEY" not in os.environ:
25+
raise RuntimeError(
26+
"Missing API_KEY. Run with e.g. `API_KEY=... python tests/e2e/test_middle_out_basic.py`"
27+
)
28+
29+
API_KEY = os.environ["API_KEY"]
30+
31+
client = AcontextClient(
32+
api_key=API_KEY,
33+
base_url=BASE_URL,
34+
)
35+

tests/e2e/_helpers.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from __future__ import annotations
2+
3+
from typing import Any, List
4+
5+
from tests.e2e._client import client
6+
7+
8+
def new_session() -> str:
9+
session = client.sessions.create()
10+
return session.id
11+
12+
13+
def store_text(session_id: str, text: str) -> None:
14+
client.sessions.store_message(
15+
session_id,
16+
format="acontext",
17+
blob={
18+
"role": "user",
19+
"parts": [{"type": "text", "text": text}],
20+
},
21+
)
22+
23+
24+
def _extract_texts_from_acontext_messages(items: list[Any]) -> list[str]:
25+
texts: list[str] = []
26+
for message in items:
27+
for part in getattr(message, "parts", []) or []:
28+
if getattr(part, "type", None) == "text" and getattr(part, "text", None):
29+
texts.append(part.text)
30+
return texts
31+
32+
33+
def _extract_texts_from_openai_messages(items: list[Any]) -> list[str]:
34+
texts: list[str] = []
35+
for message in items:
36+
if isinstance(message, dict):
37+
content = message.get("content")
38+
if isinstance(content, str) and content:
39+
texts.append(content)
40+
return texts
41+
42+
43+
def get_texts(session_id: str, **kwargs: Any) -> List[str]:
44+
resp = client.sessions.get_messages(session_id, **kwargs)
45+
format_ = kwargs.get("format", "openai")
46+
if format_ == "acontext":
47+
return _extract_texts_from_acontext_messages(resp.items)
48+
if format_ == "openai":
49+
return _extract_texts_from_openai_messages(resp.items)
50+
return []
51+
52+
53+
def banner(title: str) -> None:
54+
print("\n" + "=" * 80)
55+
print(title)
56+
print("=" * 80)
57+

tests/e2e/test_middle_out_basic.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from tests.e2e._helpers import banner, get_texts, new_session, store_text
2+
3+
4+
def main() -> None:
5+
banner("middle_out preserves head and tail")
6+
7+
sid = new_session()
8+
9+
for i in range(30):
10+
store_text(sid, f"msg-{i} " + "x" * 200)
11+
12+
texts = get_texts(
13+
sid,
14+
format="acontext",
15+
edit_strategies=[
16+
{
17+
"type": "middle_out",
18+
"params": {"token_reduce_to": 500},
19+
}
20+
],
21+
)
22+
23+
for t in texts:
24+
print(t[:20])
25+
26+
print("\nEXPECT:")
27+
print("- msg-0, msg-1 present")
28+
print("- msg-28, msg-29 present")
29+
print("- gaps in the middle")
30+
31+
32+
if __name__ == "__main__":
33+
main()
34+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from tests.e2e._helpers import banner, get_texts, new_session, store_text
2+
3+
4+
def main() -> None:
5+
banner("even-count determinism (right-middle removed)")
6+
7+
sid = new_session()
8+
9+
for m in ["m0", "m1", "m2", "m3"]:
10+
store_text(sid, m)
11+
12+
texts = get_texts(
13+
sid,
14+
format="acontext",
15+
edit_strategies=[
16+
{
17+
"type": "middle_out",
18+
"params": {"token_reduce_to": 10},
19+
}
20+
],
21+
)
22+
23+
print("Returned:", texts)
24+
print("\nEXPECT:")
25+
print("- m2 is missing")
26+
27+
28+
if __name__ == "__main__":
29+
main()
30+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from tests.e2e._helpers import banner, get_texts, new_session, store_text
2+
3+
4+
def main() -> None:
5+
banner("keep-tail fallback")
6+
7+
sid = new_session()
8+
9+
store_text(sid, "old " + "x" * 200)
10+
store_text(sid, "new " + "x" * 200)
11+
12+
texts = get_texts(
13+
sid,
14+
format="acontext",
15+
edit_strategies=[
16+
{
17+
"type": "middle_out",
18+
"params": {"token_reduce_to": 10},
19+
}
20+
],
21+
)
22+
23+
print("Returned:", texts)
24+
print("\nEXPECT:")
25+
print("- only 'new' remains")
26+
27+
28+
if __name__ == "__main__":
29+
main()
30+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import json
2+
3+
from tests.e2e._client import client
4+
from tests.e2e._helpers import banner, new_session, store_text
5+
6+
7+
def main() -> None:
8+
banner("tool-call / tool-result pairing")
9+
10+
sid = new_session()
11+
12+
client.sessions.store_message(
13+
sid,
14+
format="openai",
15+
blob={
16+
"role": "assistant",
17+
"tool_calls": [
18+
{
19+
"id": "call_1",
20+
"type": "function",
21+
"function": {"name": "f", "arguments": "{}"},
22+
}
23+
],
24+
},
25+
)
26+
27+
client.sessions.store_message(
28+
sid,
29+
format="openai",
30+
blob={
31+
"role": "tool",
32+
"tool_call_id": "call_1",
33+
"content": "ok",
34+
},
35+
)
36+
37+
store_text(sid, "noise")
38+
39+
resp = client.sessions.get_messages(
40+
sid,
41+
format="openai",
42+
edit_strategies=[
43+
{
44+
"type": "middle_out",
45+
"params": {"token_reduce_to": 50},
46+
}
47+
],
48+
)
49+
50+
print(json.dumps(resp.model_dump(), indent=2))
51+
52+
print("\nEXPECT:")
53+
print("- tool-call and tool-result appear together or not at all")
54+
55+
56+
if __name__ == "__main__":
57+
main()
58+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from tests.e2e._client import client
2+
from tests.e2e._helpers import banner, new_session
3+
4+
5+
def main() -> None:
6+
banner("validation errors")
7+
8+
sid = new_session()
9+
10+
cases = [
11+
{"type": "middle_out", "params": {}},
12+
{"type": "middle_out", "params": {"token_reduce_to": "x"}},
13+
{"type": "middle_out", "params": {"token_reduce_to": 0}},
14+
]
15+
16+
for c in cases:
17+
print("\nCase:", c)
18+
try:
19+
client.sessions.get_messages(
20+
sid,
21+
format="acontext",
22+
edit_strategies=[c], # type: ignore[arg-type]
23+
)
24+
print("❌ Unexpected success")
25+
except Exception as e:
26+
print("✅ Error:", e)
27+
28+
29+
if __name__ == "__main__":
30+
main()
31+

0 commit comments

Comments
 (0)