The thirteen `.jsx` files under `src/components/ai-assistant/`, which
completes that directory: 24/24 files migrated and all 24 linted under
their new extensions.
39 errors, and converting 21 `/** @param {any} props */` hatches to
`: any` cleared 33 of them — the same pattern as batch 6, and the same
reason: without the JSDoc, TypeScript infers every destructured prop as
required, so `ResponseBlocks` and `AssistantMessage` alone produced 31
complaints about call sites that were always correct.
The remaining six were already there before this batch and are
unchanged.
13/13 erase byte-identically. `.jsx` -> `.tsx` is the move that can drop
unused imports through esbuild's loader difference; it did not here, and
the bundle hash is unchanged.
Measured against `3f835ee`:
typecheck 6 errors, unchanged; no new error anywhere
lint exit 0, 0 errors, 289 warnings, 24/24 linted by name
npm test 1684/1691, the same 7 failures verbatim
build exit 0, identical bundle hash 74d17e2d…
type erasure 96/96 byte-identical across Phase 11 so far
No baseline artifact touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
import * as React from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
import { agentIconFor } from '@/components/agents/icons';
|
|
import OwliverAvatar from '@/components/krow/OwliverAvatar';
|
|
import { useActiveAgent } from './AgentContext';
|
|
|
|
/**
|
|
* Who is answering, in Owliver's own header.
|
|
*
|
|
* This was an agent *switcher*: the header opened a popover with a search box,
|
|
* every registered agent, Browse all and Create agent. That made the panel a
|
|
* second place to decide which agent answers, competing with the one place that
|
|
* actually configures agents — the Agent Editor — and letting a reader put
|
|
* Owliver into a state nothing on the page explained.
|
|
*
|
|
* It is now a label. The agent is whatever `AgentContext` resolves for the page
|
|
* being read, which is the same resolution the runtime already uses to answer,
|
|
* so the header cannot disagree with the reply underneath it. Switching belongs
|
|
* to Agent Registry → Agents → Configure.
|
|
*
|
|
* Deliberately **not** a button, and deliberately no chevron: a disclosure
|
|
* affordance that discloses nothing is worse than none. Nothing here is
|
|
* clickable, so nothing here promises a menu.
|
|
*/
|
|
|
|
/** The avatar for the primary agent; a lucide glyph for the rest. */
|
|
function AgentGlyph({ agent, className = 'h-7 w-7' }) {
|
|
const Icon = agentIconFor(agent?.icon);
|
|
|
|
if (!Icon) return <OwliverAvatar className={className} rounded="rounded-lg" />;
|
|
|
|
return (
|
|
<span
|
|
className={cn(
|
|
'inline-flex shrink-0 items-center justify-center rounded-lg border border-border/80 bg-surface-subtle text-krow-blue shadow-2xs',
|
|
className
|
|
)}
|
|
aria-hidden="true"
|
|
>
|
|
<Icon className="h-4 w-4" />
|
|
</span>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The mark a constrained agent carries.
|
|
*
|
|
* Kept: it is a fact about the answer that follows — this agent does not cover
|
|
* this page and will say so — not a control, and losing it would make a
|
|
* constrained reply arrive with no warning.
|
|
*/
|
|
function ConstrainedTag() {
|
|
return (
|
|
<span className="inline-flex shrink-0 items-center rounded-md border border-amber-500/25 bg-amber-500/10 px-1.5 py-0.5 text-[10px] font-medium leading-none text-amber-700 dark:text-amber-300">
|
|
Constrained
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export function AgentBadge({ page }: any) {
|
|
const { agent, covers } = useActiveAgent();
|
|
|
|
return (
|
|
<>
|
|
{agent
|
|
? <AgentGlyph agent={agent} />
|
|
: <OwliverAvatar className="h-7 w-7" rounded="rounded-lg" />}
|
|
|
|
<div className="min-w-0 flex-1">
|
|
<h2 className="truncate font-heading text-body-sm font-semibold leading-tight text-ink-1">
|
|
Owliver
|
|
</h2>
|
|
<div className="flex min-w-0 items-center gap-1.5">
|
|
<p className="truncate text-caption leading-tight text-ink-3">{page}</p>
|
|
{agent && !covers && <ConstrainedTag />}
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default AgentBadge;
|