Add the Tirma interface: chat, live memory panel, pixel athlete - #2
Open
JorgeRdg wants to merge 1 commit into
Open
Add the Tirma interface: chat, live memory panel, pixel athlete#2JorgeRdg wants to merge 1 commit into
JorgeRdg wants to merge 1 commit into
Conversation
A web front end for the coaching agent, served by the same FastAPI app.
Three panes: session history, the conversation, and a context panel
holding the client's memory store next to an athlete drawn from it.
The athlete is the argument, not decoration. Everything about the pixel
figure is derived from the memory store in api/ui_state.py — build from
the sessions the coach logged, wrist wraps because an injury entry names
the wrist, sleeves because one names the knee. Two rules keep it honest,
and they are the coach's own rules from its system prompt:
· a constraint stays in force until something clears it, resolved per
section, so one file holding wrist + knee + lower back can close one
and keep the others;
· a partial clearance clears nothing. "Cleared for neutral grip, loaded
wrist extension still contraindicated" keeps the wraps on.
Reading a partial clearance as a general all-clear is the exact failure
the agent exists to avoid, so the drawing must not commit it either.
The coaching turn is untouched. api/ui.py relays Coach's own SSE frames
and appends two once the store has been re-read — memory.updated and
athlete.updated — so the panel and the figure change because the store
changed, never because the browser guessed.
Also adds DemoCoach: interface-compatible with Coach, no API key, real
memory writes. api/ui.py never branches on which one it holds, so the
demo and live paths exercise the same code. It exists so the interface
could be built without burning tokens, and so a stage demo has a floor.
Brand: TAM-50, piece type proto. IBM Plex only by proto role, Carbon
icons used verbatim, TAM spacing and radii, no shadows, product palette
with role discipline, product_logo_plus_tam_text signature in the footer.
Every decision and every deviation is written down in ui/tam-decision.yml,
including a conflict between proto.md v0.2 and TAM-50.design.md v0.4 over
which signature variant this tier takes.
ui/sprite-lab.html renders the sprite outside the app — every tier, every
frame, every accessory. It caught two bugs worth having caught: plates
clipping off the canvas at lockout, and shoulder tape drawn under the arm.
Not verified: a real mobile device, and measured contrast ratios. Both
are listed under warnings in the sidecar rather than left implied.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A web front end for the coaching agent, served by the same FastAPI app. Three
panes: session history, the conversation, and a context panel holding the
client's memory store next to an athlete drawn from it.
Built by team Tirma. Brand tier TAM-50, piece type proto — every
decision and every deviation is written down in
ui/tam-decision.yml.Run it
ANTHROPIC_API_KEY="sk-ant-..." uvicorn api.main:app --reloadThen http://127.0.0.1:8000/. The REST API and
/docsare unchanged. Without akey,
TIRMA_DEMO=1 uvicorn api.main:app --reloadruns a scripted coach.The athlete is the argument, not decoration
Everything about the pixel figure is derived from the memory store in
api/ui_state.py— build from the sessions the coach logged, wrist wraps becausean injury entry names the wrist, sleeves because one names the knee. Clicking a
trait chip finds the memory entry that put it there.
Two rules keep it honest, and they are the coach's own rules from its system
prompt rather than something invented for the UI:
section, so one file holding wrist + knee + lower back can close one and keep
the others.
loaded wrist extension still contraindicated" keeps the wraps on.
Reading a partial clearance as a general all-clear is the exact failure the agent
exists to avoid, so the drawing must not commit it either.
The coaching turn is untouched
api/ui.pysits on top rather than beside. It relaysCoach's own SSE framesverbatim and appends two once the store has been re-read —
memory.updatedandathlete.updated— so the panel and the figure change because the store changed,never because the browser guessed.
It adds only the two things a browser needs and the agent does not: conversation
scrollback (the coach runs a fresh session per message, so it has no thread of
its own) and the derived athlete.
DemoCoach
Interface-compatible with
Coach: same methods, same frames, real memory writes.api/ui.pynever branches on which one it holds, so the demo and live pathsexercise the same code. It exists so the interface could be built without burning
tokens, and so a stage demo has a floor if the network has a bad day.
Changes to existing files
api/main.pyonly — the coach is selected viaTIRMA_DEMO, the lifespan demandsANTHROPIC_API_KEYonly outside demo mode, and the interface is mounted. Nothingelse in
api/was modified.Two-minute demo
Start on the right panel: seven sessions on record, two live constraints, an
athlete already in wrist wraps and knee sleeves because memory says so. Send
"physio says the knee is fully cleared now" and watch the coach read the
training file, close the knee entry while leaving the wrist alone, and the
sleeves come off the athlete. The wraps stay on.
Checked
Dark and light, 1440×900 and 1280×720,
prefers-reduced-motionon and off,keyboard-only through every control. Session history, memory panel and athlete
survive a reload. A failed turn puts the typed message back in the box rather
than losing it.
ui/sprite-lab.htmlrenders the sprite outside the app — every tier, every frameof the rep, every accessory. It caught two bugs worth catching: plates clipping
off the canvas at lockout, and shoulder tape drawn under the arm.
Not verified
Listed under
warningsin the sidecar rather than left implied:surface_scopeis desktop_first; the sub-900 breakpointis untested on hardware.
TAM's own AA-validated values, but the violet-on-basalt pairing should go
through a checker before this is called done.
One brand-system conflict, resolved rather than papered over
generators/proto.mdv0.2 says TAM-50 proto takes thewith_wordmark_imagesignature;
tiers/TAM-50.design.mdv0.4 fixesproduct_logo_plus_tam_textforthe whole tier and makes it a condition of tier membership. The tier doc is
followed, since proto.md states it is not the SSOT. Probably worth a PR upstream
to
theam/brand-system.🤖 Generated with Claude Code