HTTP fallback leg (docs/19): e2e scenario 13 + docs
- e2e.py: scenario 13 (http fallback) — drives a full turn over the HTTP leg (health + POST /v1/frame + SSE /v1/events, no WS) and asserts the user echo lands on the SSE stream in < 1.5 s. - ws_probe.py --http: prints '== user echo in X.XXs' (the docs/19 sendable-in-fallback timing assertion) alongside the existing health/POST/SSE output; same assertion flags as the WS leg. - docs: 19 status flipped to implemented; 09-pairing-security §9.4 cross-reference (second door, same lock: token + device allowlist, 64 KiB cap, rate limit, optional TLS, unauthenticated /v1/health); 13-testing manual scenario 15 + automated pointers.
This commit is contained in:
1 parent
7f936fa596
commit
2349a95dd4
5 files changed
+61
-2
No files matched your search
@@ -740,6 +740,7 @@ def run_http(args, base: str) -> int:
|
||||
print("== SSE open (/v1/events)")
|
||||
|
||||
# 3. POST the message.send frame (accept-and-ack).
|
||||
post_time: float | None = None
|
||||
if args.send:
|
||||
frame = {
|
||||
"v": 1, "id": 1, "type": "message.send",
|
||||
@@ -753,6 +754,7 @@ def run_http(args, base: str) -> int:
|
||||
r = conn.getresponse()
|
||||
body = r.read()
|
||||
conn.close()
|
||||
post_time = time.time()
|
||||
print(f"== POST /v1/frame -> {r.status} {body[:200]!r}")
|
||||
if r.status >= 400:
|
||||
print("!! POST /v1/frame rejected")
|
||||
@@ -763,11 +765,12 @@ def run_http(args, base: str) -> int:
|
||||
st = _TurnState()
|
||||
got_final = False
|
||||
seen_final_frame = False
|
||||
echo_logged = False
|
||||
deadline = time.time() + args.timeout
|
||||
cur_data: list[str] = []
|
||||
|
||||
def feed(line: str) -> bool:
|
||||
nonlocal cur_data, got_final, seen_final_frame
|
||||
nonlocal cur_data, got_final, seen_final_frame, echo_logged
|
||||
line = line.rstrip("\r\n")
|
||||
if line == "":
|
||||
if cur_data:
|
||||
@@ -776,6 +779,14 @@ def run_http(args, base: str) -> int:
|
||||
ftype = data.get("type")
|
||||
payload = data.get("payload") or {}
|
||||
st.track(ftype, payload)
|
||||
# docs/19: the user echo must land on the SSE stream
|
||||
# promptly after the POST (the < 1 s sendable-in-fallback
|
||||
# UX assertion).
|
||||
if (not echo_logged and post_time is not None
|
||||
and ftype == "message"
|
||||
and payload.get("role") == "user"):
|
||||
echo_logged = True
|
||||
print(f"== user echo in {time.time() - post_time:.2f}s")
|
||||
if ftype == "message" and payload.get("role") == "assistant":
|
||||
got_final = True
|
||||
if ftype == "message.stop":
|
||||
|
||||
Reference in new issue
Block a user