advisor: show a "thinking" indicator during advisor fetches (v0.6.0)
CI / build + unit + e2e (pull_request) Successful in 1m33s

This commit is contained in:
2026-10-11 18:32:09 +00:00
parent 977bf584ce
commit c19db2c118
6 changed files with 101 additions and 6 deletions
+22 -2
View File
@@ -19,8 +19,14 @@ import type { GameState, RoundItem } from '@shared/types';
interface Props {
game: GameState;
/** A jump (the only LLM call) is currently in flight — disable the commit. */
/** A jump (the only turn LLM call) is currently in flight — disable the commit. */
busy: boolean;
/**
* An advisor fetch (a separate LLM call) is in flight. Distinct from `busy`:
* it gates only the advisor UI (the "Ask advisor" button + its hint) and must
* never disable "Jump forward" or the rest of the turn flow.
*/
advisorBusy: boolean;
/** Advisor brainstorm suggestions from the last request. */
advisors: string[];
/** Queue a free-text action onto the pending round (no turn advance). */
@@ -59,6 +65,7 @@ function describeItem(item: RoundItem, nationName: (id?: string) => string): str
export default function ActionPanel({
game,
busy,
advisorBusy,
advisors,
onAddAction,
onAddDiplomacy,
@@ -194,10 +201,23 @@ export default function ActionPanel({
variant="secondary"
size="sm"
onClick={() => onAdvisor(prompt.trim() || undefined)}
disabled={advisorBusy}
data-testid="ask-advisor"
>
Ask advisor
{advisorBusy && <Loader2 className="size-3.5 animate-spin" />}
{advisorBusy ? 'Thinking…' : 'Ask advisor'}
</Button>
{/* While the advisor (a separate LLM call) is thinking, mirror the
turn's "sim-hint" so the user knows the request is in flight. */}
{advisorBusy && (
<p
className="flex items-center gap-1.5 text-xs text-muted-foreground"
data-testid="advisor-hint"
>
<span className="sim-pulse inline-block size-1.5 rounded-full bg-primary" />
The advisor is thinking… this can take a few seconds.
</p>
)}
{advisors.length > 0 && (
<ul className="space-y-1.5" data-testid="advisor-list">
{advisors.map((a, i) => (