Files
krow_talent_app/src/components/ai-assistant/AgentBadge.tsx
Aravind 7a95d95151 refactor(ts-migration): Phase 11 batch 8 — the assistant panel components
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
2026-09-18 15:37:09 +05:30

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;