Progress: the reply's line is the 3.4.0 progress object, {{text}} · {{elapsed}}
ui/js/progress.js draws harness spec 3.4.0's `progress` (progress.md) with the spec's texts as the page's sentences: the thirteen phases, their variants and field words, the line with its clock in whole seconds (5s, 1m 05s, 1h 02m), none for stopped and failed, retrying counted down. A live reply takes `progress` from any stream frame that carries it and ticks once a second; with no progress (an older server, or null) it draws the status text as before. The sentences are the server's to translate: gen-i18n.py takes them from its catalogues once they are there (SERVER_PENDING), English until then, without failing. tests/ui: every case of the spec's conformance/progress.json (copied, 3.4.0), and a live stream's progress, clock, fallback and stopped line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
7 files changed
+607
-2
No files matched your search
+51
-1
@@ -401,6 +401,42 @@ KEYS = (
|
||||
"The terminal needs a newer LLeMbas server. Ask its administrator to update it.",
|
||||
)
|
||||
|
||||
# The progress line's sentences (ui/js/progress.js; harness spec 3.4.0, `loop.json`
|
||||
# progress.texts, its `{{field}}` written as `%(field)s`). Shared with every client, so they
|
||||
# are the server's to translate and never in OWN: until its catalogues have one, that sentence
|
||||
# shows in English and this script says how many are waiting -- not a failure.
|
||||
SERVER_PENDING = (
|
||||
"Queued",
|
||||
"Queued: %(ahead)s ahead",
|
||||
"Waiting for %(model)s: %(reason)s",
|
||||
"Loading %(model)s",
|
||||
"Reading the prompt: %(done)s / %(total)s tokens (%(percent)s%%)",
|
||||
"Reading the prompt",
|
||||
"Thinking",
|
||||
"Writing: %(rate)s tok/s",
|
||||
"Writing",
|
||||
"Running %(tool)s: %(what)s",
|
||||
"Running %(tool)s",
|
||||
"Waiting for you: %(what)s",
|
||||
"Waiting for subagents: %(running)s running",
|
||||
"Compacting the conversation",
|
||||
"Retrying in %(in)s s: %(reason)s",
|
||||
"Stopped",
|
||||
"Stopped: %(reason)s",
|
||||
"Failed: %(reason)s",
|
||||
"it serves one request at a time and is answering another",
|
||||
"all its slots are in use",
|
||||
"its server holds another model now",
|
||||
"allow %(tool)s?",
|
||||
"an approval",
|
||||
"a question",
|
||||
"the plan",
|
||||
"by you",
|
||||
"step limit",
|
||||
"budget",
|
||||
"%(text)s · %(elapsed)s",
|
||||
)
|
||||
|
||||
# The app's own sentences. The mode names (Manual, Edit, Auto, Plan) stay English, as the
|
||||
# server's catalogues keep them ("Režim Edit", "Modus Edit"); "Local" is the server's word for
|
||||
# the device, as the server's catalogue has it.
|
||||
@@ -2218,6 +2254,20 @@ def main() -> None:
|
||||
ours = OWN.get(lang, {})
|
||||
table: dict[str, str] = {}
|
||||
from_server = 0
|
||||
waiting = 0
|
||||
for key in SERVER_PENDING:
|
||||
if key in KEYS:
|
||||
continue
|
||||
text = theirs.get(key)
|
||||
if not text:
|
||||
waiting += 1
|
||||
elif set(FIELD.findall(text)) != set(FIELD.findall(key)):
|
||||
print(f"gen-i18n: {lang}: the fields of {text!r} do not match {key!r}", file=sys.stderr)
|
||||
problems += 1
|
||||
else:
|
||||
table[key] = text
|
||||
if waiting:
|
||||
print(f"gen-i18n: {lang}: {waiting} progress sentences wait for the server's catalogue (English until then)")
|
||||
for key in KEYS:
|
||||
text = theirs.get(key)
|
||||
if text:
|
||||
@@ -2238,7 +2288,7 @@ def main() -> None:
|
||||
print(f"gen-i18n: {lang}: OWN has {key!r}, which no page uses", file=sys.stderr)
|
||||
problems += 1
|
||||
catalogue[lang] = table
|
||||
print(f"gen-i18n: {lang}: {len(table)} of {len(KEYS)} ({from_server} from the server)")
|
||||
print(f"gen-i18n: {lang}: {len(table)} sentences, {from_server} of the page's {len(KEYS)} from the server")
|
||||
|
||||
body = json.dumps(catalogue, ensure_ascii=False, indent=2, sort_keys=True)
|
||||
out = (
|
||||
|
||||
Reference in new issue
Block a user