Split the newest reply once its turn ends, and make the UI harness reusable
The transcript's remaining lag was the newest assistant reply: transcriptUnits kept the last row whole -- right while it streams (splitting a changing text is a parse per delta), wrong forever after, so a session that ends on a long reply drew it as one lazy-list item with every node alive. On a Pixel 9 Pro XL that was 13.8ms of draw phase a frame, 79% of it the framework's own per-node bookkeeping, against a 34,996px item. An AssistantMsg now carries `settled`, folded from the status event that ends its turn (status changes are transcript events with seqs, so replay settles the same way), and cleared if a delta ever grows the message again. A settled newest reply splits like every other. Folding it -- rather than reading the screen's status -- routes the resplit through the held-events gate, so it can only happen at the newest end while pinned, never under a reader. The "session is working" predicate now lives once, in sessionWorking(). Measured on the emulator, same session and gestures, a 43KB reply as the last row: draw phase 3.92ms -> 1.20ms per frame, framework share 3.07ms (78%) -> 0.54ms (45%), worst single measure 82.5ms -> 9.1ms. The report's "on screen" line went from one 60,674px AssistantMsg to five blocks of 95-846px. A live streamed turn settles and splits the moment it goes idle. The harness half, asked for by Bryan: ui-sandbox.sh now derives its port and root from the checkout name (two checkouts' sandboxes cannot reach each other), keeps its token in ~/.config/ai-app/sandbox-token and salvages enrolled device tokens across restarts (enrol the emulator once, ever), and gained the driving verbs every UI session was re-inventing in /tmp: spawn, send (text or @file), api. transcript-bench.sh is the standard scroll-and-report measurement. AGENTS.md documents all of it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
917eb9a7b3
commit
7a48f8ff1f
8 files changed
+250
-23
No files matched your search
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
# Scrolls the transcript and prints the app's own render report -- the
|
||||
# standard measurement for "is the transcript smooth", so a perf session
|
||||
# starts from a number instead of re-inventing this loop in /tmp.
|
||||
#
|
||||
# ./transcript-bench.sh restart the app, open the first
|
||||
# session, scroll, report
|
||||
# ./transcript-bench.sh -k keep whatever screen is open now
|
||||
# ./transcript-bench.sh -n 4 swipe cycles (default 6; one cycle is
|
||||
# two swipes back and two forward)
|
||||
#
|
||||
# What it prints is the report the in-app copy button produces, plus any
|
||||
# duplicate-key warnings the flatten logged. Absolute frame times from the
|
||||
# emulator are worthless (it renders in software); what transfers is the
|
||||
# report's own accounting -- what was on screen, and where the draw phase
|
||||
# went. Compare two runs of this with the same gestures, not one run
|
||||
# against a phone.
|
||||
#
|
||||
# Coordinates are the ai-app AVD's 1080x2400 screen: the report button in
|
||||
# the session top bar, and the first row of the session list.
|
||||
set -eu
|
||||
cd "$(dirname "$0")"
|
||||
. ./android-env.sh >/dev/null 2>&1
|
||||
|
||||
keep=""
|
||||
cycles=6
|
||||
while getopts kn: flag; do
|
||||
case $flag in
|
||||
k) keep=1 ;;
|
||||
n) cycles=$OPTARG ;;
|
||||
*) exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$keep" ]; then
|
||||
adb shell am force-stop com.example.aiapp
|
||||
adb shell am start -n com.example.aiapp/.MainActivity >/dev/null
|
||||
sleep 5
|
||||
ui-trace record -d 3000 --do 'tap 500 545' -o /tmp/bench-open.txt >/dev/null 2>&1
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# First tap resets the report's "work since last copied" window, so the
|
||||
# numbers cover exactly the swipes between the two taps.
|
||||
ui-trace record -d 2000 --do 'tap 723 205' -o /tmp/bench-reset.txt >/dev/null 2>&1
|
||||
adb logcat -c
|
||||
|
||||
DO=""
|
||||
i=0
|
||||
while [ "$i" -lt "$cycles" ]; do
|
||||
DO="$DO --do 'swipe 540 700 540 1600 200' --do 'wait 500'"
|
||||
DO="$DO --do 'swipe 540 700 540 1600 200' --do 'wait 500'"
|
||||
DO="$DO --do 'swipe 540 1600 540 700 200' --do 'wait 500'"
|
||||
DO="$DO --do 'swipe 540 1600 540 700 200' --do 'wait 500'"
|
||||
i=$((i + 1))
|
||||
done
|
||||
eval ui-trace record -d $((cycles * 4400 + 2000)) $DO -o /tmp/bench-scroll.txt >/dev/null 2>&1
|
||||
|
||||
ui-trace record -d 2000 --do 'tap 723 205' -o /tmp/bench-report.txt >/dev/null 2>&1
|
||||
sleep 1
|
||||
adb logcat -d -s ai-app:I | sed -n '/ai-app render report/,$p' | sed 's/^.*ai-app : //'
|
||||
adb logcat -d 2>/dev/null | grep -i "duplicate unit key" | head -3 || true
|
||||
Reference in new issue
Block a user