fix: type the health test mode, pace cards with the stream, and size the results panel
Some checks are pending
ci / backend (push) Waiting to run
ci / frontend (push) Waiting to run

This commit is contained in:
Justin Visser 2026-08-11 10:15:20 +02:00
parent fa356ba5c5
commit cdace7d170
7 changed files with 41 additions and 15 deletions

View file

@ -154,6 +154,11 @@ Forgejo/GitHub mirror, deployment, how the agents are used) is mapped in
- A faster model on the intent call, which would cut most of the time to
first card; the grounding stage already measures the trade-off to watch
(fabrication rate), so the experiment is cheap to run safely.
- A guaranteed minimum grounding budget. The request deadline is anchored
at request start, so an unusually slow intent call can leave grounding
with no time at all; raising the deadline works around it (env-tunable),
but grounding deserves a floor of its own regardless of what call 1
spent.
- Deeper discovery. A repair loop that re-prompts the model for candidates
that failed verification would let the prompt chase less obvious work
without losing the pool, and a novelty signal beyond exact-id exclusion

View file

@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, Mock
import pytest
from fastapi.testclient import TestClient
from app.config import Settings
from app.config import AppMode, Settings
from app.main import create_app
@ -23,7 +23,7 @@ def test_anthropic_client_uses_configured_timeout(monkeypatch: pytest.MonkeyPatc
monkeypatch.setattr("app.main.AsyncAnthropic", constructor)
live_settings = Settings(
app_mode="live",
app_mode=AppMode.LIVE,
spotify_client_id="client-id",
anthropic_api_key="api-key",
llm_timeout_seconds=42.0,

View file

@ -472,3 +472,29 @@ Wat ik heb laten vallen of uitgesteld:
- Een sneller model op de intent call (zou de wachttijd flink verlagen;
de fabrication rate is de afweging om dan te meten) staat als vervolg
in de README, niet gebouwd.
### Afronding en de laatste live-test
Wat ik deed:
- Laatste ronde live testen op de gehoste instantie voor het insturen.
Twee dingen gevonden: een vraag waarbij call 1 zo lang nadacht dat de
request deadline al om was voordat grounding begon (0 resultaten,
0 Spotify calls), en opnieuw QUOTA_EXCEEDED 429's omdat het dagquotum
van gisteren nog meetelde in het huidige quota-venster.
- De deadline via env verhoogd naar 60 s en de cache-TTL's op de gehoste
instantie opgerekt (resolutie 24 h, taste profile 1 h) zodat het quotum
langer meegaat; een structurele fix (een gegarandeerd minimum
tijdsbudget voor grounding, los van wat call 1 opmaakt) staat in de
README als vervolgstap.
- De card-animatie versneld: elke kaart wachtte nog index maal 80 ms na
binnenkomst voordat hij verscheen, bovenop het tempo van de stream
zelf. De vertraging is weg; de stream is nu zelf de cadans. De
resultatenlijst toont nu ongeveer 5,5 kaarten zodat zichtbaar is dat er
meer te scrollen valt.
- Insturen gepland na de quota-reset vanavond.
Waarom:
- Een reviewer die de live instantie opent moet niet als eerste een
uitgeput quotum zien; de reset bepaalt dus het moment van insturen.

View file

@ -17,12 +17,7 @@ const regionLabel = computed(() =>
<template>
<div class="set" role="region" :aria-label="regionLabel" tabindex="0">
<TrackCard
v-for="(event, index) in tracks"
:key="event.track.id"
:event="event"
:style="`--card-order: ${index}`"
/>
<TrackCard v-for="event in tracks" :key="event.track.id" :event="event" />
</div>
</template>
@ -31,7 +26,8 @@ const regionLabel = computed(() =>
display: flex;
flex-direction: column;
gap: var(--s-2);
max-height: min(42dvh, 480px);
/* Roughly 5.5 cards tall: the half card signals there is more to scroll. */
max-height: min(66dvh, 610px);
padding: var(--s-2) var(--s-3) var(--s-2) 0;
overflow-y: auto;
overscroll-behavior-y: contain;
@ -42,7 +38,7 @@ const regionLabel = computed(() =>
@media (max-width: 560px) {
.set {
max-height: min(34dvh, 360px);
max-height: min(52dvh, 470px);
}
}
</style>

View file

@ -53,7 +53,6 @@ const artworkAlt = computed(() =>
border-color var(--dur-fast) ease,
background var(--dur-fast) ease;
animation: card-in var(--dur-card) var(--ease) both;
animation-delay: calc(var(--card-order, 0) * var(--dur-card-stagger));
}
.card:hover {

View file

@ -76,7 +76,6 @@
--ease: cubic-bezier(0.2, 0.8, 0.3, 1);
--dur-fast: 0.16s;
--dur-card: 0.4s;
--dur-card-stagger: 0.08s;
--dur-reduced-motion: 0.001s;
color-scheme: dark;

View file

@ -104,12 +104,13 @@ describe('result presentation', () => {
expect(region?.contains(action ?? null)).toBe(false)
})
it('assigns a deliberate stagger order to arriving cards', () => {
it('renders arriving cards without an artificial entrance delay', () => {
const root = mountComponent(AssistantMessage, { turn: doneTurn(), canSave: true })
const cards = root.querySelectorAll<HTMLElement>('article')
expect(cards[0]?.style.getPropertyValue('--card-order')).toBe('0')
expect(cards[1]?.style.getPropertyValue('--card-order')).toBe('1')
expect(cards.length).toBeGreaterThan(1)
expect(cards[0]?.style.getPropertyValue('--card-order')).toBe('')
expect(cards[1]?.style.getPropertyValue('--card-order')).toBe('')
})
it('anchors a completed response at the top of the conversation viewport', async () => {