Files
cleveragents-core/robot/helper_session_model.py

209 lines
5.7 KiB
Python

"""Robot Framework helper for Session domain model smoke tests.
Provides a CLI-style interface for Robot to invoke session model
operations and verify outputs. Exit code 0 = success, 1 = failure.
Usage:
python robot/helper_session_model.py create
python robot/helper_session_model.py append-messages
python robot/helper_session_model.py export
python robot/helper_session_model.py cli-dict
python robot/helper_session_model.py export-key-order
"""
from __future__ import annotations
import sys
from pathlib import Path
# Ensure the src directory is on the import path.
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
sys.path.insert(0, _SRC)
from ulid import ULID # noqa: E402
from cleveragents.domain.models.core.session import ( # noqa: E402
EXPORT_SCHEMA_VERSION,
MessageRole,
Session,
)
def _make_session() -> Session:
"""Create a minimal valid Session."""
return Session(session_id=str(ULID()))
def _cmd_create() -> int:
"""Create a session and verify fields."""
session = _make_session()
if not session.session_id:
print("session-create-fail: missing session_id")
return 1
if session.namespace != "local":
print(f"session-create-fail: namespace={session.namespace}")
return 1
if not session.is_empty:
print("session-create-fail: session should be empty")
return 1
print(f"session-create-ok: id={session.session_id}")
return 0
def _cmd_append_messages() -> int:
"""Create a session, append messages, verify ordering."""
session = _make_session()
session.append_message(MessageRole.USER, "Hello")
session.append_message(MessageRole.ASSISTANT, "Hi there")
session.append_message(MessageRole.USER, "How are you?")
if session.message_count != 3:
print(f"session-append-fail: count={session.message_count}")
return 1
# Verify sequences are 0, 1, 2
sequences = [m.sequence for m in session.messages]
if sequences != [0, 1, 2]:
print(f"session-append-fail: sequences={sequences}")
return 1
# Verify last message
last = session.last_message
if last is None or last.content != "How are you?":
print("session-append-fail: wrong last message")
return 1
print("session-append-ok: 3 messages in order")
return 0
def _cmd_export() -> int:
"""Create a session with messages, export, verify keys."""
session = _make_session()
session.append_message(MessageRole.USER, "Hello")
session.append_message(MessageRole.ASSISTANT, "Hi there")
export = session.as_export_dict()
required_keys = [
"schema_version",
"session_id",
"actor_name",
"namespace",
"messages",
"linked_plan_ids",
"token_usage",
"metadata",
"created_at",
"updated_at",
"checksum",
]
for key in required_keys:
if key not in export:
print(f"session-export-fail: missing key '{key}'")
return 1
if export["schema_version"] != EXPORT_SCHEMA_VERSION:
print(f"session-export-fail: schema_version={export['schema_version']}")
return 1
if len(export["messages"]) != 2:
print(f"session-export-fail: messages count={len(export['messages'])}")
return 1
print("session-export-ok: all keys present")
return 0
def _cmd_cli_dict() -> int:
"""Create a session with messages, get CLI dict, verify keys."""
session = _make_session()
session.append_message(MessageRole.USER, "Hello")
cli = session.as_cli_dict()
required_keys = [
"session_id",
"namespace",
"message_count",
"created_at",
"updated_at",
"token_usage",
]
for key in required_keys:
if key not in cli:
print(f"session-cli-dict-fail: missing key '{key}'")
return 1
if cli["message_count"] != 1:
print(f"session-cli-dict-fail: message_count={cli['message_count']}")
return 1
print("session-cli-dict-ok: all keys present")
return 0
def _cmd_export_key_order() -> int:
"""Verify export dict keys appear in expected serialization order."""
session = _make_session()
session.append_message(MessageRole.USER, "Hello")
export = session.as_export_dict()
expected_order = [
"schema_version",
"session_id",
"actor_name",
"namespace",
"messages",
"linked_plan_ids",
"token_usage",
"metadata",
"created_at",
"updated_at",
"checksum",
]
actual_keys = list(export.keys())
if actual_keys != expected_order:
print(f"session-export-order-fail: {actual_keys}")
return 1
# Verify messages within export are ordered by sequence
seqs = [m["sequence"] for m in export["messages"]]
if seqs != sorted(seqs):
print(f"session-export-order-fail: message sequences={seqs}")
return 1
print("session-export-order-ok")
return 0
_COMMANDS: dict[str, object] = {
"create": _cmd_create,
"append-messages": _cmd_append_messages,
"export": _cmd_export,
"cli-dict": _cmd_cli_dict,
"export-key-order": _cmd_export_key_order,
}
def main() -> int:
"""Entry point called by Robot Framework ``Run Process``."""
if len(sys.argv) < 2:
print(
"Usage: helper_session_model.py"
" <create|append-messages|export|cli-dict|export-key-order>"
)
return 1
command = sys.argv[1]
handler = _COMMANDS.get(command)
if handler is None:
print(f"Unknown command: {command}")
return 1
return handler() # type: ignore[operator]
if __name__ == "__main__":
sys.exit(main())