f3d80b4628
Auto Release / auto-release (push) Failing after 1s
CI / lint (push) Failing after 0s
CI / screenshot-quality (push) Failing after 3s
CI / pr-policy (push) Has been skipped
CI / test (3.11) (push) Failing after 0s
CI / test (3.12) (push) Failing after 0s
CI / test (3.13) (push) Failing after 3s
CI / coverage (push) Failing after 1s
Legibility / legibility (push) Failing after 3s
70 lines
2.4 KiB
Python
70 lines
2.4 KiB
Python
"""Viewer regression test: opencode traces must not be mislabelled as Claude Code.
|
|
|
|
opencode's system prompt begins with "You are opencode, ..." but may also
|
|
mention "Claude Code" later (e.g. in agent-builder examples). The sidebar
|
|
fingerprint heuristic must prefer the explicit self-identification.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
import pytest
|
|
|
|
pw_missing = False
|
|
try:
|
|
from playwright.sync_api import sync_playwright # noqa: F401
|
|
except ImportError:
|
|
pw_missing = True
|
|
|
|
|
|
@pytest.mark.skipif(pw_missing, reason="playwright not installed")
|
|
def test_opencode_prompt_is_labelled_opencode_not_claude_code(tmp_path) -> None:
|
|
from playwright.sync_api import sync_playwright
|
|
|
|
from claude_tap.viewer import _generate_html_viewer
|
|
|
|
# Mirror the real opencode system prompt shape: opens with the
|
|
# "You are opencode" self-id, then mentions "Claude Code" deep inside
|
|
# an example list. The pre-fix heuristic stopped at the first match
|
|
# and labelled the trace "Claude Code".
|
|
system_prompt = (
|
|
"You are opencode, an interactive CLI tool that helps users with "
|
|
"software engineering tasks.\n"
|
|
"Use the instructions below and the tools available to you to assist the user.\n"
|
|
+ ("filler ... " * 200)
|
|
+ "\n(4) ask about Claude Code, Cursor, or similar agent internals\n"
|
|
+ ("filler ... " * 200)
|
|
)
|
|
|
|
trace_path = tmp_path / "trace.jsonl"
|
|
record = {
|
|
"timestamp": "2026-05-01T23:46:43+00:00",
|
|
"request_id": "req_1",
|
|
"turn": 1,
|
|
"duration_ms": 100,
|
|
"request": {
|
|
"method": "POST",
|
|
"path": "/anthropic/v1/messages",
|
|
"headers": {},
|
|
"body": {
|
|
"system": system_prompt,
|
|
"messages": [{"role": "user", "content": [{"type": "text", "text": "ping"}]}],
|
|
},
|
|
},
|
|
"response": {"status": 200, "headers": {}, "body": {"content": [], "usage": {}}},
|
|
}
|
|
trace_path.write_text(json.dumps(record) + "\n", encoding="utf-8")
|
|
|
|
html_path = tmp_path / "trace.html"
|
|
_generate_html_viewer(trace_path, html_path)
|
|
|
|
with sync_playwright() as p:
|
|
browser = p.chromium.launch()
|
|
page = browser.new_page()
|
|
page.goto(html_path.resolve().as_uri(), wait_until="networkidle")
|
|
label = page.locator(".sidebar-item .si-task").first.inner_text()
|
|
browser.close()
|
|
|
|
assert label == "OpenCode", f"opencode trace mislabelled as {label!r}"
|