Files
ai-app/app/stream-bench.sh
T
irisandClaude Fable 5.1 6892dc7caf Colour list markers by depth, highlight fences, draw images as links, and stream a list an item at a time
Items 1-5 of TRANSCRIPT_RENDERING.md's list, plus the AGP 9.4.0 bump from 7.
MarkdownRoot provides the renderer's locals itself instead of calling its
Markdown() composable; fences and indented blocks go through CodeFence.kt,
which shares the tool-input highlighter and a fence-language alias table;
an image in a paragraph is a link carrying its alt text, so every paragraph
is now platform text; LiveParse freezes the finished items of the tail list
so a forty-item list streams as forty paragraphs would.

Measured before, on the emulator (report from transcript-bench.sh over the
200-line fence fixture): draw phase 0.72ms per frame, transcript 0.36ms.
stream-bench.sh (new) streaming forty linked bullets on the old build:
markdown reparsed while streaming 483, 3.9ms mean, 11.6ms worst; record:
one block worst 1.6ms. The after runs, the on-screen check of the glyphs
and lint are recorded as owed in the doc's "What is next".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 13:49:51 -04:00

60 lines
2.2 KiB
Bash
Executable File

#!/bin/sh
# Streams a message into the sandbox session on screen and prints the app's
# render report for the time it took -- the standard measurement for "is a
# reply that is still arriving cheap", the way transcript-bench.sh is for
# scrolling one that has settled.
#
# ./stream-bench.sh FILE restart the app, open the first
# session, stream FILE into it, report
# ./stream-bench.sh -k FILE keep whatever session is open now
#
# The session is the first one the sandbox lists (ui-sandbox.sh spawn makes
# one), and the file is echoed back a word at a time, which is the shape a
# real reply arrives in. The numbers to read are `markdown reparsed while
# streaming` -- how many times, and how long each -- and the worst
# `record: one block`; both are proportional to how much of the reply the
# tail reparse has to cover, which is what the live parse exists to bound.
set -eu
cd "$(dirname "$0")"
. ./android-env.sh >/dev/null 2>&1
keep=""
while getopts k flag; do
case $flag in
k) keep=1 ;;
*) exit 2 ;;
esac
done
shift $((OPTIND - 1))
file=${1:?usage: stream-bench.sh [-k] FILE}
sid=$(./ui-sandbox.sh api /sessions | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["id"])')
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
# The first tap resets the report's window; see transcript-bench.sh.
ui-trace record -d 2000 --do 'tap 723 205' -o /tmp/bench-reset.txt >/dev/null 2>&1
adb logcat -c
./ui-sandbox.sh send "$sid" "@$file" >/dev/null
# Until the echo has finished: its status goes back to idle.
i=0
while [ "$i" -lt 120 ]; do
status=$(./ui-sandbox.sh api "/sessions/$sid" |
python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
[ "$status" = idle ] && break
sleep 2
i=$((i + 1))
done
sleep 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 : //'