import json import sys from hermes_cli.session_export import export_record_count, render_sessions_export from hermes_cli.session_export_html import ( _generate_messages_html, generate_multi_session_html_export, ) def _sample_session(): return { "id": "sess-123", "source": "cli", "model": "test/model", "title": "Debug auth flow", "started_at": 1700000000, "message_count": 5, "messages": [ { "id": 1, "role": "system", "content": "hidden system context", "timestamp": 1700000000, }, { "id": 2, "role": "user", "content": "Why is login broken?", "timestamp": 1700000001, "platform_message_id": "evt-2", }, { "id": 3, "role": "assistant", "content": "I will inspect the auth middleware.", "timestamp": 1700000002, }, { "id": 4, "role": "tool", "tool_name": "read_file", "content": "def redirect_after_login(): pass", "timestamp": 1700000003, }, { "id": 5, "role": "user", "content": [{"type": "text", "text": "Only show me the prompts."}], "timestamp": 1700000004, }, ], } def test_default_jsonl_preserves_full_session_shape(): session = _sample_session() rendered = render_sessions_export([session]) assert [json.loads(line) for line in rendered.splitlines()] == [session] def test_prompt_only_jsonl_emits_one_record_per_user_prompt(): rendered = render_sessions_export( [_sample_session()], only="user-prompts", ) records = [json.loads(line) for line in rendered.splitlines()] assert records == [ { "session_id": "sess-123", "index": 1, "created_at": "2023-11-14T22:13:21Z", "role": "user", "text": "Why is login broken?", "message_id": 2, "event_id": "evt-2", }, { "session_id": "sess-123", "index": 2, "created_at": "2023-11-14T22:13:24Z", "role": "user", "text": "Only show me the prompts.", "message_id": 5, }, ] def test_prompt_only_markdown_excludes_assistant_tool_and_system_content(): rendered = render_sessions_export( [_sample_session()], fmt="markdown", only="user-prompts", ) assert "# User prompts for session sess-123" in rendered assert "## 1. 2023-11-14T22:13:21Z" in rendered assert "Why is login broken?" in rendered assert "Only show me the prompts." in rendered assert "I will inspect the auth middleware." not in rendered assert "def redirect_after_login" not in rendered assert "hidden system context" not in rendered def test_full_markdown_renderer_collapses_tool_output_and_filters_system(): rendered = render_sessions_export([_sample_session()], fmt="markdown") assert "# Session: Debug auth flow" in rendered assert "## User - 2023-11-14T22:13:21Z" in rendered assert "## Assistant - 2023-11-14T22:13:22Z" in rendered assert "
read_file" in rendered assert "```text\ndef redirect_after_login(): pass\n```" in rendered assert "hidden system context" not in rendered def test_html_export_escapes_tool_call_names(): payload = '' rendered = _generate_messages_html( [ { "role": "assistant", "content": "", "tool_calls": [ { "id": "call_1", "type": "function", "function": {"name": payload, "arguments": "x"}, } ], } ] ) assert payload not in rendered assert '<img src=x onerror="alert(document.domain)">' in rendered assert "<b>x</b>" in rendered def test_html_export_uses_csp_without_inline_event_handlers(): first = _sample_session() second = {**_sample_session(), "id": "sess-456", "title": "Second session"} rendered = generate_multi_session_html_export([first, second]) assert "Content-Security-Policy" in rendered assert "script-src 'nonce-" in rendered assert "