@dataverse-kit/agent-kit 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -2
- package/dist/index.cjs +882 -397
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +171 -6
- package/dist/index.d.ts +171 -6
- package/dist/index.mjs +880 -390
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/conversation/MessageList.tsx","../src/core/runStatus.ts","../src/core/grouping.ts","../src/core/dayDividers.ts","../src/core/citations.ts","../src/core/conversationReducer.ts","../src/core/normalize.ts","../src/core/announce.ts","../src/core/scroll.ts","../src/core/ids.ts","../src/a11y/LiveAnnouncer.tsx","../src/a11y/visuallyHidden.ts","../src/a11y/useFocusRestore.ts","../src/a11y/useRovingTabindex.ts","../src/hooks/useStickyScroll.ts","../src/hooks/useConversation.ts","../src/conversation/MessageBubble.tsx","../src/conversation/StreamingText.tsx","../src/conversation/MessageActions.tsx","../src/internal/ActionToolbar.tsx","../src/internal/CardSurface.tsx","../src/internal/ConfirmInline.tsx","../src/internal/Disclosure.tsx","../src/conversation/DayDivider.tsx","../src/conversation/TypingIndicator.tsx","../src/conversation/Composer.tsx","../src/conversation/SuggestedPrompts.tsx","../src/conversation/EmptyConversation.tsx","../src/conversation/SystemNotice.tsx","../src/ops/AgentStatusBadge.tsx","../src/ops/AvailabilityBanner.tsx","../src/ops/UsageMeter.tsx","../src/ops/ThrottleNotice.tsx","../src/ops/ModelBadge.tsx","../src/ops/AgentPicker.tsx","../src/ops/RunTimeline.tsx","../src/ops/RunHistoryPanel.tsx","../src/ops/AgentOpsPanel.tsx","../src/shell/AgentAppShell.tsx","../src/shell/AppRail.tsx","../src/shell/ConversationList.tsx","../src/shell/ConversationListItem.tsx","../src/shell/AgentAvatar.tsx","../src/shell/ConversationHeader.tsx","../src/shell/RightPane.tsx","../src/shell/GlobalSearchBar.tsx","../src/grounding/CitationChip.tsx","../src/grounding/CitationList.tsx","../src/grounding/SourceCard.tsx","../src/grounding/AnswerWithCitations.tsx","../src/grounding/GroundingPanel.tsx","../src/grounding/ProviderAttribution.tsx","../src/actions/ActionCard.tsx","../src/actions/ApprovalCard.tsx","../src/actions/ParameterReview.tsx","../src/actions/ActionResult.tsx","../src/actions/ToolCallCard.tsx","../src/host/AgentKitHostProvider.tsx","../src/theme/index.ts","../src/host/idPrefix.ts","../src/services/scenarios.ts","../src/services/MockAgentService.ts","../src/services/NullAgentService.ts","../src/services/createAgentService.ts"],"sourcesContent":["import * as React from 'react';\nimport { Button, makeStyles, tokens } from '@fluentui/react-components';\nimport { ArrowDownRegular } from '@fluentui/react-icons';\nimport {\n bucketByDay,\n groupMessages,\n type AgentMessage,\n type AgentParticipant,\n type Announcement,\n} from '../core';\nimport { LiveAnnouncer } from '../a11y';\nimport { useStickyScroll } from '../hooks';\nimport { MessageBubble } from './MessageBubble';\nimport { DayDivider } from './DayDivider';\nimport { TypingIndicator } from './TypingIndicator';\nimport type { MessageActionsProps } from './MessageActions';\n\nexport interface MessageListProps extends Omit<MessageActionsProps, 'message'> {\n messages: readonly AgentMessage[];\n participants?: readonly AgentParticipant[];\n /** Renders the typing indicator and suppresses the \"jump to latest\" nudge. */\n busy?: boolean;\n announcement?: Announcement;\n groupWindowMs?: number;\n timeZone?: string;\n locale?: string;\n /** Injected so day labels are deterministic in tests and Chromatic. */\n now?: number;\n emptyState?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: { position: 'relative', height: '100%', minHeight: 0, display: 'flex', flexDirection: 'column' },\n scroller: {\n flex: 1,\n overflowY: 'auto',\n padding: tokens.spacingVerticalM,\n display: 'flex',\n flexDirection: 'column',\n gap: tokens.spacingVerticalS,\n },\n jump: { position: 'absolute', bottom: tokens.spacingVerticalM, alignSelf: 'center', zIndex: 1 },\n});\n\n/**\n * The transcript.\n *\n * ★ It is NOT a live region. Announcements go through `LiveAnnouncer`, fed by\n * `deriveAnnouncement` on state TRANSITIONS — a live region over the streaming node queues\n * every token and a screen reader never finishes reading.\n *\n * ★ Grouping (avatar + name once per run) is VISUAL. Every `MessageBubble` still carries its\n * author and timestamp in the accessible tree.\n */\nexport function MessageList(props: MessageListProps): React.ReactElement {\n const {\n messages, participants, busy = false, announcement,\n groupWindowMs, timeZone, locale, now, emptyState, ...actionHandlers\n } = props;\n\n const styles = useStyles();\n const scrollerRef = React.useRef<HTMLDivElement>(null);\n const { onScroll, scrollToBottom, isPinned } = useStickyScroll(scrollerRef, messages.length);\n\n const byId = React.useMemo(\n () => new Map((participants ?? []).map((p) => [p.id, p])),\n [participants],\n );\n\n // A message is a run START unless the grouping says it continues one.\n const runStarts = React.useMemo(() => {\n const groups = groupMessages(messages, { windowMs: groupWindowMs, timeZone });\n return new Set(groups.map((g) => g.messageIds[0]));\n }, [messages, groupWindowMs, timeZone]);\n\n const buckets = React.useMemo(\n () => bucketByDay(messages, { timeZone, now }),\n [messages, timeZone, now],\n );\n const dividerBefore = React.useMemo(() => {\n const map = new Map<string, (typeof buckets)[number]['label']>();\n for (const bucket of buckets) map.set(bucket.messageIds[0], bucket.label);\n return map;\n }, [buckets]);\n\n return (\n <div className={styles.root}>\n <LiveAnnouncer polite={announcement?.polite} assertive={announcement?.assertive} />\n\n <div\n ref={scrollerRef}\n className={styles.scroller}\n onScroll={onScroll}\n // A labelled, focusable scroll region: a keyboard user must be able to reach and\n // scroll the transcript without tabbing through every message inside it.\n role=\"log\"\n aria-label=\"Conversation\"\n tabIndex={0}\n >\n {messages.length === 0 ? (\n emptyState ?? null\n ) : (\n messages.map((message) => (\n <React.Fragment key={message.id}>\n {dividerBefore.has(message.id) ? (\n <DayDivider label={dividerBefore.get(message.id)!} locale={locale} />\n ) : null}\n <MessageBubble\n message={message}\n author={byId.get(message.authorId)}\n isRunStart={runStarts.has(message.id)}\n locale={locale}\n {...actionHandlers}\n />\n </React.Fragment>\n ))\n )}\n {busy ? <TypingIndicator /> : null}\n </div>\n\n {!isPinned && messages.length > 0 ? (\n <Button\n className={styles.jump}\n size=\"small\"\n appearance=\"primary\"\n icon={<ArrowDownRegular />}\n onClick={scrollToBottom}\n >\n Jump to latest\n </Button>\n ) : null}\n </div>\n );\n}\n","import type { AgentFailure, AgentRunStatus } from './protocol';\n\n/** Terminal statuses. `succeeded` included — this answers \"is the turn over?\", not \"did it work?\". */\nconst TERMINAL: ReadonlySet<AgentRunStatus> = new Set<AgentRunStatus>([\n 'succeeded',\n 'blocked',\n 'refused',\n 'error',\n 'notProvisioned',\n 'cancelled',\n]);\n\nexport function isTerminalStatus(status: AgentRunStatus): boolean {\n return TERMINAL.has(status);\n}\n\n/** How a status should READ, not what colour it is — the UI maps this to tokens. */\nexport function runStatusSeverity(\n status: AgentRunStatus,\n): 'success' | 'warning' | 'error' | 'info' {\n switch (status) {\n case 'succeeded':\n return 'success';\n case 'blocked':\n case 'refused':\n return 'warning';\n case 'error':\n return 'error';\n case 'notProvisioned':\n case 'cancelled':\n return 'info';\n }\n}\n\n/**\n * Classify a transport failure into the six-state ladder.\n *\n * ★★ 503 maps to `notProvisioned`, NOT `error`. Adopted from the ai-103 broker, which\n * records the reason: with on-demand Azure most services are absent most of the time,\n * and that is a normal state — reporting it as a failure is what would make the app look\n * broken. Without this branch, \"nobody has turned this on yet\" and \"it is broken\" are\n * indistinguishable on screen, and they need completely different fixes.\n */\nexport function classifyTransportFailure(input: {\n httpStatus?: number;\n code?: string;\n message?: string;\n retryAfterMs?: number;\n}): AgentFailure {\n const { httpStatus, code, retryAfterMs } = input;\n const message = input.message ?? 'The agent could not be reached.';\n\n if (httpStatus === 503) {\n return {\n status: 'notProvisioned',\n message,\n code: code ?? 'not_provisioned',\n recoverable: false,\n correlationId: undefined,\n };\n }\n if (httpStatus === 429) {\n return { status: 'error', message, code: code ?? 'rate_limited', recoverable: true, retryAfterMs };\n }\n if (code === 'content_filter') {\n return { status: 'blocked', message, code, recoverable: false };\n }\n return { status: 'error', message, code, recoverable: httpStatus !== undefined && httpStatus >= 500 };\n}\n","import type { AgentMessage, AgentRole } from './protocol';\n\n/** Teams groups consecutive messages from one author inside a short window. */\nexport const DEFAULT_GROUP_WINDOW_MS = 5 * 60 * 1000;\n\nexport interface GroupingOptions {\n windowMs?: number;\n /** Injected so day-boundary behaviour is testable without touching the system clock. */\n timeZone?: string;\n}\n\nexport interface MessageGroup {\n key: string;\n authorId: string;\n role: AgentRole;\n startedAt: number;\n messageIds: string[];\n}\n\n/** Local calendar day, in the given zone. Duplicated deliberately from dayDividers to keep\n * this module independent of it; both delegate to Intl, so they cannot disagree. */\nfunction dayKey(epochMs: number, timeZone?: string): string {\n return new Intl.DateTimeFormat('en-CA', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).format(new Date(epochMs));\n}\n\n/**\n * Do these two messages belong to the same visual run?\n *\n * ★ Exported separately from `groupMessages` on purpose. The boundary cases (4:59 / exactly\n * 5:00 / 5:01) are then assertable against the PREDICATE, instead of being inferred from\n * a group count — where an off-by-one and a correct implementation can produce the same\n * number of groups for the wrong reason.\n */\nexport function isSameAuthorRun(\n a: AgentMessage,\n b: AgentMessage,\n windowMs: number = DEFAULT_GROUP_WINDOW_MS,\n timeZone?: string,\n): boolean {\n if (a.authorId !== b.authorId) return false;\n if (a.role !== b.role) return false;\n // A system notice between two messages ends the run: the second is a new utterance.\n if (a.role === 'system' || b.role === 'system') return false;\n if (b.createdAt < a.createdAt) return false;\n if (b.createdAt - a.createdAt > windowMs) return false;\n // Never group across a day divider — the divider would have to render inside the group.\n return dayKey(a.createdAt, timeZone) === dayKey(b.createdAt, timeZone);\n}\n\n/**\n * Collapse consecutive same-author messages into runs, Teams-style: the avatar and name\n * render once per run.\n *\n * ★ Grouping is a VISUAL affordance only. Every message must still carry its author in the\n * accessible name — a screen reader navigating message-by-message would otherwise hear\n * nothing identifying messages 2..N of a run, in a UI whose entire point is the\n * distinction between what the user said and what the model said.\n */\nexport function groupMessages(\n messages: readonly AgentMessage[],\n options: GroupingOptions = {},\n): MessageGroup[] {\n const windowMs = options.windowMs ?? DEFAULT_GROUP_WINDOW_MS;\n const groups: MessageGroup[] = [];\n\n for (const message of messages) {\n const current = groups[groups.length - 1];\n const previousId = current?.messageIds[current.messageIds.length - 1];\n const previous = previousId ? messages.find((m) => m.id === previousId) : undefined;\n\n if (current && previous && isSameAuthorRun(previous, message, windowMs, options.timeZone)) {\n current.messageIds.push(message.id);\n continue;\n }\n groups.push({\n key: `${message.authorId}:${message.id}`,\n authorId: message.authorId,\n role: message.role,\n startedAt: message.createdAt,\n messageIds: [message.id],\n });\n }\n return groups;\n}\n","import type { AgentMessage } from './protocol';\n\n/**\n * A day divider as a DESCRIPTOR, never a localised string.\n *\n * ★ A pure-TS module that returned \"Yesterday\" could not be localised by the host and could\n * not be tested deterministically. The React layer maps this through `Intl.DateTimeFormat`.\n */\nexport type DayDividerLabel =\n | { kind: 'today' }\n | { kind: 'yesterday' }\n | { kind: 'weekday'; weekday: number; iso: string }\n | { kind: 'date'; iso: string };\n\nexport interface DayBucket {\n /** `YYYY-MM-DD` in the resolved zone. */\n dayKey: string;\n label: DayDividerLabel;\n messageIds: string[];\n}\n\n/** Local calendar day in `timeZone`. `en-CA` because it formats as `YYYY-MM-DD`. */\nexport function dayKeyOf(epochMs: number, timeZone?: string): string {\n return new Intl.DateTimeFormat('en-CA', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).format(new Date(epochMs));\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction labelFor(dayKey: string, nowMs: number, timeZone?: string): DayDividerLabel {\n const todayKey = dayKeyOf(nowMs, timeZone);\n if (dayKey === todayKey) return { kind: 'today' };\n if (dayKey === dayKeyOf(nowMs - DAY_MS, timeZone)) return { kind: 'yesterday' };\n\n // Within the last week, Teams shows the weekday name.\n const asDate = new Date(`${dayKey}T00:00:00Z`);\n for (let back = 2; back <= 6; back++) {\n if (dayKey === dayKeyOf(nowMs - back * DAY_MS, timeZone)) {\n return { kind: 'weekday', weekday: asDate.getUTCDay(), iso: dayKey };\n }\n }\n return { kind: 'date', iso: dayKey };\n}\n\n/**\n * Bucket messages by local calendar day.\n *\n * ★ `now` and `timeZone` are INJECTED, not read from the environment. That is what makes\n * the claim expressible at all: the test that separates a correct implementation from a\n * naive `new Date().toDateString()` is the one that feeds the SAME epoch with two zones\n * either side of the date line and asserts the keys DIFFER. A UTC-only test passes for\n * both.\n */\nexport function bucketByDay(\n messages: readonly AgentMessage[],\n options: { timeZone?: string; now?: number } = {},\n): DayBucket[] {\n const nowMs = options.now ?? Date.now();\n const buckets: DayBucket[] = [];\n\n for (const message of messages) {\n const key = dayKeyOf(message.createdAt, options.timeZone);\n const current = buckets[buckets.length - 1];\n if (current && current.dayKey === key) {\n current.messageIds.push(message.id);\n continue;\n }\n buckets.push({\n dayKey: key,\n label: labelFor(key, nowMs, options.timeZone),\n messageIds: [message.id],\n });\n }\n return buckets;\n}\n","import type { AgentCitation, AgentSource } from './protocol';\n\nexport interface CitationSegment {\n kind: 'text' | 'citation';\n text: string;\n marker?: string;\n sourceId?: string;\n}\n\n/** `[1]` and the Azure OpenAI annotation form `【3:0†source】`. */\nconst BRACKET_MARKER = /\\[(\\d{1,3})\\]/g;\nconst AOAI_MARKER = /【(\\d{1,3}):\\d+†[^】]*】/g;\n\nexport interface ExtractedMarker {\n marker: string;\n index: number;\n length: number;\n}\n\n/** Every citation marker in the text, in order of appearance. */\nexport function extractCitationMarkers(text: string): ExtractedMarker[] {\n const found: ExtractedMarker[] = [];\n for (const re of [BRACKET_MARKER, AOAI_MARKER]) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n found.push({ marker: m[1], index: m.index, length: m[0].length });\n }\n }\n return found.sort((a, b) => a.index - b.index);\n}\n\n/**\n * Renumber an answer's citations to `[1]`, `[2]`… in first-appearance order, and return\n * ONLY the sources the text actually cites.\n *\n * ★★ Dropping uncited sources is the point of this function, not a side effect. A grounding\n * panel listing twelve retrieved chunks under a two-citation answer is the defect it\n * exists to prevent: it implies the answer rests on twelve things when it rests on two,\n * which is exactly the kind of overstated provenance that makes a citation panel\n * decorative rather than trustworthy.\n */\nexport function renumberCitations(\n text: string,\n sources: readonly AgentSource[],\n): { text: string; used: AgentSource[]; citations: AgentCitation[] } {\n const markers = extractCitationMarkers(text);\n const order: string[] = [];\n for (const { marker } of markers) if (!order.includes(marker)) order.push(marker);\n\n const byOriginal = new Map<string, number>();\n order.forEach((marker, i) => byOriginal.set(marker, i + 1));\n\n const used: AgentSource[] = [];\n const citations: AgentCitation[] = [];\n for (const marker of order) {\n // Markers are 1-based positions into the ORIGINAL source list.\n const source = sources[Number(marker) - 1];\n if (!source) continue;\n used.push(source);\n citations.push({ marker: String(byOriginal.get(marker)), sourceId: source.id });\n }\n\n let out = '';\n let cursor = 0;\n for (const { marker, index, length } of markers) {\n out += text.slice(cursor, index);\n const renumbered = byOriginal.get(marker);\n out += renumbered === undefined ? '' : `[${renumbered}]`;\n cursor = index + length;\n }\n out += text.slice(cursor);\n\n return { text: out, used, citations };\n}\n\n/** Split text into runs so the renderer can put a chip where each marker was. */\nexport function splitTextByCitations(\n text: string,\n citations: readonly AgentCitation[],\n): CitationSegment[] {\n const markers = extractCitationMarkers(text);\n if (markers.length === 0) return text ? [{ kind: 'text', text }] : [];\n\n const segments: CitationSegment[] = [];\n let cursor = 0;\n for (const { marker, index, length } of markers) {\n if (index > cursor) segments.push({ kind: 'text', text: text.slice(cursor, index) });\n const citation = citations.find((c) => c.marker === marker);\n segments.push({\n kind: 'citation',\n text: `[${marker}]`,\n marker,\n sourceId: citation?.sourceId,\n });\n cursor = index + length;\n }\n if (cursor < text.length) segments.push({ kind: 'text', text: text.slice(cursor) });\n return segments;\n}\n","import type {\n AgentAttachment,\n AgentEvent,\n AgentFailure,\n AgentMessage,\n AgentRunStatus,\n AgentUsage,\n} from './protocol';\n\n/** One field, not a `{loading, error}` pair that can disagree with itself. */\nexport type ConversationStatus = 'idle' | 'connecting' | 'streaming' | AgentRunStatus;\n\nexport interface ConversationState {\n messages: AgentMessage[];\n streamingMessageId: string | null;\n status: ConversationStatus;\n /** Ephemeral chrome from a `status` event (\"Searching Dataverse…\"). Not message content. */\n statusLabel?: string;\n failure?: AgentFailure;\n usage?: AgentUsage;\n suggestions?: string[];\n}\n\nexport function initialConversation(seed: readonly AgentMessage[] = []): ConversationState {\n return { messages: [...seed], streamingMessageId: null, status: 'idle' };\n}\n\n/** Replace exactly one message, leaving every other array slot identity-stable so React can\n * bail out of re-rendering the rest of the transcript during a stream. */\nfunction patch(\n state: ConversationState,\n messageId: string,\n update: (m: AgentMessage) => AgentMessage,\n): AgentMessage[] {\n const i = state.messages.findIndex((m) => m.id === messageId);\n if (i === -1) return state.messages;\n const next = state.messages.slice();\n next[i] = update(next[i]);\n return next;\n}\n\nexport function appendUserMessage(\n state: ConversationState,\n input: { id: string; text: string; authorId?: string; attachments?: AgentAttachment[]; now?: number },\n): ConversationState {\n const message: AgentMessage = {\n id: input.id,\n role: 'user',\n authorId: input.authorId ?? 'user',\n text: input.text,\n createdAt: input.now ?? Date.now(),\n attachments: input.attachments,\n };\n return { ...state, messages: [...state.messages, message], status: 'connecting', failure: undefined };\n}\n\n/**\n * Apply one stream event.\n *\n * ★ Written as an EXHAUSTIVE switch with no `default:`. The repo's tsconfig sets\n * `noFallthroughCasesInSwitch` and `strict`, so adding a member to `AgentEvent` without a\n * case here is a compile error — a gate you get for free, and one that a tidy-looking\n * `default: return state` would silently remove. Do not add one.\n */\nexport function applyAgentEvent(state: ConversationState, event: AgentEvent): ConversationState {\n switch (event.type) {\n case 'turn_start': {\n const message: AgentMessage = {\n id: event.messageId,\n role: 'assistant',\n authorId: event.provider ?? 'agent',\n text: '',\n createdAt: Date.now(),\n streaming: true,\n provider: event.provider,\n };\n return {\n ...state,\n messages: [...state.messages, message],\n streamingMessageId: event.messageId,\n status: 'streaming',\n statusLabel: undefined,\n failure: undefined,\n suggestions: undefined,\n };\n }\n\n case 'text_delta':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({ ...m, text: m.text + event.text })),\n };\n\n case 'thinking_delta':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n thinking: (m.thinking ?? '') + event.text,\n })),\n };\n\n case 'tool_call':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n toolCalls: [...(m.toolCalls ?? []), event.call],\n })),\n };\n\n case 'tool_result':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n toolCalls: (m.toolCalls ?? []).map((c) =>\n c.id === event.callId\n ? { ...c, status: event.status, resultText: event.resultText, failure: event.failure }\n : c,\n ),\n })),\n };\n\n case 'sources':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({ ...m, sources: event.sources })),\n };\n\n case 'citation':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n citations: [...(m.citations ?? []), event.citation],\n })),\n };\n\n case 'suggestions':\n return { ...state, suggestions: event.prompts };\n\n case 'status':\n return { ...state, statusLabel: event.label };\n\n case 'turn_end': {\n const { result } = event;\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n // A non-streaming provider sends no deltas, so the assembled text arrives here.\n text: m.text.length > 0 ? m.text : result.text,\n streaming: false,\n guarded: result.guarded,\n provider: result.provider,\n usage: result.usage,\n failure: result.failure,\n })),\n streamingMessageId: null,\n status: result.status,\n statusLabel: undefined,\n failure: result.failure,\n usage: result.usage,\n };\n }\n }\n}\n","import type { AgentEvent, AgentToolCall } from './protocol';\n\n/**\n * Transport normalizers: turn one provider's wire shape into `AgentEvent[]`.\n *\n * ★ Each returns an ARRAY, never a single event or null. One Azure OpenAI chunk can\n * legitimately carry a text delta AND a tool-call fragment AND a citation annotation, so\n * a one-in-one-out signature would silently drop two of the three.\n *\n * ★ These live in ./core (no React, no DOM) because a transport adapter frequently runs\n * where React must not be — an Azure Function proxying SSE, a web worker, a Node broker.\n * The same normalizer must be usable on both sides of that boundary.\n *\n * ★ Only shapes whose wire format is KNOWN are implemented. A normalizer written from an\n * assumed shape is a fixture that measures a platform which does not exist, so\n * `fromDirectLineActivity` is deliberately absent until an adapter exists to measure it\n * against — see CLAUDE.md.\n */\n\nexport interface NormalizeCtx {\n messageId: string;\n turnId: string;\n}\n\n/**\n * Unwrap one SSE line. Returns `undefined` for keep-alives, comments and blank lines, and\n * the sentinel `'[DONE]'` for the terminator — callers must distinguish those, since\n * \"nothing to do\" and \"the stream is over\" are different.\n */\nexport function fromSseLine(line: string): unknown | '[DONE]' | undefined {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith(':')) return undefined;\n if (!trimmed.startsWith('data:')) return undefined;\n const payload = trimmed.slice('data:'.length).trim();\n if (payload === '') return undefined;\n if (payload === '[DONE]') return '[DONE]';\n try {\n return JSON.parse(payload) as unknown;\n } catch {\n return undefined;\n }\n}\n\ninterface OpenAiDelta {\n content?: string | null;\n tool_calls?: { index?: number; id?: string; function?: { name?: string; arguments?: string } }[];\n}\ninterface OpenAiChunk {\n choices?: { delta?: OpenAiDelta }[];\n}\n\n/** An OpenAI / Azure OpenAI streaming chunk. */\nexport function fromOpenAiChatChunk(chunk: unknown, ctx: NormalizeCtx): AgentEvent[] {\n const events: AgentEvent[] = [];\n const delta = (chunk as OpenAiChunk | undefined)?.choices?.[0]?.delta;\n if (!delta) return events;\n\n if (typeof delta.content === 'string' && delta.content.length > 0) {\n events.push({ type: 'text_delta', messageId: ctx.messageId, text: delta.content });\n }\n for (const call of delta.tool_calls ?? []) {\n if (!call.id) continue; // a pure arguments continuation; the caller accumulates it\n const toolCall: AgentToolCall = {\n id: call.id,\n name: call.function?.name ?? '',\n argumentsJson: call.function?.arguments ?? '',\n status: 'proposed',\n };\n events.push({ type: 'tool_call', messageId: ctx.messageId, call: toolCall });\n }\n return events;\n}\n\n/** The `@dataverse-kit/claude-bridge` event union. */\nexport interface ClaudeLikeStreamEvent {\n type: 'init' | 'text_delta' | 'thinking_delta' | 'done' | 'error';\n text?: string;\n fullText?: string;\n model?: string;\n sessionId?: string;\n costUsd?: number;\n durationMs?: number;\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n message?: string;\n recoverable?: boolean;\n}\n\nexport function fromClaudeStreamEvent(\n event: ClaudeLikeStreamEvent,\n ctx: NormalizeCtx,\n): AgentEvent[] {\n switch (event.type) {\n case 'init':\n return [\n {\n type: 'turn_start',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n model: event.model,\n provider: 'claude-bridge',\n sessionId: event.sessionId,\n },\n ];\n case 'text_delta':\n return event.text ? [{ type: 'text_delta', messageId: ctx.messageId, text: event.text }] : [];\n case 'thinking_delta':\n return event.text\n ? [{ type: 'thinking_delta', messageId: ctx.messageId, text: event.text }]\n : [];\n case 'done':\n return [\n {\n type: 'turn_end',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n result: {\n status: 'succeeded',\n text: event.fullText ?? '',\n provider: 'claude-bridge',\n model: event.model,\n usage: {\n inputTokens: event.inputTokens,\n outputTokens: event.outputTokens,\n cachedTokens: event.cacheReadTokens,\n costUsd: event.costUsd,\n durationMs: event.durationMs,\n model: event.model,\n },\n },\n },\n ];\n case 'error':\n return [\n {\n type: 'turn_end',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n result: {\n status: 'error',\n text: '',\n provider: 'claude-bridge',\n failure: {\n status: 'error',\n message: event.message ?? 'The agent failed.',\n recoverable: event.recoverable ?? false,\n },\n },\n },\n ];\n }\n}\n\n/** A NON-streaming Foundry reply (`certifications/ai-103/broker`'s `FoundryChatResult`). */\nexport interface FoundryLikeResult {\n text: string;\n promptTokens?: number;\n completionTokens?: number;\n model?: string;\n}\n\n/**\n * ★ Two events, no faked deltas. This is what `AgentTurnResult.text` exists for: a provider\n * with no streaming at all still produces a complete message through the same reducer.\n */\nexport function fromFoundryChatResult(\n result: FoundryLikeResult,\n ctx: NormalizeCtx,\n provider = 'foundry',\n): AgentEvent[] {\n return [\n { type: 'turn_start', turnId: ctx.turnId, messageId: ctx.messageId, model: result.model, provider },\n {\n type: 'turn_end',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n result: {\n status: 'succeeded',\n text: result.text,\n provider,\n model: result.model,\n usage: {\n inputTokens: result.promptTokens,\n outputTokens: result.completionTokens,\n model: result.model,\n },\n },\n },\n ];\n}\n","import type { ConversationState } from './conversationReducer';\n\n/** Past this many characters, announce a summary instead of the whole answer. */\nexport const ANNOUNCE_FULL_TEXT_MAX_CHARS = 240;\n\nexport interface Announcement {\n /** Read when the screen reader next pauses. Empty means \"nothing new\". */\n polite: string;\n /** Interrupts. Reserved for failures. */\n assertive: string;\n}\n\nexport const NO_ANNOUNCEMENT: Announcement = { polite: '', assertive: '' };\n\nconst TERMINAL = new Set(['succeeded', 'blocked', 'refused', 'error', 'notProvisioned', 'cancelled']);\n\n/**\n * What, if anything, should be announced for this state change.\n *\n * ★★ THE WHOLE POINT: this is derived from a state TRANSITION, never from a delta.\n *\n * Both naive choices are wrong. No live region at all and a screen-reader user never\n * hears the answer — the kit's primary output is silent. A live region on the streaming\n * node and every token is queued for announcement; NVDA and JAWS re-read the growing\n * string and never finish. So the transcript is NOT a live region, the streaming bubble\n * carries `aria-busy`, the typing indicator's own `role=\"status\"` covers \"responding\",\n * and this announces exactly once per turn: the settled answer.\n *\n * ★ Deltas, `thinking` and tool calls are never announced. Thinking especially: it is\n * explicitly the model's scratch work, and reading it aloud would bury the answer.\n *\n * ★ Failures go to the ASSERTIVE channel, because an error the user is not told about is\n * an error they wait through.\n */\nexport function deriveAnnouncement(\n state: ConversationState,\n previous: ConversationState | undefined,\n): Announcement {\n const wasTerminal = previous ? TERMINAL.has(previous.status) : false;\n const isTerminal = TERMINAL.has(state.status);\n\n // Only the moment of settling produces an announcement.\n if (!isTerminal || wasTerminal) return NO_ANNOUNCEMENT;\n\n if (state.failure) {\n return { polite: '', assertive: state.failure.message };\n }\n\n const last = state.messages[state.messages.length - 1];\n const text = last?.text ?? '';\n if (!text) return NO_ANNOUNCEMENT;\n\n const guarded = last?.guarded ? 'The response was withheld. ' : '';\n if (text.length <= ANNOUNCE_FULL_TEXT_MAX_CHARS) {\n return { polite: `${guarded}${text}`, assertive: '' };\n }\n const words = text.trim().split(/\\s+/).length;\n return {\n polite: `${guarded}Response complete, ${words} words.`,\n assertive: '',\n };\n}\n","/** How close to the bottom still counts as \"at the bottom\", in CSS pixels. */\nexport const STICK_TO_BOTTOM_THRESHOLD_PX = 32;\n\nexport interface ScrollGeometry {\n scrollTop: number;\n scrollHeight: number;\n clientHeight: number;\n}\n\n/**\n * Should an append scroll the transcript to the bottom?\n *\n * ★ The DECISION is extracted from the EFFECT on purpose. It is what lets a unit test\n * express \"the user scrolled up, so do not yank them back\" without a real scroller —\n * jsdom reports `scrollHeight`/`clientHeight` as 0 forever, so a test that drives a real\n * element can only ever observe \"at the bottom\" and the interesting branch never runs.\n *\n * ★ The rule itself carries a MEASURED defect forward. apps/form-builder's ChatPane once\n * keyed its scroll effect on the streaming message's content length, which queued a\n * smooth `scrollTo` per token — 10+ per second — and jittered the viewport. The fix there\n * was to key on message COUNT and use `behavior: 'auto'`. This adds the half that was\n * still missing: only stick if the reader was already at the bottom, so scrolling up to\n * re-read mid-stream is not undone.\n */\nexport function shouldStickToBottom(\n geometry: ScrollGeometry,\n thresholdPx: number = STICK_TO_BOTTOM_THRESHOLD_PX,\n): boolean {\n const { scrollTop, scrollHeight, clientHeight } = geometry;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n return distanceFromBottom <= thresholdPx;\n}\n","/**\n * Build a per-instance id-prefix generator.\n *\n * ★ The FACTORY is exported (pure, testable); the module SINGLETON that a provider uses\n * lives in src/host/idPrefix.ts. That split matters: the gallery's measurement is that\n * there must be exactly ONE counter per bundle, so two instances of the same control get\n * different prefixes. A constant prefix is the wrong fix and a per-call factory is too.\n */\nexport function createIdPrefixCounter(tag: string): () => string {\n let n = 0;\n return () => `${tag}${++n}-`;\n}\n","import * as React from 'react';\nimport { useVisuallyHiddenStyles } from './visuallyHidden';\n\nexport interface LiveAnnouncerProps {\n /** Read at the next pause. Changing this to a new non-empty value announces it. */\n polite?: string;\n /** Interrupts. Failures only. */\n assertive?: string;\n}\n\nfunction useAnnounceWithRepeat(\n next: string,\n set: React.Dispatch<React.SetStateAction<string>>,\n): void {\n React.useEffect(() => {\n if (!next) return;\n let cancelled = false;\n // Clear-then-set across two ticks. Screen readers SWALLOW a repeat: assigning a region\n // the text it already holds announces nothing, so two identical answers in a row would\n // be read once. Clearing first guarantees the region genuinely changes.\n set('');\n const id = setTimeout(() => {\n if (!cancelled) set(next);\n }, 0);\n return () => {\n cancelled = true;\n clearTimeout(id);\n };\n }, [next, set]);\n}\n\n/**\n * The two live regions for a conversation surface.\n *\n * ★ The transcript itself is NOT a live region, and that is the point. A live region on the\n * streaming node queues every token for announcement — NVDA and JAWS re-read the growing\n * string and never finish. The streaming bubble carries `aria-busy`, the typing indicator's\n * own `role=\"status\"` covers \"responding\", and this announces once per turn: the settled\n * answer (see `deriveAnnouncement` in ./core, which is where the rule lives).\n *\n * ★ `aria-atomic` so the whole message is read, not just the changed fragment.\n */\nexport function LiveAnnouncer({\n polite = '',\n assertive = '',\n}: LiveAnnouncerProps): React.ReactElement {\n const styles = useVisuallyHiddenStyles();\n const [politeText, setPoliteText] = React.useState('');\n const [assertiveText, setAssertiveText] = React.useState('');\n\n useAnnounceWithRepeat(polite, setPoliteText);\n useAnnounceWithRepeat(assertive, setAssertiveText);\n\n return (\n <>\n <div\n className={styles.root}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"agentkit-live-polite\"\n >\n {politeText}\n </div>\n <div\n className={styles.root}\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n data-testid=\"agentkit-live-assertive\"\n >\n {assertiveText}\n </div>\n </>\n );\n}\n","import { makeStyles } from '@fluentui/react-components';\n\n/**\n * Content available to assistive technology and not to sight.\n *\n * ★ NOT `display:none` and NOT `visibility:hidden` — both remove the node from the\n * accessibility tree, which is the opposite of the intent. The clip-rect recipe is the one\n * that keeps it announced.\n */\nexport const useVisuallyHiddenStyles = makeStyles({\n root: {\n position: 'absolute',\n width: '1px',\n height: '1px',\n margin: '-1px',\n padding: '0',\n overflow: 'hidden',\n clip: 'rect(0 0 0 0)',\n clipPath: 'inset(50%)',\n whiteSpace: 'nowrap',\n },\n});\n","import * as React from 'react';\n\n/**\n * Put focus somewhere sensible when the focused element disappears.\n *\n * ★ Fluent's tabster ships a `Restorer` and a `Deloser` for exactly this, and the kit needs\n * its own because the affordances that own focus in a transcript are the in-tree ones. A\n * chat surface removes focusable nodes constantly — a message is deleted, an approval card\n * resolves, a conversation closes. When that happens the browser puts focus on `<body>`:\n * the keyboard user's Tab position resets to the top of the page and the screen reader\n * loses its place.\n *\n * ★ It reads `document.activeElement` rather than tracking what it believes had focus,\n * because the interesting case is the one where focus has ALREADY been lost.\n */\nexport function useFocusRestore(containerRef: React.RefObject<HTMLElement>): () => void {\n return React.useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n // Only rescue focus that actually fell off. If it landed somewhere real, leave it alone.\n if (doc.activeElement && doc.activeElement !== doc.body) return;\n\n const focusable = container.querySelector<HTMLElement>(\n 'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])',\n );\n (focusable ?? container).focus();\n }, [containerRef]);\n}\n","import * as React from 'react';\n\nexport interface RovingTabindexOptions {\n orientation?: 'horizontal' | 'vertical';\n loop?: boolean;\n itemCount: number;\n onActivate?: (index: number) => void;\n}\n\nexport interface RovingTabindex {\n activeIndex: number;\n setActiveIndex: (index: number) => void;\n /** Spread onto each item. Exactly ONE item is tabbable at a time. */\n getItemProps: (index: number) => {\n tabIndex: 0 | -1;\n 'data-roving-item': true;\n onFocus: () => void;\n onKeyDown: (event: React.KeyboardEvent) => void;\n };\n}\n\n/**\n * One tab stop for a group, arrow keys within it — the WAI-ARIA roving tabindex.\n *\n * ★ Why this rather than Fluent's `Toolbar`: `react-toolbar` reaches\n * `useArrowNavigationGroup` → `getMover` → `core.attrHandlers.set`, which throws against a\n * Dynamics form's tabster (8.2.0, no `attrHandlers`) and unmounts the React tree. For a row\n * of buttons the ARIA pattern is ~40 lines, so this is the cheap side of the split-by-cost\n * decision; `TabList` and `Tree` are the expensive side and the kit uses Fluent's.\n *\n * ★ Without a roving index a transcript of 20 messages × 4 hover actions is 80 tab stops.\n */\nexport function useRovingTabindex(options: RovingTabindexOptions): RovingTabindex {\n const { orientation = 'horizontal', loop = true, itemCount, onActivate } = options;\n const [activeIndex, setActiveIndex] = React.useState(0);\n\n const clamp = React.useCallback(\n (index: number) => {\n if (itemCount === 0) return 0;\n return loop\n ? (index + itemCount) % itemCount\n : Math.min(Math.max(index, 0), itemCount - 1);\n },\n [itemCount, loop],\n );\n\n const getItemProps = React.useCallback(\n (index: number) => ({\n tabIndex: (index === activeIndex ? 0 : -1) as 0 | -1,\n 'data-roving-item': true as const,\n onFocus: () => setActiveIndex(index),\n onKeyDown: (event: React.KeyboardEvent) => {\n const prevKey = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n const nextKey = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n\n let target: number | null = null;\n if (event.key === nextKey) target = clamp(index + 1);\n else if (event.key === prevKey) target = clamp(index - 1);\n else if (event.key === 'Home') target = 0;\n else if (event.key === 'End') target = itemCount - 1;\n else if (event.key === 'Enter' || event.key === ' ') {\n onActivate?.(index);\n return;\n }\n if (target === null) return;\n\n event.preventDefault();\n event.stopPropagation();\n setActiveIndex(target);\n const group = (event.currentTarget as HTMLElement).parentElement;\n group?.querySelectorAll<HTMLElement>('[data-roving-item]')[target]?.focus();\n },\n }),\n [activeIndex, clamp, itemCount, onActivate, orientation],\n );\n\n return { activeIndex, setActiveIndex, getItemProps };\n}\n","import * as React from 'react';\nimport { shouldStickToBottom } from '../core/scroll';\n\nexport interface StickyScroll {\n /** Put on the scrolling element. */\n onScroll: () => void;\n /** Call to jump to the bottom regardless (e.g. a \"jump to latest\" button). */\n scrollToBottom: () => void;\n /** False once the reader scrolls up — drives a \"jump to latest\" affordance. */\n isPinned: boolean;\n}\n\n/**\n * Keep a transcript pinned to the bottom — but only while the reader is already there.\n *\n * ★★ THIS CARRIES A MEASURED DEFECT FORWARD. apps/form-builder's ChatPane once keyed its\n * scroll effect on the streaming message's CONTENT LENGTH, which queued a smooth\n * `scrollTo` per token — often 10+ per second — and jittered the viewport. Its fix was to\n * key on message COUNT and use `behavior: 'auto'`; both are reproduced here.\n *\n * ★★ AND IT ADDS THE HALF THAT WAS STILL MISSING. Sticking unconditionally means a reader who\n * scrolls up to re-read something mid-stream is yanked back to the bottom on the next\n * append. `wasPinnedRef` is sampled from SCROLL EVENTS, so it reflects where the reader\n * was before the append, not after.\n *\n * ★ `behavior: 'auto'`, never `'smooth'`: a queued smooth scroll is what produced the\n * jitter, and an involuntary animation is a WCAG 2.2.2 hazard besides.\n */\nexport function useStickyScroll(\n ref: React.RefObject<HTMLElement>,\n messageCount: number,\n): StickyScroll {\n const wasPinnedRef = React.useRef(true);\n const [isPinned, setIsPinned] = React.useState(true);\n\n const onScroll = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const pinned = shouldStickToBottom({\n scrollTop: el.scrollTop,\n scrollHeight: el.scrollHeight,\n clientHeight: el.clientHeight,\n });\n wasPinnedRef.current = pinned;\n setIsPinned(pinned);\n }, [ref]);\n\n const scrollToBottom = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n el.scrollTo({ top: el.scrollHeight, behavior: 'auto' });\n wasPinnedRef.current = true;\n setIsPinned(true);\n }, [ref]);\n\n React.useEffect(() => {\n if (!wasPinnedRef.current) return;\n const el = ref.current;\n if (!el) return;\n el.scrollTo({ top: el.scrollHeight, behavior: 'auto' });\n // ★ messageCount ONLY. Adding the streaming text here is the original defect.\n }, [messageCount, ref]);\n\n return { onScroll, scrollToBottom, isPinned };\n}\n","import * as React from 'react';\nimport {\n applyAgentEvent,\n appendUserMessage,\n deriveAnnouncement,\n initialConversation,\n NO_ANNOUNCEMENT,\n type Announcement,\n type AgentAttachment,\n type AgentMessage,\n type ConversationState,\n type IAgentService,\n} from '../core';\n\nexport interface UseConversationOptions {\n service: IAgentService;\n seed?: readonly AgentMessage[];\n grounding?: Record<string, unknown>;\n conversationId?: string;\n /** Ids are injected so tests and Storybook are deterministic. */\n createId?: () => string;\n}\n\nexport interface Conversation {\n state: ConversationState;\n announcement: Announcement;\n busy: boolean;\n send: (text: string, attachments?: AgentAttachment[]) => Promise<void>;\n cancel: () => void;\n}\n\nlet fallbackId = 0;\n\n/**\n * Drive an `IAgentService` into a `ConversationState`.\n *\n * ★ The reducer and the announcement rule are both PURE and live in ./core — this hook only\n * owns the effectful parts: the abort controller, the iteration, and holding the previous\n * state so a transition can be detected. That split is what lets the interesting rules be\n * tested without a DOM.\n *\n * ★ `send()` NEVER throws. A transport that throws mid-stream (which an AsyncIterable can do,\n * and a Promise-shaped seam cannot) is converted into terminal state, because the\n * alternative is an unmounted tree — the React-layer analogue of the tabster crash.\n */\nexport function useConversation(options: UseConversationOptions): Conversation {\n const { service, seed, grounding, conversationId, createId } = options;\n const [state, setState] = React.useState<ConversationState>(() => initialConversation(seed));\n const [announcement, setAnnouncement] = React.useState<Announcement>(NO_ANNOUNCEMENT);\n const abortRef = React.useRef<AbortController | null>(null);\n const stateRef = React.useRef(state);\n stateRef.current = state;\n\n const nextId = React.useCallback(\n () => createId?.() ?? `m${++fallbackId}-${Date.now().toString(36)}`,\n [createId],\n );\n\n const commit = React.useCallback((next: ConversationState) => {\n const previous = stateRef.current;\n stateRef.current = next;\n setState(next);\n const derived = deriveAnnouncement(next, previous);\n if (derived.polite || derived.assertive) setAnnouncement(derived);\n }, []);\n\n const cancel = React.useCallback(() => {\n abortRef.current?.abort();\n }, []);\n\n const send = React.useCallback(\n async (text: string, attachments?: AgentAttachment[]) => {\n if (!text.trim()) return;\n // Abort any in-flight turn before starting another, or the previous iterator keeps\n // running and both write into the same state.\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n let next = appendUserMessage(stateRef.current, { id: nextId(), text, attachments });\n commit(next);\n\n try {\n for await (const event of service.send({\n text,\n history: next.messages,\n grounding,\n attachments,\n conversationId,\n cancelSignal: controller.signal,\n })) {\n next = applyAgentEvent(next, event);\n commit(next);\n }\n } catch (error) {\n commit({\n ...next,\n streamingMessageId: null,\n status: 'error',\n failure: {\n status: 'error',\n message: error instanceof Error ? error.message : String(error),\n recoverable: true,\n },\n });\n } finally {\n if (abortRef.current === controller) abortRef.current = null;\n }\n },\n [service, grounding, conversationId, nextId, commit],\n );\n\n React.useEffect(() => () => abortRef.current?.abort(), []);\n\n const busy = state.status === 'connecting' || state.status === 'streaming';\n return { state, announcement, busy, send, cancel };\n}\n","import * as React from 'react';\nimport { Avatar, makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { AgentMessage, AgentParticipant } from '../core';\nimport { useVisuallyHiddenStyles } from '../a11y';\nimport { StreamingText } from './StreamingText';\nimport { MessageActions, type MessageActionsProps } from './MessageActions';\n\nexport interface MessageBubbleProps extends Omit<MessageActionsProps, 'message'> {\n message: AgentMessage;\n author?: AgentParticipant;\n /** First message of a run — renders the avatar and name. */\n isRunStart?: boolean;\n locale?: string;\n}\n\nconst useStyles = makeStyles({\n row: {\n display: 'flex',\n gap: tokens.spacingHorizontalS,\n position: 'relative',\n paddingRight: tokens.spacingHorizontalXXL,\n },\n own: { flexDirection: 'row-reverse', paddingRight: 0, paddingLeft: tokens.spacingHorizontalXXL },\n gutter: { width: '32px', flexShrink: 0 },\n stack: { display: 'flex', flexDirection: 'column', gap: '2px', minWidth: 0, maxWidth: '80%' },\n name: { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 },\n bubble: {\n padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalM}`,\n borderRadius: tokens.borderRadiusLarge,\n backgroundColor: tokens.colorNeutralBackground3,\n color: tokens.colorNeutralForeground1,\n fontSize: tokens.fontSizeBase300,\n },\n ownBubble: {\n backgroundColor: tokens.colorBrandBackground,\n color: tokens.colorNeutralForegroundOnBrand,\n },\n actions: {\n position: 'absolute',\n top: '-12px',\n right: tokens.spacingHorizontalS,\n opacity: 0,\n pointerEvents: 'none',\n transitionProperty: 'opacity',\n transitionDuration: tokens.durationFaster,\n },\n // ★ hover OR focus-within. Without the second selector the row is unreachable by keyboard.\n actionsVisible: { opacity: 1, pointerEvents: 'auto' },\n});\n\nexport function MessageBubble(props: MessageBubbleProps): React.ReactElement {\n const { message, author, isRunStart = true, locale, ...actionHandlers } = props;\n const styles = useStyles();\n const hidden = useVisuallyHiddenStyles();\n const [revealed, setRevealed] = React.useState(false);\n\n const own = message.role === 'user';\n const name = author?.displayName ?? (own ? 'You' : (message.provider ?? 'Assistant'));\n const time = new Intl.DateTimeFormat(locale, { timeStyle: 'short' }).format(new Date(message.createdAt));\n\n return (\n <div\n className={mergeClasses(styles.row, own && styles.own)}\n onMouseEnter={() => setRevealed(true)}\n onMouseLeave={() => setRevealed(false)}\n onFocus={() => setRevealed(true)}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setRevealed(false);\n }}\n data-testid=\"agentkit-message\"\n >\n <div className={styles.gutter}>\n {isRunStart ? <Avatar name={name} size={32} image={author?.imageUrl ? { src: author.imageUrl } : undefined} /> : null}\n </div>\n\n <div className={styles.stack}>\n {/* ★ The author and timestamp are ALWAYS in the accessible tree, even on a grouped\n continuation where they are visually suppressed. Grouping is a visual affordance;\n a screen reader navigating message-by-message would otherwise hear nothing\n identifying messages 2..N of a run — in a UI whose entire point is the distinction\n between what the user said and what the model said. */}\n <span className={hidden.root}>\n {name}, <time dateTime={new Date(message.createdAt).toISOString()}>{time}</time>\n </span>\n\n {isRunStart ? (\n <span className={styles.name} aria-hidden=\"true\">\n {name} · {time}\n </span>\n ) : null}\n\n <div\n className={mergeClasses(styles.bubble, own && styles.ownBubble)}\n // ★ Tells a screen reader the answer is still arriving, WITHOUT making the\n // transcript a live region — see a11y/LiveAnnouncer.\n aria-busy={message.streaming || undefined}\n >\n <StreamingText text={message.text} streaming={message.streaming} />\n </div>\n </div>\n\n <div className={mergeClasses(styles.actions, revealed && styles.actionsVisible)}>\n <MessageActions message={message} {...actionHandlers} />\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface StreamingTextProps {\n text: string;\n streaming?: boolean;\n}\n\nconst useStyles = makeStyles({\n root: { whiteSpace: 'pre-wrap', wordBreak: 'break-word' },\n caret: {\n display: 'inline-block',\n width: '2px',\n height: '1em',\n marginLeft: '2px',\n verticalAlign: 'text-bottom',\n backgroundColor: tokens.colorBrandForeground1,\n animationName: { '0%,49%': { opacity: 1 }, '50%,100%': { opacity: 0 } },\n animationDuration: '1s',\n animationIterationCount: 'infinite',\n // WCAG 2.2.2: a blinking caret is motion, and some readers cannot tolerate it.\n '@media (prefers-reduced-motion: reduce)': { animationName: 'none', opacity: 1 },\n },\n});\n\n/**\n * The in-flight answer.\n *\n * ★ A STABLE element, deliberately. If this subtree remounted per token, any focus inside the\n * streaming bubble (a citation chip, a copy button) would be thrown to `<body>` mid-answer.\n * Only the text node changes; the element identity does not. `useStreamingText.test.tsx`\n * pins that as an invariant rather than leaving it to a comment.\n */\nexport function StreamingText({ text, streaming }: StreamingTextProps): React.ReactElement {\n const styles = useStyles();\n return (\n <span className={styles.root} data-testid=\"agentkit-streaming-text\">\n {text}\n {streaming ? <span className={styles.caret} aria-hidden=\"true\" /> : null}\n </span>\n );\n}\n","import * as React from 'react';\nimport { CopyRegular, ArrowClockwiseRegular, ThumbLikeRegular, ThumbDislikeRegular } from '@fluentui/react-icons';\nimport { ActionToolbar, type ToolbarAction } from '../internal';\nimport type { AgentMessage } from '../core';\n\nexport interface MessageActionsProps {\n message: AgentMessage;\n onCopy?: (message: AgentMessage) => void;\n onRetry?: (message: AgentMessage) => void;\n onFeedback?: (message: AgentMessage, vote: 'up' | 'down') => void;\n}\n\n/**\n * The hover row on a message.\n *\n * ★★ It is revealed by `:hover` **or `:focus-within`** — see MessageBubble's styles. A\n * hover-only affordance is a WCAG 2.1.1 (Keyboard, Level A) failure outright: there is no\n * pointer-free route to it at all. The other naive choice, leaving the row permanently in\n * the tab order, adds N tab stops per message. Reveal-on-focus plus a roving tabindex gives\n * exactly one tab stop per message and a keyboard route to every action.\n */\nexport function MessageActions({\n message,\n onCopy,\n onRetry,\n onFeedback,\n}: MessageActionsProps): React.ReactElement | null {\n const actions: ToolbarAction[] = [];\n if (onCopy) {\n actions.push({ key: 'copy', label: 'Copy message', icon: <CopyRegular />, onClick: () => onCopy(message) });\n }\n if (onRetry && message.role === 'assistant') {\n actions.push({ key: 'retry', label: 'Regenerate', icon: <ArrowClockwiseRegular />, onClick: () => onRetry(message) });\n }\n if (onFeedback && message.role === 'assistant') {\n actions.push(\n { key: 'up', label: 'Good response', icon: <ThumbLikeRegular />, onClick: () => onFeedback(message, 'up') },\n { key: 'down', label: 'Bad response', icon: <ThumbDislikeRegular />, onClick: () => onFeedback(message, 'down') },\n );\n }\n if (actions.length === 0) return null;\n\n return <ActionToolbar actions={actions} label={`Actions for this message`} />;\n}\n","import * as React from 'react';\nimport { Button, Tooltip, makeStyles, tokens, mergeClasses } from '@fluentui/react-components';\nimport { useRovingTabindex } from '../a11y/useRovingTabindex';\n\nexport interface ToolbarAction {\n key: string;\n label: string;\n icon: React.ReactElement;\n onClick: () => void;\n disabled?: boolean;\n}\n\nexport interface ActionToolbarProps {\n actions: ToolbarAction[];\n label: string;\n className?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'inline-flex',\n gap: tokens.spacingHorizontalXXS,\n alignItems: 'center',\n backgroundColor: tokens.colorNeutralBackground1,\n borderRadius: tokens.borderRadiusMedium,\n boxShadow: tokens.shadow4,\n padding: tokens.spacingHorizontalXXS,\n },\n button: {\n // ★ A focus ring that survives Windows forced-colors. Once the kit owns its own focus\n // management it owns the indicator too, and `outline: none` + box-shadow — the usual\n // custom-focus recipe — disappears entirely under forced-colors.\n ':focus-visible': {\n outline: `2px solid ${tokens.colorStrokeFocus2}`,\n outlineOffset: '1px',\n },\n },\n});\n\n/**\n * The in-tree replacement for Fluent's `Toolbar`.\n *\n * ★ Fluent's reaches `useArrowNavigationGroup` → `getMover` → `core.attrHandlers.set`, which\n * throws against a Dynamics form's tabster and unmounts the tree. For a row of buttons the\n * WAI-ARIA pattern is small enough to own, which is why this is on the in-tree side of the\n * split while `TabList` and `Tree` are not.\n *\n * ★ ONE tab stop for the whole row (roving tabindex), not one per button. A transcript of 20\n * messages × 4 actions would otherwise add 80 tab stops between the reader and the composer.\n */\nexport function ActionToolbar({ actions, label, className }: ActionToolbarProps): React.ReactElement {\n const styles = useStyles();\n const roving = useRovingTabindex({ itemCount: actions.length, orientation: 'horizontal' });\n\n return (\n <div role=\"toolbar\" aria-label={label} aria-orientation=\"horizontal\" className={mergeClasses(styles.root, className)}>\n {actions.map((action, index) => {\n const item = roving.getItemProps(index);\n return (\n <Tooltip key={action.key} content={action.label} relationship=\"label\" withArrow>\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={action.icon}\n disabled={action.disabled}\n onClick={action.onClick}\n className={styles.button}\n {...item}\n />\n </Tooltip>\n );\n })}\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\n\nexport interface CardSurfaceProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Renders a highlighted edge — used by ApprovalCard while a decision is pending. */\n emphasis?: 'none' | 'attention';\n children?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: tokens.spacingVerticalXS,\n padding: tokens.spacingVerticalM,\n borderRadius: tokens.borderRadiusMedium,\n backgroundColor: tokens.colorNeutralBackground1,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n boxShadow: tokens.shadow2,\n },\n attention: { borderLeft: `3px solid ${tokens.colorBrandStroke1}` },\n});\n\n/**\n * The in-tree replacement for Fluent's `Card`.\n *\n * ★★ Fluent's `Card` calls `useFocusableGroup()` UNCONDITIONALLY — `react-card/useCard.js:66`,\n * a hook call, so the `shouldApplyFocusAttributes` guard below it only decides whether the\n * ATTRIBUTES are applied, not whether the hook runs. That reaches `getGroupper` and\n * `core.attrHandlers.set`, which throws against a Dynamics form's tabster (8.2.0, no\n * `attrHandlers`) and unmounts the whole React tree.\n *\n * ★★ It is also the single easiest thing in this kit to get wrong: `Card` is the obvious\n * import for anything card-shaped, the estate's closest existing v9 chat component wraps\n * its ENTIRE surface in one, and the canonical grep in the PCF standard\n * (`useArrowNavigationGroup|useModalAttributes|useRestoreFocus`) does not find `react-card`\n * because it omits `useFocusableGroup`. eslint bans `Card` by name outside this directory.\n *\n * ★ What is lost is Groupper's \"card is one tab stop, Enter to enter, Escape to exit\". The\n * cards here hold at most a couple of buttons, so the plain tab order is correct and\n * cheaper; if a card ever holds many controls, revisit rather than reaching for `Card`.\n */\nexport const CardSurface = React.forwardRef<HTMLDivElement, CardSurfaceProps>(\n function CardSurface({ emphasis = 'none', className, children, ...rest }, ref) {\n const styles = useStyles();\n return (\n <div\n ref={ref}\n className={mergeClasses(styles.root, emphasis === 'attention' && styles.attention, className)}\n {...rest}\n >\n {children}\n </div>\n );\n },\n);\n","import * as React from 'react';\nimport { Button, makeStyles, tokens, Text } from '@fluentui/react-components';\nimport { CardSurface } from './CardSurface';\n\nexport interface ConfirmInlineProps {\n open: boolean;\n title: string;\n body: React.ReactNode;\n confirmLabel?: string;\n cancelLabel?: string;\n destructive?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nconst useStyles = makeStyles({\n root: { maxWidth: '420px' },\n actions: { display: 'flex', gap: tokens.spacingHorizontalS, justifyContent: 'flex-end', marginTop: tokens.spacingVerticalS },\n});\n\nconst FOCUSABLE =\n 'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * An in-tree confirmation, replacing Fluent's `Dialog`.\n *\n * ★ `react-dialog` reaches `useModalAttributes` → `getModalizer` + `getRestorer` →\n * `core.attrHandlers.set`. The gallery's `image-gallery-field` removed `Dialog` for exactly\n * this and cut its bundle 431,706 → 317,346 bytes, so the trade is well established.\n *\n * ★★ BUT THAT PRECEDENT SHIPS THREE FOCUS DEFECTS, AND THIS FIXES THEM. Read against it:\n * it focuses into the dialog and handles Escape, but it (1) never returns focus to the\n * trigger on close, (2) has no focus trap, so Tab walks straight out of a `role=\"alertdialog\"`,\n * and (3) omits `aria-modal` — so the role asserts a modality the implementation does not\n * provide, which is an ARIA lie rather than a missing nicety. Removing tabster means\n * removing its Modalizer and Restorer, and whatever they were doing has to be done here.\n */\nexport function ConfirmInline(props: ConfirmInlineProps): React.ReactElement | null {\n const { open, title, body, confirmLabel = 'Confirm', cancelLabel = 'Cancel', destructive, onConfirm, onCancel } = props;\n const styles = useStyles();\n const ref = React.useRef<HTMLDivElement>(null);\n const returnTo = React.useRef<HTMLElement | null>(null);\n const titleId = React.useId();\n const bodyId = React.useId();\n\n // (1) Remember where focus came from, and put it back. Without this the keyboard user is\n // returned to <body> — the top of the page — every time they cancel.\n React.useEffect(() => {\n if (!open) return;\n returnTo.current = (document.activeElement as HTMLElement | null) ?? null;\n const first = ref.current?.querySelector<HTMLElement>(FOCUSABLE);\n first?.focus();\n return () => {\n const target = returnTo.current;\n if (target && target.isConnected) target.focus();\n };\n }, [open]);\n\n if (!open) return null;\n\n // (2) The trap. A `role=\"alertdialog\"` that Tab can leave is announcing something untrue.\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onCancel();\n return;\n }\n if (event.key !== 'Tab') return;\n const items = [...(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])];\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n return (\n <CardSurface\n ref={ref}\n role=\"alertdialog\"\n // (3) The role without this is a claim the implementation does not honour.\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={bodyId}\n onKeyDown={onKeyDown}\n className={styles.root}\n emphasis=\"attention\"\n >\n <Text id={titleId} weight=\"semibold\">\n {title}\n </Text>\n <Text id={bodyId} size={200}>\n {body}\n </Text>\n <div className={styles.actions}>\n <Button size=\"small\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n <Button size=\"small\" appearance={destructive ? 'primary' : 'primary'} onClick={onConfirm}>\n {confirmLabel}\n </Button>\n </div>\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, mergeClasses } from '@fluentui/react-components';\nimport { ChevronRightRegular, ChevronDownRegular } from '@fluentui/react-icons';\n\nexport interface DisclosureProps {\n id: string;\n summary: React.ReactNode;\n children: React.ReactNode;\n defaultOpen?: boolean;\n className?: string;\n}\n\nconst useStyles = makeStyles({\n trigger: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalXS,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: `${tokens.spacingVerticalXXS} 0`,\n color: tokens.colorNeutralForeground2,\n font: 'inherit',\n fontSize: tokens.fontSizeBase200,\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '1px' },\n },\n panel: { paddingTop: tokens.spacingVerticalXS },\n});\n\n/**\n * The in-tree replacement for Fluent's `Accordion`.\n *\n * ★ APG's Disclosure pattern really is just `<button aria-expanded aria-controls>` plus a\n * labelled region — there is nothing else to it. `Accordion` adds arrow navigation between\n * headers, which a citation list or a trace does not need, and reaches\n * `useArrowNavigationGroup` to provide it. So this is the cheap side of the split.\n */\nexport function Disclosure({\n id,\n summary,\n children,\n defaultOpen = false,\n className,\n}: DisclosureProps): React.ReactElement {\n const styles = useStyles();\n const [open, setOpen] = React.useState(defaultOpen);\n const panelId = `${id}-panel`;\n\n return (\n <div className={className}>\n <button\n type=\"button\"\n id={id}\n className={styles.trigger}\n aria-expanded={open}\n aria-controls={panelId}\n onClick={() => setOpen((v) => !v)}\n >\n {open ? <ChevronDownRegular /> : <ChevronRightRegular />}\n {summary}\n </button>\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={id}\n hidden={!open}\n className={mergeClasses(styles.panel)}\n >\n {open ? children : null}\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport type { DayDividerLabel } from '../core';\n\nexport interface DayDividerProps {\n label: DayDividerLabel;\n locale?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalM,\n margin: `${tokens.spacingVerticalM} 0`,\n color: tokens.colorNeutralForeground3,\n fontSize: tokens.fontSizeBase200,\n },\n rule: { flex: 1, height: '1px', backgroundColor: tokens.colorNeutralStroke2 },\n});\n\n/** Map the pure descriptor to words. ★ The formatting lives HERE, not in ./core, so the host\n * can localise it and so the core function stays deterministic across CI locales. */\nexport function formatDayLabel(label: DayDividerLabel, locale?: string): string {\n switch (label.kind) {\n case 'today':\n return 'Today';\n case 'yesterday':\n return 'Yesterday';\n case 'weekday':\n return new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: 'UTC' }).format(\n new Date(`${label.iso}T00:00:00Z`),\n );\n case 'date':\n return new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeZone: 'UTC' }).format(\n new Date(`${label.iso}T00:00:00Z`),\n );\n }\n}\n\n/** ★ `role=\"separator\"` with an accessible name. A bare text node floating between list items\n * reads as a message. */\nexport function DayDivider({ label, locale }: DayDividerProps): React.ReactElement {\n const styles = useStyles();\n const text = formatDayLabel(label, locale);\n return (\n <div className={styles.root} role=\"separator\" aria-label={text}>\n <span className={styles.rule} aria-hidden=\"true\" />\n <span>{text}</span>\n <span className={styles.rule} aria-hidden=\"true\" />\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface TypingIndicatorProps {\n /** Announced. Keep it short — it interrupts nothing but is read on appearance. */\n label?: string;\n}\n\nconst useStyles = makeStyles({\n root: { display: 'inline-flex', gap: '4px', alignItems: 'center', padding: tokens.spacingVerticalXS },\n dot: {\n width: '6px',\n height: '6px',\n borderRadius: tokens.borderRadiusCircular,\n backgroundColor: tokens.colorNeutralForeground3,\n animationName: { '0%,80%,100%': { opacity: 0.3 }, '40%': { opacity: 1 } },\n animationDuration: '1.4s',\n animationIterationCount: 'infinite',\n '@media (prefers-reduced-motion: reduce)': { animationName: 'none', opacity: 0.6 },\n },\n d2: { animationDelay: '0.2s' },\n d3: { animationDelay: '0.4s' },\n});\n\n/**\n * ★ This carries \"the assistant is responding\" for screen readers, via its own `role=\"status\"`\n * firing when it MOUNTS. That is why `deriveAnnouncement` does not also announce the start —\n * doing both would say it twice.\n */\nexport function TypingIndicator({ label = 'Assistant is responding' }: TypingIndicatorProps): React.ReactElement {\n const styles = useStyles();\n return (\n <div className={styles.root} role=\"status\" aria-label={label} data-testid=\"agentkit-typing\">\n <span className={styles.dot} aria-hidden=\"true\" />\n <span className={`${styles.dot} ${styles.d2}`} aria-hidden=\"true\" />\n <span className={`${styles.dot} ${styles.d3}`} aria-hidden=\"true\" />\n </div>\n );\n}\n","import * as React from 'react';\nimport { Button, Textarea, makeStyles, tokens, Tooltip } from '@fluentui/react-components';\nimport { SendRegular, StopRegular } from '@fluentui/react-icons';\n\nexport interface ComposerProps {\n value: string;\n onChange: (value: string) => void;\n onSend: (value: string) => void;\n onStop?: () => void;\n busy?: boolean;\n disabled?: boolean;\n placeholder?: string;\n maxLength?: number;\n /** 'enter' sends on Enter; 'mod+enter' needs Ctrl/Cmd. */\n sendOn?: 'enter' | 'mod+enter';\n /** Rendered left of the send button — attachments, formatting, etc. */\n toolbar?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n gap: tokens.spacingHorizontalS,\n alignItems: 'flex-end',\n padding: tokens.spacingVerticalS,\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n input: { flex: 1 },\n hint: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n});\n\n/**\n * The send box.\n *\n * ★ `sendOn` is configurable, and defaults to Enter only because that is what users expect\n * from Teams. Enter-to-send in a multiline field is hostile to dictation and voice control,\n * and Shift+Enter is undiscoverable — hence the `aria-describedby` hint, which makes the\n * contract audible instead of folklore.\n *\n * ★ Deliberately NOT Fluent's `Toolbar` for the affordance row: it reaches\n * `useArrowNavigationGroup`. Consumers pass plain buttons, or the in-tree ActionToolbar.\n */\nexport function Composer(props: ComposerProps): React.ReactElement {\n const {\n value, onChange, onSend, onStop, busy = false, disabled = false,\n placeholder = 'Type a message', maxLength, sendOn = 'enter', toolbar,\n } = props;\n const styles = useStyles();\n const hintId = React.useId();\n\n const submit = () => {\n const text = value.trim();\n if (!text || busy || disabled) return;\n onSend(text);\n };\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key !== 'Enter') return;\n const wants = sendOn === 'enter' ? !event.shiftKey : event.metaKey || event.ctrlKey;\n if (!wants) return;\n event.preventDefault();\n submit();\n };\n\n const hint = sendOn === 'enter' ? 'Press Enter to send, Shift plus Enter for a new line.' : 'Press Control or Command plus Enter to send.';\n\n return (\n <div className={styles.root}>\n <div className={styles.input}>\n <Textarea\n value={value}\n onChange={(_, data) => onChange(data.value)}\n onKeyDown={onKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n maxLength={maxLength}\n resize=\"vertical\"\n aria-label={placeholder}\n aria-describedby={hintId}\n textarea={{ 'aria-multiline': true }}\n />\n <span id={hintId} className={styles.hint}>\n {hint}\n </span>\n </div>\n {toolbar}\n {busy && onStop ? (\n <Tooltip content=\"Stop generating\" relationship=\"label\" withArrow>\n <Button appearance=\"secondary\" icon={<StopRegular />} onClick={onStop} />\n </Tooltip>\n ) : (\n <Tooltip content=\"Send\" relationship=\"label\" withArrow>\n <Button\n appearance=\"primary\"\n icon={<SendRegular />}\n onClick={submit}\n disabled={!value.trim() || busy || disabled}\n />\n </Tooltip>\n )}\n </div>\n );\n}\n","import * as React from 'react';\nimport { Button, makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface SuggestedPromptsProps {\n prompts: readonly string[];\n onPick: (prompt: string) => void;\n heading?: string;\n}\n\nconst useStyles = makeStyles({\n root: { display: 'flex', flexWrap: 'wrap', gap: tokens.spacingHorizontalXS, padding: tokens.spacingVerticalXS },\n heading: { width: '100%', fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 },\n});\n\n/** ★ Plain Buttons in a labelled list, not Fluent's `TagGroup` — `react-tags` reaches\n * `useArrowNavigationGroup`, and chips gain nothing from it here. */\nexport function SuggestedPrompts({\n prompts,\n onPick,\n heading = 'Suggested follow-ups',\n}: SuggestedPromptsProps): React.ReactElement | null {\n const styles = useStyles();\n if (prompts.length === 0) return null;\n return (\n <div className={styles.root} role=\"group\" aria-label={heading}>\n <span className={styles.heading}>{heading}</span>\n {prompts.map((prompt) => (\n <Button key={prompt} size=\"small\" appearance=\"outline\" onClick={() => onPick(prompt)}>\n {prompt}\n </Button>\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport { SuggestedPrompts } from './SuggestedPrompts';\n\nexport interface EmptyConversationProps {\n title?: string;\n description?: string;\n prompts?: readonly string[];\n onPick?: (prompt: string) => void;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: tokens.spacingVerticalS,\n height: '100%',\n padding: tokens.spacingVerticalXXL,\n textAlign: 'center',\n color: tokens.colorNeutralForeground3,\n },\n});\n\nexport function EmptyConversation({\n title = 'Ask the agent',\n description = 'It answers from the records you have open.',\n prompts = [],\n onPick,\n}: EmptyConversationProps): React.ReactElement {\n const styles = useStyles();\n return (\n <div className={styles.root}>\n <Text as=\"h2\" size={500} weight=\"semibold\">\n {title}\n </Text>\n <Text>{description}</Text>\n {onPick && prompts.length > 0 ? (\n <SuggestedPrompts prompts={prompts} onPick={onPick} heading=\"Try one of these\" />\n ) : null}\n </div>\n );\n}\n","import * as React from 'react';\nimport {\n MessageBar,\n MessageBarBody,\n MessageBarTitle,\n MessageBarActions,\n Button,\n} from '@fluentui/react-components';\nimport type { AgentFailure } from '../core';\nimport { runStatusSeverity } from '../core';\n\nexport interface SystemNoticeProps {\n failure?: AgentFailure;\n guarded?: boolean;\n onRetry?: () => void;\n}\n\nconst INTENT = { success: 'success', warning: 'warning', error: 'error', info: 'info' } as const;\n\n/**\n * A terminal state the user needs to see.\n *\n * ★ `blocked` / `refused` / `notProvisioned` render as WARNING or INFO, not error — they are\n * different outcomes needing different fixes, and flattening them into \"something went\n * wrong\" is what makes an unprovisioned environment look broken.\n * ★ The state is in the TEXT, never only in the colour (WCAG 1.4.1).\n */\nexport function SystemNotice({ failure, guarded, onRetry }: SystemNoticeProps): React.ReactElement | null {\n if (!failure && !guarded) return null;\n\n if (!failure && guarded) {\n return (\n <MessageBar intent=\"warning\">\n <MessageBarBody>\n <MessageBarTitle>Response withheld</MessageBarTitle>\n The provider substituted safe text for the generated answer.\n </MessageBarBody>\n </MessageBar>\n );\n }\n if (!failure) return null;\n\n const title: Record<string, string> = {\n blocked: 'Response withheld',\n refused: 'The agent declined',\n error: 'Something went wrong',\n notProvisioned: 'Not configured',\n cancelled: 'Stopped',\n };\n\n return (\n <MessageBar intent={INTENT[runStatusSeverity(failure.status)]}>\n <MessageBarBody>\n <MessageBarTitle>{title[failure.status] ?? 'Notice'}</MessageBarTitle>\n {failure.message}\n </MessageBarBody>\n {failure.recoverable && onRetry ? (\n <MessageBarActions>\n <Button size=\"small\" onClick={onRetry}>\n Try again\n </Button>\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { Badge, Tooltip, type BadgeProps } from '@fluentui/react-components';\nimport {\n CheckmarkCircleRegular, ShieldErrorRegular, DismissCircleRegular,\n ErrorCircleRegular, PlugDisconnectedRegular, StopRegular,\n} from '@fluentui/react-icons';\nimport type { AgentRunStatus } from '../core';\n\nexport interface AgentStatusBadgeProps {\n status: AgentRunStatus;\n /** Shown in a tooltip — the provider's own message, when there is one. */\n reason?: string;\n size?: BadgeProps['size'];\n}\n\ninterface Presentation {\n label: string;\n color: NonNullable<BadgeProps['color']>;\n icon: React.ReactElement;\n}\n\n/**\n * ★★ SIX STATES, EACH WITH ITS OWN WORDS.\n *\n * The whole reason the run ladder is six-valued rather than {ok|error} is that these need\n * different reactions: `blocked` is a content filter, `refused` is the model declining,\n * `notProvisioned` is nobody having turned the service on, `cancelled` is the user pressing\n * stop. Collapsing any pair into a shared label throws that away — so the label is part of\n * the contract, and a test enumerates the union to prove each is distinct and non-empty.\n *\n * ★ The state is in the TEXT, never only the colour (WCAG 1.4.1). Four of these would otherwise\n * be shades of red.\n */\nconst PRESENTATION: Record<AgentRunStatus, Presentation> = {\n succeeded: { label: 'Succeeded', color: 'success', icon: <CheckmarkCircleRegular /> },\n blocked: { label: 'Blocked by content filter', color: 'warning', icon: <ShieldErrorRegular /> },\n refused: { label: 'Declined', color: 'warning', icon: <DismissCircleRegular /> },\n error: { label: 'Error', color: 'danger', icon: <ErrorCircleRegular /> },\n notProvisioned: { label: 'Not configured', color: 'informative', icon: <PlugDisconnectedRegular /> },\n cancelled: { label: 'Stopped', color: 'subtle', icon: <StopRegular /> },\n};\n\n/** Exported so the label contract can be asserted directly rather than scraped from markup. */\nexport function runStatusLabel(status: AgentRunStatus): string {\n return PRESENTATION[status].label;\n}\n\nexport function AgentStatusBadge({ status, reason, size = 'medium' }: AgentStatusBadgeProps): React.ReactElement {\n const { label, color, icon } = PRESENTATION[status];\n const badge = (\n <Badge appearance=\"tint\" color={color} icon={icon} size={size}>\n {label}\n </Badge>\n );\n return reason ? (\n <Tooltip content={reason} relationship=\"description\" withArrow>\n {badge}\n </Tooltip>\n ) : (\n badge\n );\n}\n","import * as React from 'react';\nimport { MessageBar, MessageBarBody, MessageBarTitle, MessageBarActions, Button } from '@fluentui/react-components';\nimport type { AgentAvailability } from '../core';\n\nexport interface AvailabilityBannerProps {\n availability?: AgentAvailability;\n onRetry?: () => void;\n /** Rendered beside Retry — a link to the setup doc, a \"Configure\" button. */\n actions?: React.ReactNode;\n}\n\n/**\n * Whether the agent can answer here, and if not, why.\n *\n * ★★ `notProvisioned` renders as INFORMATION, not an error. Nobody having configured the service\n * yet is a normal state in an on-demand Azure estate; dressing it as a failure is what makes a\n * working app look broken, and it needs a completely different response from an outage.\n *\n * ★ `reason` is displayed rather than summarised. \"Not licensed\" and \"not on this host\" need\n * different fixes, and the seam keeps them distinct precisely so the UI can say which.\n */\nexport function AvailabilityBanner({\n availability,\n onRetry,\n actions,\n}: AvailabilityBannerProps): React.ReactElement | null {\n if (!availability || availability.available) return null;\n\n const notProvisioned = availability.status === 'notProvisioned';\n return (\n <MessageBar intent={notProvisioned ? 'info' : 'warning'}>\n <MessageBarBody>\n <MessageBarTitle>\n {notProvisioned ? 'No agent configured' : 'The agent is unavailable'}\n </MessageBarTitle>\n {availability.reason ?? 'No reason was reported.'}\n </MessageBarBody>\n {onRetry || actions ? (\n <MessageBarActions>\n {actions}\n {onRetry ? (\n <Button size=\"small\" onClick={onRetry}>\n Check again\n </Button>\n ) : null}\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport type { AgentUsage } from '../core';\n\nexport interface UsageMeterProps {\n usage?: AgentUsage;\n show?: readonly ('tokens' | 'cost' | 'duration' | 'model')[];\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: tokens.spacingHorizontalM,\n fontSize: tokens.fontSizeBase100,\n color: tokens.colorNeutralForeground3,\n },\n item: { display: 'flex', gap: tokens.spacingHorizontalXXS },\n value: { fontFamily: tokens.fontFamilyMonospace },\n unknown: { fontStyle: 'italic' },\n});\n\n/**\n * Tokens, cost, latency.\n *\n * ★★ \"Not reported\" is rendered as such, never as 0. A provider that does not report cost and\n * one that cost nothing are completely different facts, and showing `$0.00` for the first is\n * a confident lie — the kind that gets believed because it looks like data.\n */\nexport function UsageMeter({\n usage,\n show = ['tokens', 'cost', 'duration'],\n}: UsageMeterProps): React.ReactElement | null {\n const styles = useStyles();\n if (!usage) return null;\n\n const items: { key: string; label: string; value: string; known: boolean }[] = [];\n\n if (show.includes('tokens')) {\n const known = usage.inputTokens !== undefined || usage.outputTokens !== undefined;\n items.push({\n key: 'tokens',\n label: 'Tokens',\n value: known\n ? `${usage.inputTokens ?? 0} in / ${usage.outputTokens ?? 0} out${\n usage.cachedTokens ? ` / ${usage.cachedTokens} cached` : ''\n }`\n : 'not reported',\n known,\n });\n }\n if (show.includes('cost')) {\n const known = usage.costUsd !== undefined;\n items.push({\n key: 'cost',\n label: 'Cost',\n value: known ? `$${usage.costUsd!.toFixed(6)}` : 'not reported',\n known,\n });\n }\n if (show.includes('duration')) {\n const known = usage.durationMs !== undefined;\n items.push({\n key: 'duration',\n label: 'Duration',\n value: known ? `${usage.durationMs} ms` : 'not reported',\n known,\n });\n }\n if (show.includes('model') && usage.model) {\n items.push({ key: 'model', label: 'Model', value: usage.model, known: true });\n }\n\n return (\n <div className={styles.root}>\n {items.map((item) => (\n <span key={item.key} className={styles.item}>\n {item.label}:{' '}\n <span className={item.known ? styles.value : styles.unknown}>{item.value}</span>\n </span>\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { MessageBar, MessageBarBody, MessageBarTitle, MessageBarActions, Button } from '@fluentui/react-components';\nimport type { AgentFailure } from '../core';\n\nexport interface ThrottleNoticeProps {\n failure?: AgentFailure;\n onRetry?: () => void;\n /** Injected so the countdown is testable without fake timers. */\n now?: () => number;\n}\n\n/**\n * A rate-limit notice that counts down.\n *\n * ★ It renders only for a failure that is BOTH retriable and carries `retryAfterMs`. A countdown\n * over an unknown wait would be invented, and a retry button that fires into an active throttle\n * just burns the next window.\n */\nexport function ThrottleNotice({ failure, onRetry, now = Date.now }: ThrottleNoticeProps): React.ReactElement | null {\n const retryAfterMs = failure?.retryAfterMs;\n const eligible = Boolean(failure?.recoverable && retryAfterMs && retryAfterMs > 0);\n\n const [remaining, setRemaining] = React.useState(retryAfterMs ?? 0);\n\n React.useEffect(() => {\n if (!eligible) return;\n const deadline = now() + (retryAfterMs ?? 0);\n setRemaining(retryAfterMs ?? 0);\n const id = setInterval(() => {\n const left = deadline - now();\n setRemaining(left > 0 ? left : 0);\n if (left <= 0) clearInterval(id);\n }, 250);\n return () => clearInterval(id);\n }, [eligible, retryAfterMs, now]);\n\n if (!eligible || !failure) return null;\n\n const seconds = Math.ceil(remaining / 1000);\n const ready = remaining <= 0;\n\n return (\n <MessageBar intent=\"warning\">\n <MessageBarBody>\n <MessageBarTitle>Rate limited</MessageBarTitle>\n {ready ? 'You can try again now.' : `${failure.message} Try again in ${seconds}s.`}\n </MessageBarBody>\n {onRetry ? (\n <MessageBarActions>\n <Button size=\"small\" onClick={onRetry} disabled={!ready}>\n Try again\n </Button>\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { Badge } from '@fluentui/react-components';\n\nexport interface ModelBadgeProps {\n provider?: string;\n model?: string;\n version?: string;\n}\n\n/** Which agent, which model, which version — so a run can be traced to a configuration. */\nexport function ModelBadge({ provider, model, version }: ModelBadgeProps): React.ReactElement | null {\n const parts = [provider, model, version ? `v${version}` : undefined].filter(Boolean);\n if (parts.length === 0) return null;\n return (\n <Badge appearance=\"outline\" color=\"informative\">\n {parts.join(' · ')}\n </Badge>\n );\n}\n","import * as React from 'react';\nimport { Dropdown, Option, Field } from '@fluentui/react-components';\nimport type { AgentDescriptor } from './types';\n\nexport interface AgentPickerProps {\n agents: readonly AgentDescriptor[];\n selectedId?: string;\n onSelect: (id: string) => void;\n label?: string;\n disabled?: boolean;\n}\n\n/**\n * Choose which agent answers.\n *\n * ★ Fluent's `Dropdown` — measured tabster-safe. `react-combobox` imports only\n * `useTabsterAttributes`, `useMergedTabsterAttributes_unstable`, `useSetKeyboardNavigation` and\n * `useOnKeyboardNavigationChange`; `useTabsterAttributes` calls `useTabster()` with NO argument,\n * and `useTabster`'s default factory is the identity, so it never reaches a `get*` factory or\n * `attrHandlers.set`. Two reviewers disagreed about this and the source settled it.\n *\n * ★ Selecting an agent is a CONFIG change, not a capability change: the seam still has no write\n * method whichever agent is chosen.\n */\nexport function AgentPicker({\n agents,\n selectedId,\n onSelect,\n label = 'Agent',\n disabled,\n}: AgentPickerProps): React.ReactElement {\n const selected = agents.find((a) => a.id === selectedId);\n\n return (\n <Field label={label}>\n <Dropdown\n disabled={disabled}\n value={selected ? selected.name : ''}\n selectedOptions={selectedId ? [selectedId] : []}\n onOptionSelect={(_, data) => {\n if (data.optionValue) onSelect(data.optionValue);\n }}\n placeholder=\"Select an agent\"\n >\n {agents.map((agent) => (\n <Option key={agent.id} value={agent.id} text={agent.name}>\n {agent.model ? `${agent.name} — ${agent.model}` : agent.name}\n </Option>\n ))}\n </Dropdown>\n </Field>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { AgentMessage, AgentToolCall } from '../core';\nimport { AgentStatusBadge } from './AgentStatusBadge';\nimport { UsageMeter } from './UsageMeter';\nimport { Disclosure } from '../internal';\n\nexport interface RunTimelineProps {\n message: AgentMessage;\n /** Collapsed by default: a trace is diagnostic, not the primary reading. */\n defaultOpen?: boolean;\n}\n\nconst useStyles = makeStyles({\n list: { listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n step: { display: 'flex', gap: tokens.spacingHorizontalS, alignItems: 'baseline' },\n index: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3, minWidth: '18px' },\n name: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase200 },\n status: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n section: { marginTop: tokens.spacingVerticalS },\n});\n\nconst TOOL_STATUS: Record<AgentToolCall['status'], string> = {\n proposed: 'proposed',\n running: 'running',\n succeeded: 'succeeded',\n failed: 'failed',\n denied: 'denied',\n};\n\n/**\n * What one turn actually did: its outcome, the tools it called, what it cited, what it cost.\n *\n * ★ An ORDERED LIST, not Fluent's `Tree`. `react-tree` reaches `useArrowNavigationGroup`, and a\n * trace is a sequence — the ordering is the information. If steps ever nest, revisit rather\n * than flattening a tree into a list.\n *\n * ★ Each step's status is in TEXT beside it. A row of coloured dots conveys nothing to a\n * screen reader and little to a colour-blind reader.\n */\nexport function RunTimeline({ message, defaultOpen = false }: RunTimelineProps): React.ReactElement | null {\n const styles = useStyles();\n const id = React.useId();\n\n const calls = message.toolCalls ?? [];\n const sources = message.sources ?? [];\n const hasAnything = calls.length > 0 || sources.length > 0 || message.usage || message.failure;\n if (!hasAnything) return null;\n\n const status = message.failure?.status ?? (message.guarded ? 'blocked' : 'succeeded');\n\n return (\n <Disclosure\n id={id}\n defaultOpen={defaultOpen}\n summary={`Trace — ${calls.length} tool call${calls.length === 1 ? '' : 's'}`}\n >\n <div className={styles.step}>\n <AgentStatusBadge status={status} reason={message.failure?.message} size=\"small\" />\n </div>\n\n {calls.length > 0 ? (\n <ol className={styles.list} aria-label=\"Tool calls\">\n {calls.map((call, index) => (\n <li key={call.id} className={styles.step}>\n <span className={styles.index}>{index + 1}.</span>\n <span className={styles.name}>{call.name}</span>\n <span className={styles.status}>{TOOL_STATUS[call.status]}</span>\n </li>\n ))}\n </ol>\n ) : null}\n\n {sources.length > 0 ? (\n <Text as=\"p\" size={200} className={styles.section}>\n {sources.length} source{sources.length === 1 ? '' : 's'} retrieved\n </Text>\n ) : null}\n\n <div className={styles.section}>\n <UsageMeter usage={message.usage} show={['tokens', 'cost', 'duration', 'model']} />\n </div>\n </Disclosure>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { AgentRunRecord } from './types';\nimport { AgentStatusBadge } from './AgentStatusBadge';\nimport { UsageMeter } from './UsageMeter';\n\nexport interface RunHistoryPanelProps {\n runs: readonly AgentRunRecord[];\n /**\n * A grid to render instead of the built-in list.\n *\n * ★★ THIS SLOT IS WHY THERE IS NO `RunHistoryList`. A run history is tabular, and this repo\n * already ships a grid — `@dataverse-kit/grid-kit/v9` — with sorting, virtualisation and\n * column chooser. Re-implementing a thin version here would be a second grid to maintain\n * and a worse one.\n *\n * It is a SLOT rather than a dependency because grid-kit/v9's `DataGrid` builds on\n * `react-table` and its toolbar on `Menu`, both of which reach tabster. A host that accepts\n * that passes a grid in; a host that does not gets the fallback list below. That is\n * surface-kit's documented \"pass grids in as children\" pattern, and it moves the tabster\n * decision to the host, where it belongs.\n */\n grid?: React.ReactNode;\n locale?: string;\n emptyLabel?: string;\n}\n\nconst useStyles = makeStyles({\n list: { listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n row: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n padding: tokens.spacingVerticalXS,\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, flexWrap: 'wrap' },\n time: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n prompt: { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },\n id: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n empty: { padding: tokens.spacingVerticalM, color: tokens.colorNeutralForeground3 },\n});\n\nexport function RunHistoryPanel({\n runs,\n grid,\n locale,\n emptyLabel = 'No runs yet.',\n}: RunHistoryPanelProps): React.ReactElement {\n const styles = useStyles();\n if (grid) return <>{grid}</>;\n if (runs.length === 0) {\n return (\n <Text className={styles.empty} size={200}>\n {emptyLabel}\n </Text>\n );\n }\n\n return (\n <ul className={styles.list} aria-label=\"Run history\">\n {runs.map((run) => (\n <li key={run.id} className={styles.row}>\n <div className={styles.head}>\n <AgentStatusBadge status={run.status} size=\"small\" />\n <span className={styles.time}>\n {new Intl.DateTimeFormat(locale, { dateStyle: 'short', timeStyle: 'short' }).format(\n new Date(run.startedAt),\n )}\n </span>\n {/* ★ The correlation id is surfaced, not hidden: it is the only handle someone has\n when finding this run in App Insights at 3am. */}\n {run.correlationId ? <span className={styles.id}>{run.correlationId}</span> : null}\n </div>\n {run.prompt ? <span className={styles.prompt}>{run.prompt}</span> : null}\n <UsageMeter usage={run.usage} />\n </li>\n ))}\n </ul>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { AgentAvailability } from '../core';\nimport type { AgentDescriptor, AgentRunRecord } from './types';\nimport { AvailabilityBanner } from './AvailabilityBanner';\nimport { AgentPicker } from './AgentPicker';\nimport { ModelBadge } from './ModelBadge';\nimport { RunHistoryPanel } from './RunHistoryPanel';\n\nexport interface AgentOpsPanelProps {\n availability?: AgentAvailability;\n agents?: readonly AgentDescriptor[];\n selectedAgentId?: string;\n onSelectAgent?: (id: string) => void;\n runs?: readonly AgentRunRecord[];\n /** Passed straight through to RunHistoryPanel — see that component for why it is a slot. */\n runsGrid?: React.ReactNode;\n onRefresh?: () => void;\n locale?: string;\n}\n\nconst useStyles = makeStyles({\n root: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalM, minWidth: 0 },\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, flexWrap: 'wrap' },\n section: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n caps: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n});\n\n/** The composed ops surface: is it available, which agent, what has it done. */\nexport function AgentOpsPanel(props: AgentOpsPanelProps): React.ReactElement {\n const { availability, agents, selectedAgentId, onSelectAgent, runs = [], runsGrid, onRefresh, locale } = props;\n const styles = useStyles();\n const selected = agents?.find((a) => a.id === selectedAgentId);\n const caps = availability?.capabilities;\n\n return (\n <div className={styles.root}>\n <AvailabilityBanner availability={availability} onRetry={onRefresh} />\n\n {agents && agents.length > 0 && onSelectAgent ? (\n <div className={styles.section}>\n <AgentPicker agents={agents} selectedId={selectedAgentId} onSelect={onSelectAgent} />\n <div className={styles.head}>\n <ModelBadge provider={selected?.name} model={selected?.model} version={selected?.version} />\n </div>\n </div>\n ) : null}\n\n {caps ? (\n <span className={styles.caps}>\n {/* Capabilities in words: an affordance the provider cannot honour is worse than a\n missing one, so a host can hide the stop button when `cancel` is false. */}\n Supports:{' '}\n {(Object.entries(caps) as [string, boolean][])\n .filter(([, on]) => on)\n .map(([name]) => name)\n .join(', ') || 'nothing reported'}\n </span>\n ) : null}\n\n <div className={styles.section}>\n <Text weight=\"semibold\" size={300}>\n Recent runs\n </Text>\n <RunHistoryPanel runs={runs} grid={runsGrid} locale={locale} />\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Button } from '@fluentui/react-components';\nimport { NavigationRegular } from '@fluentui/react-icons';\nimport { BREAKPOINTS, resolveBreakpoint, useContainerWidth } from '@dataverse-kit/surface-kit/v9';\n\nexport interface AgentAppShellProps {\n /** The left icon rail. Hidden below `sm`. */\n rail?: React.ReactNode;\n /** The conversation list. Collapses to an overlay below `md`. */\n sidebar?: React.ReactNode;\n /** The conversation header, above the main region. */\n header?: React.ReactNode;\n /** The transcript + composer. */\n children?: React.ReactNode;\n /** The detail pane. Hidden below `lg` — the consumer decides what to do with it there. */\n rightPane?: React.ReactNode;\n sidebarWidth?: number;\n /**\n * Drive the layout from a KNOWN width instead of measuring.\n *\n * ★ Mirrors `FormSurface.containerWidth` in surface-kit/v9, and exists for the same reason: a\n * PCF host already knows its `context.allocatedWidth`, so making it wait for a\n * ResizeObserver round-trip is a needless reflow. It is also what makes the collapse\n * TESTABLE — jsdom's ResizeObserver is a stub that never fires, so a measured width stays 0\n * forever and only the roomy branch would ever run.\n */\n containerWidth?: number;\n /** Controlled sidebar visibility on narrow widths. */\n sidebarOpen?: boolean;\n onSidebarOpenChange?: (open: boolean) => void;\n label?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n height: '100%',\n minHeight: 0,\n backgroundColor: tokens.colorNeutralBackground2,\n position: 'relative',\n overflow: 'hidden',\n },\n sidebar: {\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n backgroundColor: tokens.colorNeutralBackground1,\n borderRight: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n // Below `md` the list overlays the conversation instead of shrinking it to nothing.\n sidebarOverlay: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n zIndex: 2,\n boxShadow: tokens.shadow16,\n },\n scrim: { position: 'absolute', inset: '0', zIndex: 1, backgroundColor: tokens.colorBackgroundOverlay },\n main: { flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, minHeight: 0 },\n body: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' },\n toggle: { position: 'absolute', top: tokens.spacingVerticalS, left: tokens.spacingHorizontalS, zIndex: 3 },\n});\n\n/**\n * The Teams-like frame: rail │ list │ conversation │ detail pane.\n *\n * ★★ BOUNDARY WITH surface-kit, in one sentence: **surface-kit owns record/form geometry;\n * agent-kit owns conversation geometry.** `FormSurface`/`Section`/`PivotSurface` are for a\n * Dataverse record; this is for a thread. `MasterDetailSurface` is not this — it is v8-only\n * and two-pane. When surface-kit's deferred v9 composites land, this row is the one to check\n * for overlap.\n *\n * ★★ IT IS NOT A SECOND BREAKPOINT AUTHORITY. The cutoffs come from\n * `@dataverse-kit/surface-kit/v9` (`BREAKPOINTS`, `resolveBreakpoint`), which surface-kit's\n * CLAUDE.md states as an invariant: \"every responsive stacking decision flows through\n * responsive/builders.ts\". Redeclaring 480/768 here is how two files start disagreeing.\n *\n * ★ It measures its CONTAINER, not the viewport (`useContainerWidth`). A PCF control or a\n * custom page occupies a pane, not a window — `context.allocatedWidth`, not `window.innerWidth`\n * — so a viewport media query would collapse the wrong way in the host this kit targets.\n */\nexport function AgentAppShell(props: AgentAppShellProps): React.ReactElement {\n const {\n rail, sidebar, header, children, rightPane,\n sidebarWidth = 280, sidebarOpen, onSidebarOpenChange, label = 'Agent workspace',\n } = props;\n const styles = useStyles();\n\n const [containerRef, measuredWidth] = useContainerWidth<HTMLDivElement>();\n // ★ `useContainerWidth` starts at 0 and stays 0 until a ResizeObserver entry lands — so 0\n // means NOT YET MEASURED, not \"zero pixels wide\". Treating it as a real width would collapse\n // the whole shell on first paint and expand it a frame later, which is a visible jolt.\n // An explicit `containerWidth` wins outright.\n const width = props.containerWidth ?? (measuredWidth > 0 ? measuredWidth : undefined);\n const effective = width ?? BREAKPOINTS.xl;\n const breakpoint = resolveBreakpoint(effective);\n\n const railVisible = effective >= BREAKPOINTS.sm;\n const sidebarInline = effective >= BREAKPOINTS.md;\n const rightPaneVisible = effective >= BREAKPOINTS.lg;\n\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const overlayOpen = sidebarOpen ?? uncontrolledOpen;\n const setOverlayOpen = (open: boolean) => {\n onSidebarOpenChange?.(open);\n if (sidebarOpen === undefined) setUncontrolledOpen(open);\n };\n\n return (\n <div ref={containerRef} className={styles.root} data-breakpoint={breakpoint} aria-label={label}>\n {rail && railVisible ? rail : null}\n\n {sidebar && sidebarInline ? (\n <div className={styles.sidebar} style={{ width: sidebarWidth }}>\n {sidebar}\n </div>\n ) : null}\n\n {sidebar && !sidebarInline && overlayOpen ? (\n <>\n <div\n className={styles.scrim}\n onClick={() => setOverlayOpen(false)}\n // Decorative: Escape and the toggle are the real affordances.\n aria-hidden=\"true\"\n />\n <div className={`${styles.sidebar} ${styles.sidebarOverlay}`} style={{ width: sidebarWidth }}>\n {sidebar}\n </div>\n </>\n ) : null}\n\n <div className={styles.main}>\n {sidebar && !sidebarInline ? (\n <Button\n className={styles.toggle}\n size=\"small\"\n appearance=\"subtle\"\n icon={<NavigationRegular />}\n aria-label={overlayOpen ? 'Hide conversations' : 'Show conversations'}\n aria-expanded={overlayOpen}\n onClick={() => setOverlayOpen(!overlayOpen)}\n />\n ) : null}\n {header}\n <div className={styles.body}>{children}</div>\n </div>\n\n {rightPaneVisible ? rightPane : null}\n </div>\n );\n}\n","import * as React from 'react';\nimport {\n Button, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Tooltip,\n makeStyles, mergeClasses, tokens,\n} from '@fluentui/react-components';\nimport { MoreHorizontalRegular } from '@fluentui/react-icons';\nimport type { RailItem } from './types';\n\nexport interface AppRailProps {\n items: readonly RailItem[];\n selectedId?: string;\n onSelect: (id: string) => void;\n /** Items beyond this many move into the overflow menu. */\n maxVisible?: number;\n label?: string;\n footer?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: tokens.spacingVerticalXS,\n padding: tokens.spacingVerticalS,\n backgroundColor: tokens.colorNeutralBackground3,\n borderRight: `1px solid ${tokens.colorNeutralStroke2}`,\n minHeight: 0,\n },\n spacer: { flex: 1 },\n button: {\n position: 'relative',\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '1px' },\n },\n selected: { backgroundColor: tokens.colorNeutralBackground1Selected },\n badge: {\n position: 'absolute',\n top: '2px',\n right: '2px',\n minWidth: '16px',\n height: '16px',\n padding: '0 3px',\n borderRadius: tokens.borderRadiusCircular,\n backgroundColor: tokens.colorPaletteRedBackground3,\n color: tokens.colorNeutralForegroundOnBrand,\n fontSize: '10px',\n lineHeight: '16px',\n },\n});\n\n/**\n * The left icon rail.\n *\n * ★★ The overflow uses Fluent's real `Menu`, which reaches `useArrowNavigationGroup` → tabster.\n * That is DELIBERATE, per the split-by-cost decision: a menu is a genuine APG widget (focus\n * trap, typeahead, Escape, roving) and hand-rolling it is 100+ LOC, whereas a PCF host closes\n * the tabster gap in one line with `targetDocument`. The coexistence spike (see CLAUDE.md)\n * measured two cores on one window and found no double-handling, so this is safe under\n * isolation. `Menu` is the ONE tabster-touching component in the shell.\n *\n * ★ Each rail button is its own tab stop deliberately: the rail is app-level navigation, not a\n * composite widget, and roving it would hide destinations from a Tab-only user.\n */\nexport function AppRail(props: AppRailProps): React.ReactElement {\n const { items, selectedId, onSelect, maxVisible = 6, label = 'Apps', footer } = props;\n const styles = useStyles();\n\n const visible = items.slice(0, maxVisible);\n const overflow = items.slice(maxVisible);\n\n return (\n <nav className={styles.root} aria-label={label}>\n {visible.map((item) => (\n <Tooltip key={item.id} content={item.label} relationship=\"label\" positioning=\"after\" withArrow>\n <Button\n appearance=\"subtle\"\n icon={item.icon}\n className={mergeClasses(styles.button, item.id === selectedId && styles.selected)}\n aria-pressed={item.id === selectedId}\n aria-label={\n item.badgeCount\n ? `${item.label}, ${item.badgeCount} unread`\n : item.label\n }\n onClick={() => onSelect(item.id)}\n >\n {item.badgeCount ? (\n <span className={styles.badge} aria-hidden=\"true\">\n {item.badgeCount}\n </span>\n ) : null}\n </Button>\n </Tooltip>\n ))}\n\n {overflow.length > 0 ? (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <Button\n appearance=\"subtle\"\n icon={<MoreHorizontalRegular />}\n className={styles.button}\n aria-label={`More apps, ${overflow.length} hidden`}\n />\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {overflow.map((item) => (\n <MenuItem key={item.id} icon={item.icon} onClick={() => onSelect(item.id)}>\n {item.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n ) : null}\n\n <div className={styles.spacer} />\n {footer}\n </nav>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { ConversationSummary } from './types';\nimport { ConversationListItem } from './ConversationListItem';\n\nexport interface ConversationListProps {\n items: readonly ConversationSummary[];\n selectedId?: string;\n onSelect: (id: string) => void;\n label?: string;\n locale?: string;\n empty?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n padding: tokens.spacingHorizontalXS,\n overflowY: 'auto',\n minHeight: 0,\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '-2px' },\n },\n empty: { padding: tokens.spacingVerticalM, color: tokens.colorNeutralForeground3 },\n});\n\n/**\n * The chat list.\n *\n * ★★ A LISTBOX with `aria-activedescendant`, not a stack of buttons and not a `Tree`.\n *\n * A bare button list is not a simpler tree — it is a widget with no collection semantics at\n * all: N tab stops, no selected state, no set size or position, no arrow navigation. A\n * listbox is ONE tab stop, Up/Down/Home/End move an active option, and `aria-selected` says\n * which conversation is open.\n *\n * `Tree` would be right if this nested (teams → channels); it does not — see ./types.ts,\n * where that decision is written down.\n *\n * ★ Modelled on the estate's existing activedescendant listbox\n * (`shared/pcf-gallery/controls/choice-grid/.../ChoiceGridApp.tsx`), including the detail that\n * `scrollIntoView` is guarded on the METHOD (`?.()`), not just the element: it is not\n * implemented everywhere a React tree runs, and an unguarded call inside an effect does not\n * degrade — it throws, React unmounts, and the list renders nothing.\n */\nexport function ConversationList(props: ConversationListProps): React.ReactElement {\n const { items, selectedId, onSelect, label = 'Conversations', locale, empty } = props;\n const styles = useStyles();\n const listRef = React.useRef<HTMLDivElement>(null);\n const idBase = React.useId();\n\n const selectedIndex = Math.max(0, items.findIndex((i) => i.id === selectedId));\n const [active, setActive] = React.useState(selectedIndex);\n\n // Follow an externally-driven selection, and never point past the end if the list shrinks.\n React.useEffect(() => {\n setActive((current) => {\n if (items.length === 0) return 0;\n if (selectedIndex >= 0 && items[selectedIndex]) return selectedIndex;\n return Math.min(current, items.length - 1);\n });\n }, [selectedIndex, items]);\n\n const optionId = (index: number) => `${idBase}-opt-${index}`;\n\n React.useEffect(() => {\n // ★ getElementById, not querySelector('#id'): React useId values contain colons, and jsdom\n // does not expose CSS.escape to sanitise them.\n // ★★ The optional call is on the METHOD. `scrollIntoView` is not implemented everywhere a\n // React tree runs — jsdom being the obvious case — and an unguarded call inside an effect\n // does not degrade: it THROWS, React unmounts, and the list renders nothing at all. A\n // cosmetic nicety must never be able to take the shell down.\n const el = listRef.current?.ownerDocument.getElementById(optionId(active));\n el?.scrollIntoView?.({ block: 'nearest' });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [active, idBase]);\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n const last = items.length - 1;\n if (last < 0) return;\n let next: number | null = null;\n if (event.key === 'ArrowDown') next = Math.min(last, active + 1);\n else if (event.key === 'ArrowUp') next = Math.max(0, active - 1);\n else if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = last;\n else if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n const picked = items[active];\n // The list can shrink while focus is held; checking the ENTRY rather than defaulting the\n // id makes that a no-op instead of selecting something wrong.\n if (picked) onSelect(picked.id);\n return;\n }\n if (next === null) return;\n event.preventDefault();\n setActive(next);\n };\n\n if (items.length === 0) {\n return (\n <div className={styles.root}>\n {empty ?? (\n <Text className={styles.empty} size={200}>\n No conversations yet.\n </Text>\n )}\n </div>\n );\n }\n\n return (\n <div\n ref={listRef}\n className={styles.root}\n role=\"listbox\"\n aria-label={label}\n // ONE tab stop for the whole list.\n tabIndex={0}\n aria-activedescendant={optionId(active)}\n onKeyDown={onKeyDown}\n >\n {items.map((summary, index) => (\n <ConversationListItem\n key={summary.id}\n id={optionId(index)}\n summary={summary}\n selected={summary.id === selectedId}\n active={index === active}\n locale={locale}\n onSelect={onSelect}\n />\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { ConversationSummary } from './types';\nimport { AgentAvatar } from './AgentAvatar';\n\nexport interface ConversationListItemProps {\n summary: ConversationSummary;\n selected: boolean;\n active: boolean;\n id: string;\n locale?: string;\n onSelect: (id: string) => void;\n}\n\nconst useStyles = makeStyles({\n row: {\n display: 'flex',\n gap: tokens.spacingHorizontalS,\n alignItems: 'center',\n padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalS}`,\n borderRadius: tokens.borderRadiusMedium,\n cursor: 'pointer',\n ':hover': { backgroundColor: tokens.colorNeutralBackground1Hover },\n },\n // ★ The ACTIVE row (aria-activedescendant target) gets a visible focus indicator, because\n // real DOM focus stays on the listbox — without this the keyboard user sees nothing move.\n active: { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '-2px' },\n selected: { backgroundColor: tokens.colorNeutralBackground1Selected },\n body: { flex: 1, minWidth: 0 },\n title: {\n display: 'block',\n fontSize: tokens.fontSizeBase300,\n fontWeight: tokens.fontWeightSemibold,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n muted: { fontWeight: tokens.fontWeightRegular, color: tokens.colorNeutralForeground3 },\n preview: {\n display: 'block',\n fontSize: tokens.fontSizeBase200,\n color: tokens.colorNeutralForeground3,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n meta: { display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: '2px' },\n time: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n unread: {\n minWidth: '18px',\n height: '18px',\n padding: `0 ${tokens.spacingHorizontalXXS}`,\n borderRadius: tokens.borderRadiusCircular,\n backgroundColor: tokens.colorBrandBackground,\n color: tokens.colorNeutralForegroundOnBrand,\n fontSize: tokens.fontSizeBase100,\n lineHeight: '18px',\n textAlign: 'center',\n },\n});\n\n/**\n * Build the row's accessible name.\n *\n * ★★ Unread count and presence go in the NAME, not only in a badge and a colour dot. A screen\n * reader hearing \"Contoso\" forty times learns nothing about which conversations are waiting,\n * and a colour-only unread indicator is a WCAG 1.4.1 failure. Exported so it can be asserted\n * directly rather than inferred from rendered markup.\n */\nexport function conversationAccessibleName(\n summary: ConversationSummary,\n locale?: string,\n): string {\n const parts = [summary.title];\n if (summary.presence && summary.presence !== 'unknown') parts.push(summary.presence);\n if (!summary.muted && summary.unreadCount) {\n parts.push(`${summary.unreadCount} unread`);\n }\n if (summary.muted) parts.push('muted');\n if (summary.timestamp) {\n parts.push(new Intl.DateTimeFormat(locale, { timeStyle: 'short' }).format(new Date(summary.timestamp)));\n }\n return parts.join(', ');\n}\n\nexport function ConversationListItem(props: ConversationListItemProps): React.ReactElement {\n const { summary, selected, active, id, locale, onSelect } = props;\n const styles = useStyles();\n const time = summary.timestamp\n ? new Intl.DateTimeFormat(locale, { timeStyle: 'short' }).format(new Date(summary.timestamp))\n : undefined;\n\n return (\n <div\n id={id}\n role=\"option\"\n aria-selected={selected}\n aria-label={conversationAccessibleName(summary, locale)}\n className={mergeClasses(styles.row, selected && styles.selected, active && styles.active)}\n onClick={() => onSelect(summary.id)}\n data-conversation-option\n >\n <AgentAvatar participant={summary.participant} presence={summary.presence} size={32} />\n {/* The visible text is aria-hidden: the row's own aria-label is the accessible name, and\n without this a screen reader reads the title twice. */}\n <div className={styles.body} aria-hidden=\"true\">\n <span className={mergeClasses(styles.title, summary.muted && styles.muted)}>{summary.title}</span>\n {summary.preview ? <span className={styles.preview}>{summary.preview}</span> : null}\n </div>\n <div className={styles.meta} aria-hidden=\"true\">\n {time ? <span className={styles.time}>{time}</span> : null}\n {!summary.muted && summary.unreadCount ? (\n <span className={styles.unread}>{summary.unreadCount}</span>\n ) : null}\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { Avatar, type PresenceBadgeStatus } from '@fluentui/react-components';\nimport type { AgentParticipant } from '../core';\nimport type { PresenceState } from './types';\n\nexport interface AgentAvatarProps {\n participant?: AgentParticipant;\n presence?: PresenceState;\n size?: 24 | 28 | 32 | 36 | 40 | 48;\n name?: string;\n}\n\nconst STATUS: Record<PresenceState, PresenceBadgeStatus | undefined> = {\n available: 'available',\n busy: 'busy',\n away: 'away',\n offline: 'offline',\n dnd: 'do-not-disturb',\n unknown: 'unknown',\n};\n\n/**\n * ★ `Avatar` and `PresenceBadge` are measured tabster-safe (`react-avatar` imports only\n * `createCustomFocusIndicatorStyle`; `react-badge` has no tabster dependency at all), so\n * these are Fluent's rather than in-tree.\n *\n * ★ `AvatarGroup` is NOT — it pulls `react-popover`, which reaches `useModalAttributes`. If a\n * facepile is ever wanted, that is the component to check first.\n */\nexport function AgentAvatar({ participant, presence, size = 32, name }: AgentAvatarProps): React.ReactElement {\n const displayName = name ?? participant?.displayName ?? 'Unknown';\n return (\n <Avatar\n name={displayName}\n initials={participant?.initials}\n image={participant?.imageUrl ? { src: participant.imageUrl } : undefined}\n size={size}\n badge={presence ? { status: STATUS[presence] ?? 'unknown' } : undefined}\n // The badge is decorative here: presence is carried in the ROW's accessible name, so a\n // screen reader does not hear it twice.\n aria-hidden={undefined}\n />\n );\n}\n","import * as React from 'react';\nimport {\n Button, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Tab, TabList, Text,\n makeStyles, tokens,\n} from '@fluentui/react-components';\nimport { MoreHorizontalRegular } from '@fluentui/react-icons';\nimport type { AgentParticipant } from '../core';\nimport type { PresenceState } from './types';\nimport { AgentAvatar } from './AgentAvatar';\n\nexport interface ConversationTab {\n id: string;\n label: string;\n}\n\nexport interface HeaderAction {\n key: string;\n label: string;\n icon?: React.ReactElement;\n onClick: () => void;\n}\n\nexport interface ConversationHeaderProps {\n title: string;\n subtitle?: string;\n participant?: AgentParticipant;\n presence?: PresenceState;\n tabs?: readonly ConversationTab[];\n selectedTabId?: string;\n onTabSelect?: (id: string) => void;\n actions?: readonly HeaderAction[];\n /** Rendered right of the tabs — a search box, a right-pane toggle. */\n trailing?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: tokens.spacingVerticalXS,\n padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalM} 0`,\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n },\n top: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS },\n identity: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, minWidth: 0 },\n titles: { display: 'flex', flexDirection: 'column', minWidth: 0 },\n subtitle: { color: tokens.colorNeutralForeground3, fontSize: tokens.fontSizeBase200 },\n spacer: { flex: 1 },\n tabRow: { display: 'flex', alignItems: 'flex-end', gap: tokens.spacingHorizontalS },\n});\n\n/**\n * The bar above the transcript: who you are talking to, the tab strip, and the actions.\n *\n * ★★ The tab strip is Fluent's real `TabList`, and that is DELIBERATE. `react-tabs` reaches\n * `useArrowNavigationGroup` → `getMover` → tabster, but rebuilding it by hand is not the\n * \"simple horizontal list\" it looks like: tabster's Mover carries RTL inversion,\n * Home/End/PageUp/PageDown, cyclic wrap, disabled-item skipping, and a caret-position guard\n * that declines arrow keys while the caret is inside a text input — roughly 120-180 LOC to\n * reproduce, against a widget nobody has tested. Per the split-by-cost decision the kit uses\n * Fluent's and the PCF host supplies an isolated `targetDocument`; the coexistence spike\n * measured that two tabster cores share a window without double-handling.\n *\n * ★ Manual activation (Fluent's default, `selectTabOnFocus` off): arrowing through the tabs must\n * not fire N conversation loads on the way past.\n *\n * ★ `aria-controls` is NOT set here. The panel these tabs govern is rendered by the consumer,\n * elsewhere in the tree, so the id contract would have to cross components — and an\n * `aria-controls` pointing at nothing is worse than none. Pass `panelId` when that contract\n * exists; until then the relationship is left unstated rather than stated falsely.\n */\nexport function ConversationHeader(props: ConversationHeaderProps): React.ReactElement {\n const {\n title, subtitle, participant, presence, tabs, selectedTabId, onTabSelect, actions, trailing,\n } = props;\n const styles = useStyles();\n\n const inline = (actions ?? []).slice(0, 2);\n const overflow = (actions ?? []).slice(2);\n\n return (\n <header className={styles.root}>\n <div className={styles.top}>\n <div className={styles.identity}>\n <AgentAvatar participant={participant} presence={presence} size={32} name={title} />\n <div className={styles.titles}>\n <Text weight=\"semibold\" truncate wrap={false}>\n {title}\n </Text>\n {subtitle ? <span className={styles.subtitle}>{subtitle}</span> : null}\n </div>\n </div>\n\n <div className={styles.spacer} />\n {trailing}\n\n {inline.map((action) => (\n <Button\n key={action.key}\n appearance=\"subtle\"\n size=\"small\"\n icon={action.icon}\n aria-label={action.label}\n onClick={action.onClick}\n />\n ))}\n\n {overflow.length > 0 ? (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<MoreHorizontalRegular />}\n aria-label={`More actions, ${overflow.length} available`}\n />\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {overflow.map((action) => (\n <MenuItem key={action.key} icon={action.icon} onClick={action.onClick}>\n {action.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n ) : null}\n </div>\n\n {tabs && tabs.length > 0 ? (\n <div className={styles.tabRow}>\n <TabList\n selectedValue={selectedTabId}\n onTabSelect={(_, data) => onTabSelect?.(data.value as string)}\n size=\"small\"\n >\n {tabs.map((tab) => (\n <Tab key={tab.id} value={tab.id}>\n {tab.label}\n </Tab>\n ))}\n </TabList>\n </div>\n ) : null}\n </header>\n );\n}\n","import * as React from 'react';\nimport { Button, makeStyles, tokens, Text } from '@fluentui/react-components';\nimport { DismissRegular } from '@fluentui/react-icons';\n\nexport interface RightPaneProps {\n open: boolean;\n title: string;\n onClose: () => void;\n children?: React.ReactNode;\n width?: number;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n borderLeft: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n minHeight: 0,\n },\n head: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: tokens.spacingHorizontalS,\n padding: tokens.spacingVerticalS,\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n body: { flex: 1, overflowY: 'auto', padding: tokens.spacingVerticalM },\n});\n\n/**\n * The detail pane beside the conversation — sources, a record, a trace.\n *\n * ★ A plain `<aside>`, NOT Fluent's `Drawer`. `react-drawer` composes dialog internals, and an\n * inline pane needs none of a drawer's modality: it sits in the layout rather than over it.\n */\nexport function RightPane({ open, title, onClose, children, width = 320 }: RightPaneProps): React.ReactElement | null {\n const styles = useStyles();\n const labelId = React.useId();\n if (!open) return null;\n\n return (\n <aside className={styles.root} style={{ width }} aria-labelledby={labelId}>\n <div className={styles.head}>\n <Text id={labelId} weight=\"semibold\">\n {title}\n </Text>\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<DismissRegular />}\n onClick={onClose}\n aria-label={`Close ${title}`}\n />\n </div>\n <div className={styles.body}>{children}</div>\n </aside>\n );\n}\n","import * as React from 'react';\nimport { SearchBox, makeStyles } from '@fluentui/react-components';\n\nexport interface GlobalSearchBarProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n placeholder?: string;\n}\n\nconst useStyles = makeStyles({\n root: { width: '100%', maxWidth: '640px' },\n});\n\n/** ★ `SearchBox` is `react-search`, which has no tabster dependency — safe. */\nexport function GlobalSearchBar({\n value,\n onChange,\n onSubmit,\n placeholder = 'Search conversations',\n}: GlobalSearchBarProps): React.ReactElement {\n const styles = useStyles();\n return (\n <SearchBox\n className={styles.root}\n value={value}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(_, data) => onChange(data.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && onSubmit) onSubmit(value);\n }}\n />\n );\n}\n","import * as React from 'react';\nimport { Tooltip, makeStyles, tokens } from '@fluentui/react-components';\nimport type { AgentSource } from '../core';\n\nexport interface CitationChipProps {\n marker: string;\n source?: AgentSource;\n onOpen?: (source: AgentSource) => void;\n}\n\nconst useStyles = makeStyles({\n chip: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: '18px',\n height: '18px',\n padding: `0 ${tokens.spacingHorizontalXXS}`,\n marginLeft: '2px',\n verticalAlign: 'super',\n fontSize: tokens.fontSizeBase100,\n lineHeight: '18px',\n borderRadius: tokens.borderRadiusSmall,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground3,\n color: tokens.colorNeutralForeground2,\n cursor: 'pointer',\n ':hover': { backgroundColor: tokens.colorNeutralBackground3Hover },\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '1px' },\n },\n inert: { cursor: 'default' },\n});\n\n/** An inline `[1]`. ★ `Tooltip` is measured tabster-safe (`react-tooltip` imports only\n * `useIsNavigatingWithKeyboard`), so this one is Fluent's rather than in-tree. */\nexport function CitationChip({ marker, source, onOpen }: CitationChipProps): React.ReactElement {\n const styles = useStyles();\n const label = source ? `Source ${marker}: ${source.title}` : `Source ${marker}`;\n\n if (!source || !onOpen) {\n return (\n <span className={`${styles.chip} ${styles.inert}`} aria-label={label}>\n {marker}\n </span>\n );\n }\n return (\n <Tooltip content={source.title} relationship=\"description\" withArrow>\n <button type=\"button\" className={styles.chip} aria-label={label} onClick={() => onOpen(source)}>\n {marker}\n </button>\n </Tooltip>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport { renumberCitations, type AgentSource } from '../core';\nimport { Disclosure } from '../internal';\nimport { SourceCard } from './SourceCard';\n\nexport interface CitationListProps {\n /** The answer text — used to work out which sources were actually cited. */\n text: string;\n sources: readonly AgentSource[];\n onOpenSource?: (source: AgentSource) => void;\n defaultOpen?: boolean;\n}\n\nconst useStyles = makeStyles({\n list: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS, listStyle: 'none', margin: 0, padding: 0 },\n});\n\n/**\n * The sources under an answer.\n *\n * ★★ IT SHOWS ONLY THE SOURCES THE TEXT ACTUALLY CITES. A retriever commonly returns a dozen\n * chunks for a two-citation answer, and listing all twelve implies the answer rests on\n * twelve things when it rests on two. That overstated provenance is what makes a citation\n * panel decorative instead of trustworthy, so `renumberCitations` drops the uncited ones\n * and renumbers what remains into first-appearance order.\n *\n * ★ A Disclosure, not Fluent's `Accordion`: APG's disclosure pattern is `<button aria-expanded\n * aria-controls>` and a labelled region, and `Accordion` reaches `useArrowNavigationGroup`\n * to add arrow-key movement between headers that a single source list does not need.\n */\nexport function CitationList({\n text,\n sources,\n onOpenSource,\n defaultOpen = false,\n}: CitationListProps): React.ReactElement | null {\n const styles = useStyles();\n const id = React.useId();\n const { used, citations } = React.useMemo(() => renumberCitations(text, sources), [text, sources]);\n\n if (used.length === 0) return null;\n\n const markerFor = (sourceId: string) => citations.find((c) => c.sourceId === sourceId)?.marker;\n\n return (\n <Disclosure\n id={id}\n defaultOpen={defaultOpen}\n summary={`${used.length} source${used.length === 1 ? '' : 's'}`}\n >\n <ul className={styles.list}>\n {used.map((source) => (\n <li key={source.id}>\n <SourceCard source={source} marker={markerFor(source.id)} onOpen={onOpenSource} />\n </li>\n ))}\n </ul>\n </Disclosure>\n );\n}\n","import * as React from 'react';\nimport { Button, Text, makeStyles, tokens } from '@fluentui/react-components';\nimport {\n DocumentRegular, DatabaseRegular, GlobeRegular, BookRegular, DocumentBulletListRegular,\n} from '@fluentui/react-icons';\nimport type { AgentSource } from '../core';\nimport { CardSurface } from '../internal';\n\nexport interface SourceCardProps {\n source: AgentSource;\n /** The marker this source was cited as, if any. */\n marker?: string;\n onOpen?: (source: AgentSource) => void;\n showSnippet?: boolean;\n}\n\nconst ICONS = {\n dataverse: DatabaseRegular,\n document: DocumentRegular,\n web: GlobeRegular,\n knowledge: BookRegular,\n other: DocumentBulletListRegular,\n} as const;\n\nconst useStyles = makeStyles({\n root: { gap: tokens.spacingVerticalXXS },\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS },\n marker: { color: tokens.colorNeutralForeground3, fontSize: tokens.fontSizeBase200 },\n snippet: { color: tokens.colorNeutralForeground2, fontSize: tokens.fontSizeBase200 },\n meta: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, marginTop: tokens.spacingVerticalXXS },\n});\n\nexport function SourceCard({ source, marker, onOpen, showSnippet = true }: SourceCardProps): React.ReactElement {\n const styles = useStyles();\n const Icon = ICONS[source.kind] ?? ICONS.other;\n\n return (\n <CardSurface className={styles.root}>\n <div className={styles.head}>\n <Icon aria-hidden=\"true\" />\n {marker ? <span className={styles.marker}>[{marker}]</span> : null}\n <Text weight=\"semibold\">{source.title}</Text>\n </div>\n {showSnippet && source.snippet ? <span className={styles.snippet}>{source.snippet}</span> : null}\n <div className={styles.meta}>\n {/* ★ The kit never calls Xrm. It raises a callback and the HOST navigates. */}\n {onOpen && (source.recordId || source.url) ? (\n <Button size=\"small\" appearance=\"subtle\" onClick={() => onOpen(source)}>\n {source.recordId ? 'Open record' : 'Open'}\n </Button>\n ) : null}\n {/* ★ \"not reported\" is shown as such, never as zero confidence — a retriever that\n returns no score and one that returns 0 mean completely different things. */}\n <span className={styles.snippet}>\n {source.score === undefined ? 'Relevance not reported' : `Relevance ${Math.round(source.score * 100)}%`}\n </span>\n </div>\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { makeStyles } from '@fluentui/react-components';\nimport { splitTextByCitations, type AgentCitation, type AgentSource } from '../core';\nimport { CitationChip } from './CitationChip';\n\nexport interface AnswerWithCitationsProps {\n text: string;\n citations?: readonly AgentCitation[];\n sources?: readonly AgentSource[];\n onOpenSource?: (source: AgentSource) => void;\n}\n\nconst useStyles = makeStyles({ root: { whiteSpace: 'pre-wrap', wordBreak: 'break-word' } });\n\n/** Renders the answer with a chip where each marker was. */\nexport function AnswerWithCitations({\n text,\n citations = [],\n sources = [],\n onOpenSource,\n}: AnswerWithCitationsProps): React.ReactElement {\n const styles = useStyles();\n const segments = React.useMemo(() => splitTextByCitations(text, citations), [text, citations]);\n const byId = React.useMemo(() => new Map(sources.map((s) => [s.id, s])), [sources]);\n\n return (\n <span className={styles.root}>\n {segments.map((segment, i) =>\n segment.kind === 'text' ? (\n <React.Fragment key={i}>{segment.text}</React.Fragment>\n ) : (\n <CitationChip\n key={i}\n marker={segment.marker ?? ''}\n source={segment.sourceId ? byId.get(segment.sourceId) : undefined}\n onOpen={onOpenSource}\n />\n ),\n )}\n </span>\n );\n}\n","import * as React from 'react';\nimport { Text, makeStyles, tokens } from '@fluentui/react-components';\nimport { Disclosure } from '../internal';\n\nexport interface GroundingPanelProps {\n /** The SAME object passed as `AgentTurn.grounding`. */\n grounding?: Record<string, unknown>;\n title?: string;\n defaultOpen?: boolean;\n}\n\nconst useStyles = makeStyles({\n grid: {\n display: 'grid',\n gridTemplateColumns: 'minmax(96px, max-content) 1fr',\n gap: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalM}`,\n margin: 0,\n fontSize: tokens.fontSizeBase200,\n },\n key: { color: tokens.colorNeutralForeground3, margin: 0 },\n value: { margin: 0, wordBreak: 'break-word', fontFamily: tokens.fontFamilyMonospace },\n empty: { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 },\n});\n\nfunction render(value: unknown): string {\n if (value === null || value === undefined) return '—';\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * What the model was told.\n *\n * ★★ It renders the SAME object the turn carried (`AgentTurn.grounding`), which is the point:\n * the facts the host computed deterministically and the facts shown on screen cannot drift\n * apart, because there is only one of them. The model EXPLAINS these; it must never be the\n * thing that derives them — a hallucinated identifier is worse than no answer.\n *\n * ★ A definition list on a CSS grid, not a `Table`: `react-table` reaches\n * `useArrowNavigationGroup`, and key/value pairs are not tabular data.\n */\nexport function GroundingPanel({\n grounding,\n title = 'What this answer used',\n defaultOpen = false,\n}: GroundingPanelProps): React.ReactElement | null {\n const styles = useStyles();\n const id = React.useId();\n const entries = Object.entries(grounding ?? {});\n if (entries.length === 0) return null;\n\n return (\n <Disclosure id={id} defaultOpen={defaultOpen} summary={title}>\n <dl className={styles.grid}>\n {entries.map(([key, value]) => (\n <React.Fragment key={key}>\n <dt className={styles.key}>{key}</dt>\n <dd className={styles.value}>{render(value)}</dd>\n </React.Fragment>\n ))}\n </dl>\n <Text as=\"p\" className={styles.empty}>\n These facts were supplied by the app, not produced by the model.\n </Text>\n </Disclosure>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport { ShieldErrorRegular } from '@fluentui/react-icons';\nimport type { AgentMessage } from '../core';\n\nexport interface ProviderAttributionProps {\n provider?: string;\n model?: string;\n guarded?: boolean;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalXXS,\n fontSize: tokens.fontSizeBase100,\n color: tokens.colorNeutralForeground3,\n },\n guarded: { color: tokens.colorPaletteDarkOrangeForeground1 },\n});\n\n/**\n * Who produced this answer.\n *\n * ★★ WHEN `guarded` IS SET THE VISIBLE TEXT MUST CHANGE, and that is the whole contract.\n * `guarded` means the provider WITHHELD its generated answer and substituted safe text.\n * Attributing that substitute to the model as if it were the model's words is the\n * misattribution this component exists to prevent — so the difference is in words a reader\n * sees, not a colour, an icon or a `data-` attribute. The gate asserts BOTH directions.\n */\nexport function ProviderAttribution({ provider, model, guarded }: ProviderAttributionProps): React.ReactElement | null {\n const styles = useStyles();\n if (!provider && !model && !guarded) return null;\n\n const who = [provider, model].filter(Boolean).join(' · ');\n\n if (guarded) {\n return (\n <span className={`${styles.root} ${styles.guarded}`}>\n <ShieldErrorRegular aria-hidden=\"true\" />\n Withheld and replaced with safe text{who ? ` — not ${who}'s words` : ''}\n </span>\n );\n }\n return <span className={styles.root}>Answered by {who || 'the agent'}</span>;\n}\n\n/** Convenience: read the attribution straight off a message. */\nexport function messageAttribution(message: AgentMessage): ProviderAttributionProps {\n return { provider: message.provider, model: message.usage?.model, guarded: message.guarded };\n}\n","import * as React from 'react';\nimport { Text, makeStyles, tokens } from '@fluentui/react-components';\nimport { CardSurface } from '../internal';\n\nexport interface ActionCardProps {\n title: string;\n description?: React.ReactNode;\n icon?: React.ReactElement;\n /** Renders an emphasised edge while a decision is outstanding. */\n pending?: boolean;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS },\n description: { color: tokens.colorNeutralForeground2, fontSize: tokens.fontSizeBase200 },\n footer: { display: 'flex', gap: tokens.spacingHorizontalS, justifyContent: 'flex-end', marginTop: tokens.spacingVerticalXS },\n});\n\n/** The container the action family shares. ★ Built on the in-tree `CardSurface`, never Fluent's\n * `Card` — see internal/CardSurface.tsx for why that one unmounts the tree on a form. */\nexport function ActionCard({ title, description, icon, pending, children, footer }: ActionCardProps): React.ReactElement {\n const styles = useStyles();\n return (\n <CardSurface emphasis={pending ? 'attention' : 'none'}>\n <div className={styles.head}>\n {icon ? React.cloneElement(icon, { 'aria-hidden': 'true' } as Record<string, unknown>) : null}\n <Text weight=\"semibold\">{title}</Text>\n </div>\n {description ? <span className={styles.description}>{description}</span> : null}\n {children}\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { Button, Spinner, makeStyles, tokens } from '@fluentui/react-components';\nimport { CheckmarkRegular, DismissRegular, EditRegular } from '@fluentui/react-icons';\nimport type { AgentToolCall } from '../core';\nimport { ActionCard } from './ActionCard';\nimport { ParameterReview } from './ParameterReview';\nimport { ActionResult } from './ActionResult';\n\nexport interface ApprovalCardProps {\n toolCall: AgentToolCall;\n onApprove: (call: AgentToolCall, argumentsJson: string) => void;\n onDeny: (call: AgentToolCall) => void;\n /** Enables in-place editing of the proposed arguments before approval. */\n allowEdit?: boolean;\n busy?: boolean;\n}\n\nconst useStyles = makeStyles({\n busy: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS, fontSize: tokens.fontSizeBase200 },\n});\n\n/**\n * A tool call awaiting a human decision.\n *\n * ★★ THE KIT DOES NOT RUN THE TOOL. It renders the request and raises a callback; the HOST\n * executes and feeds the outcome back as a `tool_result` event. That is what keeps \"the kit\n * has no tools\" a structural statement about this package rather than a promise about a\n * prompt — `IAgentService` has no method that could invoke one.\n *\n * ★★ IT CANNOT DOUBLE-SUBMIT, and that is asserted two ways, because counting the callback\n * alone is a one-field signature: it shows what the component SENT, and a card that\n * re-enables after an async settle would still submit twice later. The gate asserts one\n * `onApprove` across two synchronous clicks AND that the control is disabled afterwards.\n */\nexport function ApprovalCard({\n toolCall, onApprove, onDeny, allowEdit = false, busy = false,\n}: ApprovalCardProps): React.ReactElement {\n const styles = useStyles();\n const [args, setArgs] = React.useState(toolCall.argumentsJson);\n const [editing, setEditing] = React.useState(false);\n // Latched locally: the decision is final from this card's point of view the moment it is\n // made, regardless of how long the host takes to report a status back.\n const [decided, setDecided] = React.useState(false);\n\n const settled =\n toolCall.status === 'succeeded' || toolCall.status === 'failed' || toolCall.status === 'denied';\n\n if (settled) {\n return (\n <ActionCard title={toolCall.name} description=\"Tool call\">\n <ParameterReview argumentsJson={toolCall.argumentsJson} />\n <ActionResult\n status={toolCall.status === 'succeeded' ? 'succeeded' : toolCall.status === 'denied' ? 'denied' : 'failed'}\n message={toolCall.resultText ?? toolCall.failure?.message ?? 'Completed.'}\n correlationId={toolCall.failure?.correlationId}\n />\n </ActionCard>\n );\n }\n\n const locked = decided || busy || toolCall.status === 'running';\n\n const approve = () => {\n if (locked) return;\n setDecided(true);\n onApprove(toolCall, args);\n };\n const deny = () => {\n if (locked) return;\n setDecided(true);\n onDeny(toolCall);\n };\n\n return (\n <ActionCard\n title={toolCall.name}\n description=\"The agent is asking to run this. Check the details before approving.\"\n pending={!locked}\n footer={\n locked ? (\n <span className={styles.busy}>\n <Spinner size=\"tiny\" /> Submitting…\n </span>\n ) : (\n <>\n {allowEdit ? (\n <Button size=\"small\" icon={<EditRegular />} onClick={() => setEditing((v) => !v)}>\n {editing ? 'Done editing' : 'Edit'}\n </Button>\n ) : null}\n <Button size=\"small\" icon={<DismissRegular />} onClick={deny} disabled={locked}>\n Deny\n </Button>\n <Button size=\"small\" appearance=\"primary\" icon={<CheckmarkRegular />} onClick={approve} disabled={locked}>\n Approve\n </Button>\n </>\n )\n }\n >\n <ParameterReview argumentsJson={args} readOnly={!editing} onChange={setArgs} />\n </ActionCard>\n );\n}\n","import * as React from 'react';\nimport { Input, makeStyles, tokens, Text } from '@fluentui/react-components';\n\nexport interface ParameterReviewProps {\n /** RAW arguments as the model emitted them. */\n argumentsJson: string;\n readOnly?: boolean;\n onChange?: (next: string) => void;\n}\n\nconst useStyles = makeStyles({\n grid: {\n display: 'grid',\n gridTemplateColumns: 'minmax(110px, max-content) 1fr',\n gap: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalM}`,\n alignItems: 'center',\n margin: 0,\n },\n key: { margin: 0, color: tokens.colorNeutralForeground2, fontSize: tokens.fontSizeBase200 },\n value: { margin: 0 },\n raw: {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n fontFamily: tokens.fontFamilyMonospace,\n fontSize: tokens.fontSizeBase200,\n color: tokens.colorNeutralForeground2,\n },\n});\n\n/**\n * The arguments a tool call is proposing, laid out for a human to check before approving.\n *\n * ★ A definition list on a CSS grid, NOT a `Table`/`DataGrid` — both reach\n * `useArrowNavigationGroup`, and this is key/value data rather than a grid.\n *\n * ★★ It falls back to showing the RAW string when the JSON does not parse, and that matters:\n * a half-streamed arguments blob is not valid JSON, and an approval UI that silently\n * rendered nothing would ask the user to approve something they cannot see. Showing the raw\n * text is honest; showing an empty table is not.\n */\nexport function ParameterReview({ argumentsJson, readOnly = true, onChange }: ParameterReviewProps): React.ReactElement {\n const styles = useStyles();\n\n const parsed = React.useMemo<Record<string, unknown> | null>(() => {\n try {\n const value: unknown = JSON.parse(argumentsJson);\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n }, [argumentsJson]);\n\n if (!parsed) {\n return (\n <div>\n <Text size={200}>Arguments (unparsed)</Text>\n <pre className={styles.raw}>{argumentsJson || '(empty)'}</pre>\n </div>\n );\n }\n\n const set = (key: string, next: string) => {\n if (!onChange) return;\n onChange(JSON.stringify({ ...parsed, [key]: next }));\n };\n\n return (\n <dl className={styles.grid}>\n {Object.entries(parsed).map(([key, value]) => (\n <React.Fragment key={key}>\n <dt className={styles.key}>{key}</dt>\n <dd className={styles.value}>\n {readOnly ? (\n <span className={styles.raw}>{typeof value === 'string' ? value : JSON.stringify(value)}</span>\n ) : (\n <Input\n size=\"small\"\n aria-label={key}\n value={typeof value === 'string' ? value : JSON.stringify(value)}\n onChange={(_, data) => set(key, data.value)}\n />\n )}\n </dd>\n </React.Fragment>\n ))}\n </dl>\n );\n}\n","import * as React from 'react';\nimport { MessageBar, MessageBarBody, MessageBarTitle, MessageBarActions, Button, makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface ActionResultProps {\n status: 'succeeded' | 'failed' | 'denied';\n message: string;\n correlationId?: string;\n onRetry?: () => void;\n}\n\nconst INTENT = { succeeded: 'success', failed: 'error', denied: 'warning' } as const;\nconst TITLE = { succeeded: 'Done', failed: 'Failed', denied: 'Not approved' } as const;\n\nconst useStyles = makeStyles({\n id: { display: 'block', marginTop: tokens.spacingVerticalXXS, fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3, fontFamily: tokens.fontFamilyMonospace },\n});\n\n/** ★ The correlation id is surfaced, not hidden: it is the only thing that lets someone paged\n * at 3am find this specific run in App Insights. */\nexport function ActionResult({ status, message, correlationId, onRetry }: ActionResultProps): React.ReactElement {\n const styles = useStyles();\n return (\n <MessageBar intent={INTENT[status]}>\n <MessageBarBody>\n <MessageBarTitle>{TITLE[status]}</MessageBarTitle>\n {message}\n {correlationId ? <span className={styles.id}>Correlation id: {correlationId}</span> : null}\n </MessageBarBody>\n {status === 'failed' && onRetry ? (\n <MessageBarActions>\n <Button size=\"small\" onClick={onRetry}>Try again</Button>\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { Badge, Spinner, makeStyles, tokens } from '@fluentui/react-components';\nimport type { AgentToolCall, ToolCallStatus } from '../core';\nimport { Disclosure, CardSurface } from '../internal';\nimport { ParameterReview } from './ParameterReview';\n\nexport interface ToolCallCardProps {\n toolCall: AgentToolCall;\n defaultExpanded?: boolean;\n}\n\nconst LABEL: Record<ToolCallStatus, string> = {\n proposed: 'Proposed',\n running: 'Running',\n succeeded: 'Succeeded',\n failed: 'Failed',\n denied: 'Denied',\n};\nconst COLOUR: Record<ToolCallStatus, 'informative' | 'success' | 'danger' | 'warning'> = {\n proposed: 'informative',\n running: 'informative',\n succeeded: 'success',\n failed: 'danger',\n denied: 'warning',\n};\n\nconst useStyles = makeStyles({\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS },\n name: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase200 },\n result: {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n fontFamily: tokens.fontFamilyMonospace,\n fontSize: tokens.fontSizeBase200,\n marginTop: tokens.spacingVerticalXS,\n },\n});\n\n/** A tool call that needed no approval — collapsed by default, expandable for the arguments.\n * ★ A Disclosure rather than `Accordion`: see internal/Disclosure.tsx. */\nexport function ToolCallCard({ toolCall, defaultExpanded = false }: ToolCallCardProps): React.ReactElement {\n const styles = useStyles();\n const id = React.useId();\n\n return (\n <CardSurface>\n <Disclosure\n id={id}\n defaultOpen={defaultExpanded}\n summary={\n <span className={styles.head}>\n <span className={styles.name}>{toolCall.name}</span>\n {/* ★ The status is in the LABEL, not only in the badge colour (WCAG 1.4.1). */}\n <Badge appearance=\"tint\" color={COLOUR[toolCall.status]}>\n {LABEL[toolCall.status]}\n </Badge>\n {toolCall.status === 'running' ? <Spinner size=\"extra-tiny\" /> : null}\n </span>\n }\n >\n <ParameterReview argumentsJson={toolCall.argumentsJson} />\n {toolCall.resultText ? <div className={styles.result}>{toolCall.resultText}</div> : null}\n {toolCall.failure ? <div className={styles.result}>{toolCall.failure.message}</div> : null}\n </Disclosure>\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { FluentProvider, IdPrefixProvider, type Theme } from '@fluentui/react-components';\nimport { resolveHostTheme } from '../theme';\nimport { nextAgentIdPrefix } from './idPrefix';\n\nexport interface AgentKitHostProviderProps {\n children?: React.ReactNode;\n /** An explicit theme wins over everything. */\n theme?: Theme;\n /** The Dynamics host's theme — `context.fluentDesignLanguage?.tokenTheme` in a PCF. */\n hostTheme?: Theme;\n isDarkTheme?: boolean;\n /**\n * The document Fluent should treat as its own.\n *\n * ★★ THIS IS THE PCF ESCAPE HATCH, and it is why it is a prop rather than something the\n * kit decides. Fluent v9's tabster is a per-WINDOW singleton: `createTabster` returns\n * `win.__tabsterInstance` if one exists. A Dynamics form installs tabster 8.2.0, whose\n * core has no `attrHandlers`, while a bundled control ships 8.8.x — so the moment a\n * component reaches a `get*` factory (`TabList` -> `useArrowNavigationGroup` -> `getMover`),\n * `core.attrHandlers.set` throws and React unmounts the whole tree.\n *\n * `useTabster` reads `targetDocument` from Fluent's context and hands\n * `targetDocument.defaultView` to `createTabster`. So a host that passes a proxied\n * document with a private `__tabsterInstance` slot gets its own core, and everything\n * below inherits it — with no change to any agent-kit component.\n *\n * The proxy itself is NOT shipped here; it lives with the PCF gallery\n * (`controls/_shared/tabsterIsolation.ts`). A host writes one line:\n * `targetDocument={createIsolatedTargetDocument(document)}`\n *\n * ★ It isolates tabster and portal mount nodes, NOT Griffel: `FluentProvider` consumes\n * the ambient Griffel renderer rather than building one from this prop. That is\n * harmless for the proxy case (styles land in the real <head> either way) but means\n * this prop alone does NOT make the kit work in a separate document or shadow root —\n * that additionally needs `<RendererProvider renderer={createDOMRenderer(doc)}>`.\n */\n targetDocument?: Document;\n /** Override the generated prefix. Only for tests that need a stable value. */\n idPrefix?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * The host wrapper: `IdPrefixProvider` ▸ `FluentProvider` ▸ children.\n *\n * ★ No agent-kit COMPONENT renders a provider — that is surface-kit's convention and this\n * kit keeps it, so a host that already has a `FluentProvider` is not given a second one.\n * This is an opt-in export for hosts that do not, and it exists for a second reason: a\n * rule that lives only in a README is a rule nothing can test. Shipping the wrapper gives\n * the IdPrefix gate a subject inside `src/`, so its sabotage lands on real code instead of\n * on the test's own fixture.\n *\n * ★ Ordering is load-bearing: `IdPrefixProvider` must be OUTSIDE `FluentProvider`, because\n * the provider reads the prefix while generating the id for its own theme <style> tag.\n */\nexport function AgentKitHostProvider(props: AgentKitHostProviderProps): React.ReactElement {\n const { children, theme, hostTheme, isDarkTheme, targetDocument, className, style } = props;\n\n // Generated ONCE per mounted instance — not per render, and not shared across instances.\n const [generated] = React.useState(nextAgentIdPrefix);\n const idPrefix = props.idPrefix ?? generated;\n\n const resolved = React.useMemo(\n () => resolveHostTheme({ theme, hostTheme, isDarkTheme }),\n [theme, hostTheme, isDarkTheme],\n );\n\n return (\n <IdPrefixProvider value={idPrefix}>\n <FluentProvider\n theme={resolved}\n targetDocument={targetDocument}\n className={className}\n style={style}\n >\n {children}\n </FluentProvider>\n </IdPrefixProvider>\n );\n}\n","import type { BrandVariants, Theme } from '@fluentui/react-components';\nimport {\n createDynamicsV9Theme,\n createDynamicsV9DarkTheme,\n dynamicsBrandRamp,\n} from '@dataverse-kit/fluent-theme';\nimport { typography, radius } from '@dataverse-kit/design-tokens';\n\n/**\n * The Dynamics CE look, for conversational surfaces.\n *\n * ★ The brand ramp and the base builders are NOT declared here — they come from\n * `@dataverse-kit/fluent-theme`, the single declaration shared with grid-kit/v9 and\n * surface-kit/v9. agent-kit adds only the two things that differ for a chat surface.\n */\nfunction applyAgentOverrides(base: Theme): Theme {\n return {\n ...base,\n // Fluent's web theme is close to CE but does not pin the Web variant of Segoe.\n fontFamilyBase: typography.fontFamily,\n // CE is squarer than Fluent web's default. Bubbles opt back up to borderRadiusLarge.\n borderRadiusMedium: radius.card,\n };\n}\n\nexport function createAgentTheme(brand: BrandVariants = dynamicsBrandRamp as BrandVariants): Theme {\n return applyAgentOverrides(createDynamicsV9Theme(brand));\n}\n\nexport function createAgentDarkTheme(\n brand: BrandVariants = dynamicsBrandRamp as BrandVariants,\n): Theme {\n return applyAgentOverrides(createDynamicsV9DarkTheme(brand));\n}\n\n/** Memoized module singletons. */\nexport const agentTheme: Theme = createAgentTheme();\nexport const agentDarkTheme: Theme = createAgentDarkTheme();\n\nexport interface ResolveHostThemeInput {\n /** An explicit theme always wins. */\n theme?: Theme;\n /** The Dynamics host's own theme — `context.fluentDesignLanguage?.tokenTheme` in a PCF. */\n hostTheme?: Theme;\n isDarkTheme?: boolean;\n}\n\n/**\n * Decide which theme to render with. ONE ladder, called by both `AgentKitHostProvider` and\n * the Storybook decorator so the two cannot drift.\n *\n * ★ The host theme wins over the kit's. That is the rule worth a gate, and the test that can\n * see it must supply a host theme whose brand DIFFERS from the kit's — a resolver that\n * silently ignored `hostTheme` looks identical to a correct one when the two happen to\n * agree.\n *\n * ★ The fallback is the Dynamics theme, not stock `webLightTheme`. The gallery controls fall\n * back to `webLightTheme` because in-host they always receive a real theme; a standalone\n * SWA or custom page has none, and stock Fluent does not read as Dynamics CE.\n */\nexport function resolveHostTheme(input: ResolveHostThemeInput = {}): Theme {\n if (input.theme) return input.theme;\n if (input.hostTheme) return input.hostTheme;\n return input.isDarkTheme ? agentDarkTheme : agentTheme;\n}\n","import { createIdPrefixCounter } from '../core/ids';\n\n/**\n * ★★★ ONE counter per bundle. This module-level singleton is the whole mechanism.\n *\n * React 18's `useId` restarts its counter per root. Put two Fluent v9 React roots on one\n * Dynamics form and both name their theme `<style>` tag `fui-FluentProviderr0`; the second\n * provider ADOPTS the first's tag and writes no rules into it, and whichever unmounts first\n * `.remove()`s it unconditionally. The result is a `<style>` with zero CSS rules — invisible\n * inside the form, because custom properties inherit, and fatal for anything PORTALLED\n * (menu listbox, tooltip, dialog, toaster), which mounts on `document.body` and renders\n * untheméd.\n *\n * ★ A CONSTANT prefix does not fix it: two instances of THIS control on one form would\n * collide with each other. Measured in the gallery, where a constant prefix was a real\n * candidate fix and was wrong.\n * ★ No dev harness can show this — a harness mounts one v9 root, so there is nothing to\n * collide with. The gate is a unit test: two renders, assert the provider classes differ.\n */\nexport const nextAgentIdPrefix = createIdPrefixCounter('dvkak');\n","import type { AgentRunStatus, AgentSource, AgentToolCall } from '../core/protocol';\n\n/**\n * What the mock can be driven to do. There is one scenario per terminal state plus the\n * interesting mid-stream shapes, because a Storybook that cannot SHOW a state is a Storybook\n * in which that state is never reviewed — and a test suite that cannot REACH one is a suite\n * in which it is never asserted.\n */\nexport type MockScenarioName =\n | 'happy'\n | 'grounded'\n | 'toolApproval'\n | 'toolAuto'\n | 'blocked'\n | 'refused'\n | 'error'\n | 'notProvisioned'\n | 'cancelled'\n | 'longAnswer'\n | 'throws';\n\nexport interface MockScenario {\n /** The answer, streamed word by word unless `chunks` overrides it. */\n text: string;\n chunks?: string[];\n status: AgentRunStatus;\n guarded?: boolean;\n failureMessage?: string;\n failureCode?: string;\n recoverable?: boolean;\n retryAfterMs?: number;\n sources?: AgentSource[];\n /** Emitted mid-stream, before the terminal event. */\n toolCall?: AgentToolCall;\n /** When set, the tool resolves itself rather than waiting for host approval. */\n autoToolResult?: string;\n suggestions?: string[];\n thinking?: string;\n /** Throw from inside the iterator — the failure channel a Promise-shaped seam does not have. */\n throwsMidStream?: boolean;\n /** Never becomes available; `send()` still yields a well-formed turn. */\n unavailable?: boolean;\n}\n\nconst SOURCES: AgentSource[] = [\n { id: 'src-acct', title: 'Contoso Ltd', kind: 'dataverse', entityLogicalName: 'account', recordId: '11111111-1111-1111-1111-111111111111', snippet: 'Annual revenue £4.2m, 38 employees.' },\n { id: 'src-case', title: 'Case 4417 — invoice mismatch', kind: 'dataverse', entityLogicalName: 'incident', recordId: '22222222-2222-2222-2222-222222222222', snippet: 'Raised 12 Mar, priority High.' },\n { id: 'src-kb', title: 'KB-208: credit note policy', kind: 'knowledge', url: 'https://example.invalid/kb/208', snippet: 'Credit notes above £5,000 require finance approval.', score: 0.82 },\n { id: 'src-doc', title: 'Statement-Mar.pdf', kind: 'document', snippet: 'Page 3 lists the disputed line.' },\n { id: 'src-web', title: 'Companies House filing', kind: 'web', url: 'https://example.invalid/ch' },\n];\n\nexport const mockScenarios: Record<MockScenarioName, MockScenario> = {\n happy: {\n text: 'Contoso has three open cases. The oldest, case 4417, has been waiting eleven days for a credit note.',\n status: 'succeeded',\n suggestions: ['Draft a credit note', 'Show all three cases', 'Who owns case 4417?'],\n },\n\n // ★ FIVE sources, but the text cites only [3] and [1] — and out of order. The panel must\n // show TWO, renumbered 1 and 2 in first-appearance order. A fixture where every source\n // is cited cannot tell a correct implementation from one that lists everything it was given.\n grounded: {\n text: 'Credit notes over £5,000 need finance approval [3], and case 4417 is for £6,200 [1]. So this one needs sign-off.',\n status: 'succeeded',\n sources: SOURCES,\n },\n\n toolApproval: {\n text: 'I can raise the credit note for you — approve the details below and I will submit it.',\n status: 'succeeded',\n toolCall: {\n id: 'call-1',\n name: 'create_credit_note',\n argumentsJson: '{\"accountId\":\"11111111-1111-1111-1111-111111111111\",\"amount\":6200,\"currency\":\"GBP\",\"reason\":\"Invoice mismatch, case 4417\"}',\n status: 'proposed',\n requiresApproval: true,\n },\n },\n\n toolAuto: {\n text: 'I checked the balance for you.',\n status: 'succeeded',\n toolCall: { id: 'call-2', name: 'get_account_balance', argumentsJson: '{\"accountId\":\"1111\"}', status: 'running' },\n autoToolResult: '{\"balance\":6200,\"currency\":\"GBP\"}',\n },\n\n // ★ blocked and refused MUST look different on screen: a content filter fired, versus the\n // model declining. They need different fixes, so they are different states.\n blocked: {\n text: 'I can’t help with that request.',\n status: 'blocked',\n guarded: true,\n failureMessage: 'The response was withheld by the content filter.',\n failureCode: 'content_filter',\n recoverable: false,\n },\n\n refused: {\n text: 'I don’t have enough information to answer that safely. Could you say which account you mean?',\n status: 'refused',\n failureMessage: 'The agent declined to answer.',\n recoverable: true,\n },\n\n error: {\n text: '',\n status: 'error',\n failureMessage: 'The agent is rate limited. Try again shortly.',\n failureCode: 'rate_limited',\n recoverable: true,\n retryAfterMs: 4000,\n },\n\n notProvisioned: {\n text: '',\n status: 'notProvisioned',\n failureMessage: 'No Foundry project is configured for this environment.',\n failureCode: 'not_provisioned',\n recoverable: false,\n unavailable: true,\n },\n\n cancelled: {\n text: 'Let me pull the last six months of activity for Contoso and work through it case by case, starting with the oldest…',\n status: 'cancelled',\n failureMessage: 'Stopped.',\n },\n\n // The fixture the autoscroll and live-region gates run against: enough deltas that\n // \"once, not per token\" is a meaningful distinction.\n longAnswer: {\n text: Array.from({ length: 200 }, (_, i) => `word${i + 1}`).join(' '),\n status: 'succeeded',\n },\n\n throws: {\n text: 'partial…',\n status: 'error',\n throwsMidStream: true,\n failureMessage: 'never reached — the iterator throws instead',\n },\n};\n","import type {\n AgentAvailability,\n AgentEvent,\n AgentTurn,\n AgentTurnResult,\n IAgentService,\n} from '../core/protocol';\nimport { mockScenarios, type MockScenario, type MockScenarioName } from './scenarios';\n\n/** Injectable so tests run at zero delay and Storybook runs at human speed. */\nexport type Scheduler = (ms: number) => Promise<void>;\n\nexport const realScheduler: Scheduler = (ms) =>\n new Promise((resolve) => setTimeout(resolve, ms));\nexport const immediateScheduler: Scheduler = () => Promise.resolve();\n\nexport interface MockAgentServiceOptions {\n scenario?: MockScenarioName;\n scheduler?: Scheduler;\n /** Delay before the first token, so the typing indicator is visible and screenshottable. */\n firstTokenMs?: number;\n chunkMs?: number;\n /**\n * ★ A CONSTRUCTOR ARGUMENT, never module state.\n *\n * tsup runs with `splitting: false`, so every entry gets a self-contained bundle and any\n * module-level `let` is physically duplicated per entry — a story importing from `.` and a\n * test importing from `./services` would get two independent counters. Measured on\n * surface-kit: three copies of the same function body across its entries.\n */\n seed?: number;\n /** Override availability; otherwise derived from the scenario. */\n availability?: AgentAvailability;\n}\n\n/** A tiny deterministic PRNG so Chromatic snapshots do not drift. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * The in-package fake. It is the only \"provider\" agent-kit ships: real transports (Foundry,\n * Copilot Studio, a broker) live in the consuming app, so the kit never holds a credential.\n *\n * ★ It can reach EVERY `AgentRunStatus`. A test asserts that, because a mock that cannot\n * produce a state is a state nothing downstream is ever tested against.\n */\nexport class MockAgentService implements IAgentService {\n readonly name = 'mock';\n\n private readonly scenario: MockScenario;\n private readonly scenarioName: MockScenarioName;\n private readonly scheduler: Scheduler;\n private readonly firstTokenMs: number;\n private readonly chunkMs: number;\n private readonly rand: () => number;\n private readonly availabilityOverride?: AgentAvailability;\n\n constructor(options: MockAgentServiceOptions = {}) {\n this.scenarioName = options.scenario ?? 'happy';\n this.scenario = mockScenarios[this.scenarioName];\n this.scheduler = options.scheduler ?? realScheduler;\n this.firstTokenMs = options.firstTokenMs ?? 400;\n this.chunkMs = options.chunkMs ?? 28;\n this.rand = mulberry32(options.seed ?? 1);\n this.availabilityOverride = options.availability;\n }\n\n async isAvailable(): Promise<AgentAvailability> {\n if (this.availabilityOverride) return this.availabilityOverride;\n if (this.scenario.unavailable) {\n return {\n available: false,\n status: 'notProvisioned',\n reason: this.scenario.failureMessage ?? 'Not provisioned.',\n };\n }\n return {\n available: true,\n capabilities: { streaming: true, tools: true, citations: true, attachments: true, cancel: true },\n };\n }\n\n /**\n * A prompt can select a scenario (`/blocked`, `/tool`, `/error`), so one story can walk\n * every state without remounting.\n */\n private resolveScenario(promptText: string): { name: MockScenarioName; scenario: MockScenario } {\n const slash = promptText.trim().match(/^\\/(\\w+)/)?.[1] as MockScenarioName | undefined;\n if (slash && slash in mockScenarios) {\n return { name: slash, scenario: mockScenarios[slash] };\n }\n return { name: this.scenarioName, scenario: this.scenario };\n }\n\n async *send(turn: AgentTurn): AsyncIterable<AgentEvent> {\n const { scenario } = this.resolveScenario(turn.text);\n const messageId = `mock-${Math.floor(this.rand() * 1e9).toString(36)}`;\n const turnId = `turn-${messageId}`;\n const provider = this.name;\n\n const finish = (result: Omit<AgentTurnResult, 'provider'>): AgentEvent => ({\n type: 'turn_end',\n turnId,\n messageId,\n result: { ...result, provider },\n });\n\n yield { type: 'turn_start', turnId, messageId, provider, model: 'mock-1' };\n\n if (turn.cancelSignal?.aborted) {\n yield finish({ status: 'cancelled', text: '', failure: { status: 'cancelled', message: 'Stopped.' } });\n return;\n }\n\n // Terminal-before-any-text scenarios still emit a well-formed turn.\n if (scenario.status === 'notProvisioned' || (scenario.status === 'error' && !scenario.text)) {\n await this.scheduler(this.firstTokenMs);\n yield finish({\n status: scenario.status,\n text: '',\n failure: {\n status: scenario.status,\n message: scenario.failureMessage ?? 'Failed.',\n code: scenario.failureCode,\n recoverable: scenario.recoverable,\n retryAfterMs: scenario.retryAfterMs,\n },\n });\n return;\n }\n\n if (scenario.sources) {\n yield { type: 'status', messageId, label: 'Searching Dataverse…' };\n await this.scheduler(this.firstTokenMs);\n yield { type: 'sources', messageId, sources: scenario.sources };\n }\n\n if (scenario.thinking) {\n yield { type: 'thinking_delta', messageId, text: scenario.thinking };\n }\n\n if (scenario.toolCall) {\n yield { type: 'tool_call', messageId, call: scenario.toolCall };\n if (scenario.autoToolResult !== undefined) {\n await this.scheduler(this.chunkMs);\n yield {\n type: 'tool_result',\n messageId,\n callId: scenario.toolCall.id,\n status: 'succeeded',\n resultText: scenario.autoToolResult,\n };\n }\n }\n\n const chunks = scenario.chunks ?? scenario.text.split(/(?<=\\s)/);\n await this.scheduler(this.firstTokenMs);\n\n let emitted = '';\n for (const [i, chunk] of chunks.entries()) {\n if (turn.cancelSignal?.aborted) {\n yield finish({\n status: 'cancelled',\n text: emitted,\n failure: { status: 'cancelled', message: 'Stopped.' },\n });\n return;\n }\n if (scenario.throwsMidStream && i === Math.floor(chunks.length / 2)) {\n // The failure channel an AsyncIterable has and a Promise does not. A consumer must\n // surface this as a notice, not by unmounting the tree.\n throw new Error('mock transport exploded mid-stream');\n }\n emitted += chunk;\n yield { type: 'text_delta', messageId, text: chunk };\n await this.scheduler(this.chunkMs);\n }\n\n if (scenario.suggestions) {\n yield { type: 'suggestions', messageId, prompts: scenario.suggestions };\n }\n\n const failed = scenario.status !== 'succeeded';\n yield finish({\n status: scenario.status,\n text: emitted,\n guarded: scenario.guarded,\n usage: {\n inputTokens: 128,\n outputTokens: chunks.length,\n costUsd: Number((chunks.length * 0.000002).toFixed(6)),\n durationMs: this.firstTokenMs + chunks.length * this.chunkMs,\n model: 'mock-1',\n },\n failure: failed\n ? {\n status: scenario.status as Exclude<typeof scenario.status, 'succeeded'>,\n message: scenario.failureMessage ?? 'Failed.',\n code: scenario.failureCode,\n recoverable: scenario.recoverable,\n retryAfterMs: scenario.retryAfterMs,\n }\n : undefined,\n });\n }\n}\n","import type { AgentAvailability, AgentEvent, AgentTurn, IAgentService } from '../core/protocol';\n\n/**\n * The default provider: answers nothing, politely.\n *\n * ★ `none` is the DEFAULT and must stay so. A kit dropped into a host nobody has wired must\n * not silently start talking to a service because someone shipped a new build. Carried\n * from `ILlmService`, where the same rule is load-bearing in a regulated process.\n *\n * ★ It still yields a well-formed turn — `turn_start` then one `turn_end` — rather than\n * throwing or yielding nothing. An unconfigured kit should render \"not configured\", not\n * a spinner that never resolves.\n */\nexport class NullAgentService implements IAgentService {\n readonly name = 'none';\n\n async isAvailable(): Promise<AgentAvailability> {\n return {\n available: false,\n status: 'notProvisioned',\n reason: 'No agent provider is configured for this host.',\n };\n }\n\n async *send(turn: AgentTurn): AsyncIterable<AgentEvent> {\n const messageId = `null-${Date.now()}`;\n const turnId = `turn-${messageId}`;\n void turn;\n yield { type: 'turn_start', turnId, messageId, provider: this.name };\n yield {\n type: 'turn_end',\n turnId,\n messageId,\n result: {\n status: 'notProvisioned',\n text: '',\n provider: this.name,\n failure: {\n status: 'notProvisioned',\n message: 'No agent provider is configured for this host.',\n code: 'not_provisioned',\n recoverable: false,\n },\n },\n };\n }\n}\n","import type { AgentServiceConfig, IAgentService } from '../core/protocol';\nimport { MockAgentService } from './MockAgentService';\nimport { NullAgentService } from './NullAgentService';\n\nexport interface ServiceDecision {\n provider: IAgentService;\n /** Why this one was chosen — surfaced in diagnostics so a misconfiguration is legible. */\n reason: string;\n}\n\n/**\n * Provider selection, as ONE ladder.\n *\n * ★ `decide()` is exported alongside `createAgentService()` and they share a return type, so\n * the factory and any diagnostics view cannot drift — the shape `ServiceFactory.decide()`\n * uses in `@dataverse-kit/api-service` for exactly the same reason.\n *\n * ★ An UNRECOGNISED provider name falls back to `none`, never to a working provider. Carried\n * from `createLlmService`: a typo must produce silence, not an unintended call to a model.\n */\nexport function decide(config: AgentServiceConfig): ServiceDecision {\n switch (config.provider) {\n case 'custom':\n return config.factory\n ? { provider: config.factory(), reason: 'explicit factory (provider: custom)' }\n : { provider: new NullAgentService(), reason: 'provider: custom but no factory supplied' };\n case 'mock':\n return { provider: new MockAgentService(), reason: 'provider: mock' };\n case 'none':\n return { provider: new NullAgentService(), reason: 'provider: none (the default)' };\n default:\n return {\n provider: new NullAgentService(),\n reason: `unrecognised provider ${String(config.provider)} — falling back to none`,\n };\n }\n}\n\nexport function createAgentService(\n config: AgentServiceConfig = { provider: 'none' },\n): IAgentService {\n return decide(config).provider;\n}\n"],"mappings":"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","names":["React","Button","makeStyles","tokens","dayKey","TERMINAL","React","React","React","React","React","makeStyles","mergeClasses","tokens","makeStyles","jsx","jsxs","makeStyles","tokens","jsx","useStyles","makeStyles","tokens","React","makeStyles","mergeClasses","tokens","jsx","useStyles","CardSurface","React","Button","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Button","React","makeStyles","tokens","mergeClasses","jsx","jsxs","useStyles","jsx","jsx","jsxs","useStyles","makeStyles","tokens","mergeClasses","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","jsx","jsxs","useStyles","jsx","jsxs","useStyles","makeStyles","tokens","Button","React","Button","makeStyles","tokens","Tooltip","jsx","jsxs","useStyles","Button","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","tokens","Text","Button","jsx","jsxs","Button","Tooltip","StopRegular","jsx","MessageBar","MessageBarBody","MessageBarTitle","MessageBarActions","Button","jsx","jsxs","makeStyles","tokens","jsx","jsxs","useStyles","React","MessageBar","MessageBarBody","MessageBarTitle","MessageBarActions","Button","jsx","jsxs","Badge","jsx","jsx","React","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","tokens","Text","Fragment","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","tokens","Text","React","makeStyles","tokens","Button","Fragment","jsx","jsxs","useStyles","Button","Tooltip","makeStyles","mergeClasses","tokens","jsx","jsxs","useStyles","React","makeStyles","tokens","Text","makeStyles","mergeClasses","tokens","Avatar","jsx","jsx","jsxs","useStyles","makeStyles","tokens","mergeClasses","jsx","useStyles","makeStyles","tokens","Text","Button","Menu","MenuTrigger","MenuPopover","MenuList","MenuItem","Text","makeStyles","tokens","MoreHorizontalRegular","jsx","jsxs","useStyles","makeStyles","tokens","Text","Button","Menu","MenuTrigger","MoreHorizontalRegular","MenuPopover","MenuList","MenuItem","React","Button","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","jsx","useStyles","Tooltip","makeStyles","tokens","jsx","useStyles","React","makeStyles","tokens","Button","Text","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","Button","jsx","useStyles","makeStyles","tokens","React","makeStyles","jsx","useStyles","makeStyles","React","Text","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","tokens","ShieldErrorRegular","jsx","jsxs","useStyles","React","Text","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","React","Button","makeStyles","tokens","DismissRegular","React","makeStyles","tokens","Text","jsx","jsxs","useStyles","MessageBar","MessageBarBody","MessageBarTitle","MessageBarActions","Button","makeStyles","tokens","jsx","jsxs","INTENT","useStyles","Fragment","jsx","jsxs","useStyles","makeStyles","tokens","Button","DismissRegular","React","Badge","Spinner","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Badge","Spinner","React","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/conversation/MessageList.tsx","../src/core/runStatus.ts","../src/core/grouping.ts","../src/core/dayDividers.ts","../src/core/citations.ts","../src/core/conversationReducer.ts","../src/core/normalize.ts","../src/core/announce.ts","../src/core/scroll.ts","../src/core/ids.ts","../src/a11y/LiveAnnouncer.tsx","../src/a11y/visuallyHidden.ts","../src/a11y/useFocusRestore.ts","../src/a11y/useRovingTabindex.ts","../src/a11y/useReturnFocus.ts","../src/hooks/useStickyScroll.ts","../src/hooks/useConversation.ts","../src/conversation/MessageBubble.tsx","../src/conversation/StreamingText.tsx","../src/conversation/MessageActions.tsx","../src/internal/ActionToolbar.tsx","../src/internal/CardSurface.tsx","../src/internal/ConfirmInline.tsx","../src/internal/Disclosure.tsx","../src/conversation/DayDivider.tsx","../src/conversation/TypingIndicator.tsx","../src/conversation/Composer.tsx","../src/conversation/SuggestedPrompts.tsx","../src/conversation/EmptyConversation.tsx","../src/conversation/SystemNotice.tsx","../src/ops/AgentStatusBadge.tsx","../src/ops/AvailabilityBanner.tsx","../src/ops/UsageMeter.tsx","../src/ops/ThrottleNotice.tsx","../src/ops/ModelBadge.tsx","../src/ops/AgentPicker.tsx","../src/ops/RunTimeline.tsx","../src/ops/RunHistoryPanel.tsx","../src/ops/AgentOpsPanel.tsx","../src/support/AgentLauncher.tsx","../src/support/AssistantPanel.tsx","../src/support/FeedbackPanel.tsx","../src/shell/AgentAppShell.tsx","../src/shell/AppRail.tsx","../src/shell/ConversationList.tsx","../src/shell/ConversationListItem.tsx","../src/shell/AgentAvatar.tsx","../src/shell/ConversationHeader.tsx","../src/shell/RightPane.tsx","../src/shell/GlobalSearchBar.tsx","../src/grounding/CitationChip.tsx","../src/grounding/CitationList.tsx","../src/grounding/SourceCard.tsx","../src/grounding/AnswerWithCitations.tsx","../src/grounding/GroundingPanel.tsx","../src/grounding/ProviderAttribution.tsx","../src/actions/ActionCard.tsx","../src/actions/ApprovalCard.tsx","../src/actions/ParameterReview.tsx","../src/actions/ActionResult.tsx","../src/actions/ToolCallCard.tsx","../src/host/AgentKitHostProvider.tsx","../src/theme/index.ts","../src/host/idPrefix.ts","../src/services/scenarios.ts","../src/services/MockAgentService.ts","../src/services/NullAgentService.ts","../src/services/createAgentService.ts"],"sourcesContent":["import * as React from 'react';\nimport { Button, makeStyles, tokens } from '@fluentui/react-components';\nimport { ArrowDownRegular } from '@fluentui/react-icons';\nimport {\n bucketByDay,\n groupMessages,\n type AgentMessage,\n type AgentParticipant,\n type Announcement,\n} from '../core';\nimport { LiveAnnouncer } from '../a11y';\nimport { useStickyScroll } from '../hooks';\nimport { MessageBubble } from './MessageBubble';\nimport { DayDivider } from './DayDivider';\nimport { TypingIndicator } from './TypingIndicator';\nimport type { MessageActionsProps } from './MessageActions';\n\nexport interface MessageListProps extends Omit<MessageActionsProps, 'message'> {\n messages: readonly AgentMessage[];\n participants?: readonly AgentParticipant[];\n /** Renders the typing indicator and suppresses the \"jump to latest\" nudge. */\n busy?: boolean;\n announcement?: Announcement;\n groupWindowMs?: number;\n timeZone?: string;\n locale?: string;\n /** Injected so day labels are deterministic in tests and Chromatic. */\n now?: number;\n emptyState?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: { position: 'relative', height: '100%', minHeight: 0, display: 'flex', flexDirection: 'column' },\n scroller: {\n flex: 1,\n overflowY: 'auto',\n padding: tokens.spacingVerticalM,\n display: 'flex',\n flexDirection: 'column',\n gap: tokens.spacingVerticalS,\n },\n jump: { position: 'absolute', bottom: tokens.spacingVerticalM, alignSelf: 'center', zIndex: 1 },\n});\n\n/**\n * The transcript.\n *\n * ★ It is NOT a live region. Announcements go through `LiveAnnouncer`, fed by\n * `deriveAnnouncement` on state TRANSITIONS — a live region over the streaming node queues\n * every token and a screen reader never finishes reading.\n *\n * ★ Grouping (avatar + name once per run) is VISUAL. Every `MessageBubble` still carries its\n * author and timestamp in the accessible tree.\n */\nexport function MessageList(props: MessageListProps): React.ReactElement {\n const {\n messages, participants, busy = false, announcement,\n groupWindowMs, timeZone, locale, now, emptyState, ...actionHandlers\n } = props;\n\n const styles = useStyles();\n const scrollerRef = React.useRef<HTMLDivElement>(null);\n const { onScroll, scrollToBottom, isPinned } = useStickyScroll(scrollerRef, messages.length);\n\n const byId = React.useMemo(\n () => new Map((participants ?? []).map((p) => [p.id, p])),\n [participants],\n );\n\n // A message is a run START unless the grouping says it continues one.\n const runStarts = React.useMemo(() => {\n const groups = groupMessages(messages, { windowMs: groupWindowMs, timeZone });\n return new Set(groups.map((g) => g.messageIds[0]));\n }, [messages, groupWindowMs, timeZone]);\n\n const buckets = React.useMemo(\n () => bucketByDay(messages, { timeZone, now }),\n [messages, timeZone, now],\n );\n const dividerBefore = React.useMemo(() => {\n const map = new Map<string, (typeof buckets)[number]['label']>();\n for (const bucket of buckets) map.set(bucket.messageIds[0], bucket.label);\n return map;\n }, [buckets]);\n\n return (\n <div className={styles.root}>\n <LiveAnnouncer polite={announcement?.polite} assertive={announcement?.assertive} />\n\n <div\n ref={scrollerRef}\n className={styles.scroller}\n onScroll={onScroll}\n // A labelled, focusable scroll region: a keyboard user must be able to reach and\n // scroll the transcript without tabbing through every message inside it.\n role=\"log\"\n aria-label=\"Conversation\"\n tabIndex={0}\n >\n {messages.length === 0 ? (\n emptyState ?? null\n ) : (\n messages.map((message) => (\n <React.Fragment key={message.id}>\n {dividerBefore.has(message.id) ? (\n <DayDivider label={dividerBefore.get(message.id)!} locale={locale} />\n ) : null}\n <MessageBubble\n message={message}\n author={byId.get(message.authorId)}\n isRunStart={runStarts.has(message.id)}\n locale={locale}\n {...actionHandlers}\n />\n </React.Fragment>\n ))\n )}\n {busy ? <TypingIndicator /> : null}\n </div>\n\n {!isPinned && messages.length > 0 ? (\n <Button\n className={styles.jump}\n size=\"small\"\n appearance=\"primary\"\n icon={<ArrowDownRegular />}\n onClick={scrollToBottom}\n >\n Jump to latest\n </Button>\n ) : null}\n </div>\n );\n}\n","import type { AgentFailure, AgentRunStatus } from './protocol';\n\n/** Terminal statuses. `succeeded` included — this answers \"is the turn over?\", not \"did it work?\". */\nconst TERMINAL: ReadonlySet<AgentRunStatus> = new Set<AgentRunStatus>([\n 'succeeded',\n 'blocked',\n 'refused',\n 'error',\n 'notProvisioned',\n 'cancelled',\n]);\n\nexport function isTerminalStatus(status: AgentRunStatus): boolean {\n return TERMINAL.has(status);\n}\n\n/** How a status should READ, not what colour it is — the UI maps this to tokens. */\nexport function runStatusSeverity(\n status: AgentRunStatus,\n): 'success' | 'warning' | 'error' | 'info' {\n switch (status) {\n case 'succeeded':\n return 'success';\n case 'blocked':\n case 'refused':\n return 'warning';\n case 'error':\n return 'error';\n case 'notProvisioned':\n case 'cancelled':\n return 'info';\n }\n}\n\n/**\n * Classify a transport failure into the six-state ladder.\n *\n * ★★ 503 maps to `notProvisioned`, NOT `error`. Adopted from the ai-103 broker, which\n * records the reason: with on-demand Azure most services are absent most of the time,\n * and that is a normal state — reporting it as a failure is what would make the app look\n * broken. Without this branch, \"nobody has turned this on yet\" and \"it is broken\" are\n * indistinguishable on screen, and they need completely different fixes.\n */\nexport function classifyTransportFailure(input: {\n httpStatus?: number;\n code?: string;\n message?: string;\n retryAfterMs?: number;\n}): AgentFailure {\n const { httpStatus, code, retryAfterMs } = input;\n const message = input.message ?? 'The agent could not be reached.';\n\n if (httpStatus === 503) {\n return {\n status: 'notProvisioned',\n message,\n code: code ?? 'not_provisioned',\n recoverable: false,\n correlationId: undefined,\n };\n }\n if (httpStatus === 429) {\n return { status: 'error', message, code: code ?? 'rate_limited', recoverable: true, retryAfterMs };\n }\n if (code === 'content_filter') {\n return { status: 'blocked', message, code, recoverable: false };\n }\n return { status: 'error', message, code, recoverable: httpStatus !== undefined && httpStatus >= 500 };\n}\n","import type { AgentMessage, AgentRole } from './protocol';\n\n/** Teams groups consecutive messages from one author inside a short window. */\nexport const DEFAULT_GROUP_WINDOW_MS = 5 * 60 * 1000;\n\nexport interface GroupingOptions {\n windowMs?: number;\n /** Injected so day-boundary behaviour is testable without touching the system clock. */\n timeZone?: string;\n}\n\nexport interface MessageGroup {\n key: string;\n authorId: string;\n role: AgentRole;\n startedAt: number;\n messageIds: string[];\n}\n\n/** Local calendar day, in the given zone. Duplicated deliberately from dayDividers to keep\n * this module independent of it; both delegate to Intl, so they cannot disagree. */\nfunction dayKey(epochMs: number, timeZone?: string): string {\n return new Intl.DateTimeFormat('en-CA', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).format(new Date(epochMs));\n}\n\n/**\n * Do these two messages belong to the same visual run?\n *\n * ★ Exported separately from `groupMessages` on purpose. The boundary cases (4:59 / exactly\n * 5:00 / 5:01) are then assertable against the PREDICATE, instead of being inferred from\n * a group count — where an off-by-one and a correct implementation can produce the same\n * number of groups for the wrong reason.\n */\nexport function isSameAuthorRun(\n a: AgentMessage,\n b: AgentMessage,\n windowMs: number = DEFAULT_GROUP_WINDOW_MS,\n timeZone?: string,\n): boolean {\n if (a.authorId !== b.authorId) return false;\n if (a.role !== b.role) return false;\n // A system notice between two messages ends the run: the second is a new utterance.\n if (a.role === 'system' || b.role === 'system') return false;\n if (b.createdAt < a.createdAt) return false;\n if (b.createdAt - a.createdAt > windowMs) return false;\n // Never group across a day divider — the divider would have to render inside the group.\n return dayKey(a.createdAt, timeZone) === dayKey(b.createdAt, timeZone);\n}\n\n/**\n * Collapse consecutive same-author messages into runs, Teams-style: the avatar and name\n * render once per run.\n *\n * ★ Grouping is a VISUAL affordance only. Every message must still carry its author in the\n * accessible name — a screen reader navigating message-by-message would otherwise hear\n * nothing identifying messages 2..N of a run, in a UI whose entire point is the\n * distinction between what the user said and what the model said.\n */\nexport function groupMessages(\n messages: readonly AgentMessage[],\n options: GroupingOptions = {},\n): MessageGroup[] {\n const windowMs = options.windowMs ?? DEFAULT_GROUP_WINDOW_MS;\n const groups: MessageGroup[] = [];\n\n for (const message of messages) {\n const current = groups[groups.length - 1];\n const previousId = current?.messageIds[current.messageIds.length - 1];\n const previous = previousId ? messages.find((m) => m.id === previousId) : undefined;\n\n if (current && previous && isSameAuthorRun(previous, message, windowMs, options.timeZone)) {\n current.messageIds.push(message.id);\n continue;\n }\n groups.push({\n key: `${message.authorId}:${message.id}`,\n authorId: message.authorId,\n role: message.role,\n startedAt: message.createdAt,\n messageIds: [message.id],\n });\n }\n return groups;\n}\n","import type { AgentMessage } from './protocol';\n\n/**\n * A day divider as a DESCRIPTOR, never a localised string.\n *\n * ★ A pure-TS module that returned \"Yesterday\" could not be localised by the host and could\n * not be tested deterministically. The React layer maps this through `Intl.DateTimeFormat`.\n */\nexport type DayDividerLabel =\n | { kind: 'today' }\n | { kind: 'yesterday' }\n | { kind: 'weekday'; weekday: number; iso: string }\n | { kind: 'date'; iso: string };\n\nexport interface DayBucket {\n /** `YYYY-MM-DD` in the resolved zone. */\n dayKey: string;\n label: DayDividerLabel;\n messageIds: string[];\n}\n\n/** Local calendar day in `timeZone`. `en-CA` because it formats as `YYYY-MM-DD`. */\nexport function dayKeyOf(epochMs: number, timeZone?: string): string {\n return new Intl.DateTimeFormat('en-CA', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).format(new Date(epochMs));\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction labelFor(dayKey: string, nowMs: number, timeZone?: string): DayDividerLabel {\n const todayKey = dayKeyOf(nowMs, timeZone);\n if (dayKey === todayKey) return { kind: 'today' };\n if (dayKey === dayKeyOf(nowMs - DAY_MS, timeZone)) return { kind: 'yesterday' };\n\n // Within the last week, Teams shows the weekday name.\n const asDate = new Date(`${dayKey}T00:00:00Z`);\n for (let back = 2; back <= 6; back++) {\n if (dayKey === dayKeyOf(nowMs - back * DAY_MS, timeZone)) {\n return { kind: 'weekday', weekday: asDate.getUTCDay(), iso: dayKey };\n }\n }\n return { kind: 'date', iso: dayKey };\n}\n\n/**\n * Bucket messages by local calendar day.\n *\n * ★ `now` and `timeZone` are INJECTED, not read from the environment. That is what makes\n * the claim expressible at all: the test that separates a correct implementation from a\n * naive `new Date().toDateString()` is the one that feeds the SAME epoch with two zones\n * either side of the date line and asserts the keys DIFFER. A UTC-only test passes for\n * both.\n */\nexport function bucketByDay(\n messages: readonly AgentMessage[],\n options: { timeZone?: string; now?: number } = {},\n): DayBucket[] {\n const nowMs = options.now ?? Date.now();\n const buckets: DayBucket[] = [];\n\n for (const message of messages) {\n const key = dayKeyOf(message.createdAt, options.timeZone);\n const current = buckets[buckets.length - 1];\n if (current && current.dayKey === key) {\n current.messageIds.push(message.id);\n continue;\n }\n buckets.push({\n dayKey: key,\n label: labelFor(key, nowMs, options.timeZone),\n messageIds: [message.id],\n });\n }\n return buckets;\n}\n","import type { AgentCitation, AgentSource } from './protocol';\n\nexport interface CitationSegment {\n kind: 'text' | 'citation';\n text: string;\n marker?: string;\n sourceId?: string;\n}\n\n/** `[1]` and the Azure OpenAI annotation form `【3:0†source】`. */\nconst BRACKET_MARKER = /\\[(\\d{1,3})\\]/g;\nconst AOAI_MARKER = /【(\\d{1,3}):\\d+†[^】]*】/g;\n\nexport interface ExtractedMarker {\n marker: string;\n index: number;\n length: number;\n}\n\n/** Every citation marker in the text, in order of appearance. */\nexport function extractCitationMarkers(text: string): ExtractedMarker[] {\n const found: ExtractedMarker[] = [];\n for (const re of [BRACKET_MARKER, AOAI_MARKER]) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n found.push({ marker: m[1], index: m.index, length: m[0].length });\n }\n }\n return found.sort((a, b) => a.index - b.index);\n}\n\n/**\n * Renumber an answer's citations to `[1]`, `[2]`… in first-appearance order, and return\n * ONLY the sources the text actually cites.\n *\n * ★★ Dropping uncited sources is the point of this function, not a side effect. A grounding\n * panel listing twelve retrieved chunks under a two-citation answer is the defect it\n * exists to prevent: it implies the answer rests on twelve things when it rests on two,\n * which is exactly the kind of overstated provenance that makes a citation panel\n * decorative rather than trustworthy.\n */\nexport function renumberCitations(\n text: string,\n sources: readonly AgentSource[],\n): { text: string; used: AgentSource[]; citations: AgentCitation[] } {\n const markers = extractCitationMarkers(text);\n const order: string[] = [];\n for (const { marker } of markers) if (!order.includes(marker)) order.push(marker);\n\n const byOriginal = new Map<string, number>();\n order.forEach((marker, i) => byOriginal.set(marker, i + 1));\n\n const used: AgentSource[] = [];\n const citations: AgentCitation[] = [];\n for (const marker of order) {\n // Markers are 1-based positions into the ORIGINAL source list.\n const source = sources[Number(marker) - 1];\n if (!source) continue;\n used.push(source);\n citations.push({ marker: String(byOriginal.get(marker)), sourceId: source.id });\n }\n\n let out = '';\n let cursor = 0;\n for (const { marker, index, length } of markers) {\n out += text.slice(cursor, index);\n const renumbered = byOriginal.get(marker);\n out += renumbered === undefined ? '' : `[${renumbered}]`;\n cursor = index + length;\n }\n out += text.slice(cursor);\n\n return { text: out, used, citations };\n}\n\n/** Split text into runs so the renderer can put a chip where each marker was. */\nexport function splitTextByCitations(\n text: string,\n citations: readonly AgentCitation[],\n): CitationSegment[] {\n const markers = extractCitationMarkers(text);\n if (markers.length === 0) return text ? [{ kind: 'text', text }] : [];\n\n const segments: CitationSegment[] = [];\n let cursor = 0;\n for (const { marker, index, length } of markers) {\n if (index > cursor) segments.push({ kind: 'text', text: text.slice(cursor, index) });\n const citation = citations.find((c) => c.marker === marker);\n segments.push({\n kind: 'citation',\n text: `[${marker}]`,\n marker,\n sourceId: citation?.sourceId,\n });\n cursor = index + length;\n }\n if (cursor < text.length) segments.push({ kind: 'text', text: text.slice(cursor) });\n return segments;\n}\n","import type {\n AgentAttachment,\n AgentEvent,\n AgentFailure,\n AgentMessage,\n AgentRunStatus,\n AgentUsage,\n} from './protocol';\n\n/** One field, not a `{loading, error}` pair that can disagree with itself. */\nexport type ConversationStatus = 'idle' | 'connecting' | 'streaming' | AgentRunStatus;\n\nexport interface ConversationState {\n messages: AgentMessage[];\n streamingMessageId: string | null;\n status: ConversationStatus;\n /** Ephemeral chrome from a `status` event (\"Searching Dataverse…\"). Not message content. */\n statusLabel?: string;\n failure?: AgentFailure;\n usage?: AgentUsage;\n suggestions?: string[];\n}\n\nexport function initialConversation(seed: readonly AgentMessage[] = []): ConversationState {\n return { messages: [...seed], streamingMessageId: null, status: 'idle' };\n}\n\n/** Replace exactly one message, leaving every other array slot identity-stable so React can\n * bail out of re-rendering the rest of the transcript during a stream. */\nfunction patch(\n state: ConversationState,\n messageId: string,\n update: (m: AgentMessage) => AgentMessage,\n): AgentMessage[] {\n const i = state.messages.findIndex((m) => m.id === messageId);\n if (i === -1) return state.messages;\n const next = state.messages.slice();\n next[i] = update(next[i]);\n return next;\n}\n\nexport function appendUserMessage(\n state: ConversationState,\n input: { id: string; text: string; authorId?: string; attachments?: AgentAttachment[]; now?: number },\n): ConversationState {\n const message: AgentMessage = {\n id: input.id,\n role: 'user',\n authorId: input.authorId ?? 'user',\n text: input.text,\n createdAt: input.now ?? Date.now(),\n attachments: input.attachments,\n };\n return { ...state, messages: [...state.messages, message], status: 'connecting', failure: undefined };\n}\n\n/**\n * Apply one stream event.\n *\n * ★ Written as an EXHAUSTIVE switch with no `default:`. The repo's tsconfig sets\n * `noFallthroughCasesInSwitch` and `strict`, so adding a member to `AgentEvent` without a\n * case here is a compile error — a gate you get for free, and one that a tidy-looking\n * `default: return state` would silently remove. Do not add one.\n */\nexport function applyAgentEvent(state: ConversationState, event: AgentEvent): ConversationState {\n switch (event.type) {\n case 'turn_start': {\n const message: AgentMessage = {\n id: event.messageId,\n role: 'assistant',\n authorId: event.provider ?? 'agent',\n text: '',\n createdAt: Date.now(),\n streaming: true,\n provider: event.provider,\n };\n return {\n ...state,\n messages: [...state.messages, message],\n streamingMessageId: event.messageId,\n status: 'streaming',\n statusLabel: undefined,\n failure: undefined,\n suggestions: undefined,\n };\n }\n\n case 'text_delta':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({ ...m, text: m.text + event.text })),\n };\n\n case 'thinking_delta':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n thinking: (m.thinking ?? '') + event.text,\n })),\n };\n\n case 'tool_call':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n toolCalls: [...(m.toolCalls ?? []), event.call],\n })),\n };\n\n case 'tool_result':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n toolCalls: (m.toolCalls ?? []).map((c) =>\n c.id === event.callId\n ? { ...c, status: event.status, resultText: event.resultText, failure: event.failure }\n : c,\n ),\n })),\n };\n\n case 'sources':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({ ...m, sources: event.sources })),\n };\n\n case 'citation':\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n citations: [...(m.citations ?? []), event.citation],\n })),\n };\n\n case 'suggestions':\n return { ...state, suggestions: event.prompts };\n\n case 'status':\n return { ...state, statusLabel: event.label };\n\n case 'turn_end': {\n const { result } = event;\n return {\n ...state,\n messages: patch(state, event.messageId, (m) => ({\n ...m,\n // A non-streaming provider sends no deltas, so the assembled text arrives here.\n text: m.text.length > 0 ? m.text : result.text,\n streaming: false,\n guarded: result.guarded,\n provider: result.provider,\n usage: result.usage,\n failure: result.failure,\n })),\n streamingMessageId: null,\n status: result.status,\n statusLabel: undefined,\n failure: result.failure,\n usage: result.usage,\n };\n }\n }\n}\n","import type { AgentEvent, AgentToolCall } from './protocol';\n\n/**\n * Transport normalizers: turn one provider's wire shape into `AgentEvent[]`.\n *\n * ★ Each returns an ARRAY, never a single event or null. One Azure OpenAI chunk can\n * legitimately carry a text delta AND a tool-call fragment AND a citation annotation, so\n * a one-in-one-out signature would silently drop two of the three.\n *\n * ★ These live in ./core (no React, no DOM) because a transport adapter frequently runs\n * where React must not be — an Azure Function proxying SSE, a web worker, a Node broker.\n * The same normalizer must be usable on both sides of that boundary.\n *\n * ★ Only shapes whose wire format is KNOWN are implemented. A normalizer written from an\n * assumed shape is a fixture that measures a platform which does not exist, so\n * `fromDirectLineActivity` is deliberately absent until an adapter exists to measure it\n * against — see CLAUDE.md.\n */\n\nexport interface NormalizeCtx {\n messageId: string;\n turnId: string;\n}\n\n/**\n * Unwrap one SSE line. Returns `undefined` for keep-alives, comments and blank lines, and\n * the sentinel `'[DONE]'` for the terminator — callers must distinguish those, since\n * \"nothing to do\" and \"the stream is over\" are different.\n */\nexport function fromSseLine(line: string): unknown | '[DONE]' | undefined {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith(':')) return undefined;\n if (!trimmed.startsWith('data:')) return undefined;\n const payload = trimmed.slice('data:'.length).trim();\n if (payload === '') return undefined;\n if (payload === '[DONE]') return '[DONE]';\n try {\n return JSON.parse(payload) as unknown;\n } catch {\n return undefined;\n }\n}\n\ninterface OpenAiDelta {\n content?: string | null;\n tool_calls?: { index?: number; id?: string; function?: { name?: string; arguments?: string } }[];\n}\ninterface OpenAiChunk {\n choices?: { delta?: OpenAiDelta }[];\n}\n\n/** An OpenAI / Azure OpenAI streaming chunk. */\nexport function fromOpenAiChatChunk(chunk: unknown, ctx: NormalizeCtx): AgentEvent[] {\n const events: AgentEvent[] = [];\n const delta = (chunk as OpenAiChunk | undefined)?.choices?.[0]?.delta;\n if (!delta) return events;\n\n if (typeof delta.content === 'string' && delta.content.length > 0) {\n events.push({ type: 'text_delta', messageId: ctx.messageId, text: delta.content });\n }\n for (const call of delta.tool_calls ?? []) {\n if (!call.id) continue; // a pure arguments continuation; the caller accumulates it\n const toolCall: AgentToolCall = {\n id: call.id,\n name: call.function?.name ?? '',\n argumentsJson: call.function?.arguments ?? '',\n status: 'proposed',\n };\n events.push({ type: 'tool_call', messageId: ctx.messageId, call: toolCall });\n }\n return events;\n}\n\n/** The `@dataverse-kit/claude-bridge` event union. */\nexport interface ClaudeLikeStreamEvent {\n type: 'init' | 'text_delta' | 'thinking_delta' | 'done' | 'error';\n text?: string;\n fullText?: string;\n model?: string;\n sessionId?: string;\n costUsd?: number;\n durationMs?: number;\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n message?: string;\n recoverable?: boolean;\n}\n\nexport function fromClaudeStreamEvent(\n event: ClaudeLikeStreamEvent,\n ctx: NormalizeCtx,\n): AgentEvent[] {\n switch (event.type) {\n case 'init':\n return [\n {\n type: 'turn_start',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n model: event.model,\n provider: 'claude-bridge',\n sessionId: event.sessionId,\n },\n ];\n case 'text_delta':\n return event.text ? [{ type: 'text_delta', messageId: ctx.messageId, text: event.text }] : [];\n case 'thinking_delta':\n return event.text\n ? [{ type: 'thinking_delta', messageId: ctx.messageId, text: event.text }]\n : [];\n case 'done':\n return [\n {\n type: 'turn_end',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n result: {\n status: 'succeeded',\n text: event.fullText ?? '',\n provider: 'claude-bridge',\n model: event.model,\n usage: {\n inputTokens: event.inputTokens,\n outputTokens: event.outputTokens,\n cachedTokens: event.cacheReadTokens,\n costUsd: event.costUsd,\n durationMs: event.durationMs,\n model: event.model,\n },\n },\n },\n ];\n case 'error':\n return [\n {\n type: 'turn_end',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n result: {\n status: 'error',\n text: '',\n provider: 'claude-bridge',\n failure: {\n status: 'error',\n message: event.message ?? 'The agent failed.',\n recoverable: event.recoverable ?? false,\n },\n },\n },\n ];\n }\n}\n\n/** A NON-streaming Foundry reply (`certifications/ai-103/broker`'s `FoundryChatResult`). */\nexport interface FoundryLikeResult {\n text: string;\n promptTokens?: number;\n completionTokens?: number;\n model?: string;\n}\n\n/**\n * ★ Two events, no faked deltas. This is what `AgentTurnResult.text` exists for: a provider\n * with no streaming at all still produces a complete message through the same reducer.\n */\nexport function fromFoundryChatResult(\n result: FoundryLikeResult,\n ctx: NormalizeCtx,\n provider = 'foundry',\n): AgentEvent[] {\n return [\n { type: 'turn_start', turnId: ctx.turnId, messageId: ctx.messageId, model: result.model, provider },\n {\n type: 'turn_end',\n turnId: ctx.turnId,\n messageId: ctx.messageId,\n result: {\n status: 'succeeded',\n text: result.text,\n provider,\n model: result.model,\n usage: {\n inputTokens: result.promptTokens,\n outputTokens: result.completionTokens,\n model: result.model,\n },\n },\n },\n ];\n}\n","import type { ConversationState } from './conversationReducer';\n\n/** Past this many characters, announce a summary instead of the whole answer. */\nexport const ANNOUNCE_FULL_TEXT_MAX_CHARS = 240;\n\nexport interface Announcement {\n /** Read when the screen reader next pauses. Empty means \"nothing new\". */\n polite: string;\n /** Interrupts. Reserved for failures. */\n assertive: string;\n}\n\nexport const NO_ANNOUNCEMENT: Announcement = { polite: '', assertive: '' };\n\nconst TERMINAL = new Set(['succeeded', 'blocked', 'refused', 'error', 'notProvisioned', 'cancelled']);\n\n/**\n * What, if anything, should be announced for this state change.\n *\n * ★★ THE WHOLE POINT: this is derived from a state TRANSITION, never from a delta.\n *\n * Both naive choices are wrong. No live region at all and a screen-reader user never\n * hears the answer — the kit's primary output is silent. A live region on the streaming\n * node and every token is queued for announcement; NVDA and JAWS re-read the growing\n * string and never finish. So the transcript is NOT a live region, the streaming bubble\n * carries `aria-busy`, the typing indicator's own `role=\"status\"` covers \"responding\",\n * and this announces exactly once per turn: the settled answer.\n *\n * ★ Deltas, `thinking` and tool calls are never announced. Thinking especially: it is\n * explicitly the model's scratch work, and reading it aloud would bury the answer.\n *\n * ★ Failures go to the ASSERTIVE channel, because an error the user is not told about is\n * an error they wait through.\n */\nexport function deriveAnnouncement(\n state: ConversationState,\n previous: ConversationState | undefined,\n): Announcement {\n const wasTerminal = previous ? TERMINAL.has(previous.status) : false;\n const isTerminal = TERMINAL.has(state.status);\n\n // Only the moment of settling produces an announcement.\n if (!isTerminal || wasTerminal) return NO_ANNOUNCEMENT;\n\n if (state.failure) {\n return { polite: '', assertive: state.failure.message };\n }\n\n const last = state.messages[state.messages.length - 1];\n const text = last?.text ?? '';\n if (!text) return NO_ANNOUNCEMENT;\n\n const guarded = last?.guarded ? 'The response was withheld. ' : '';\n if (text.length <= ANNOUNCE_FULL_TEXT_MAX_CHARS) {\n return { polite: `${guarded}${text}`, assertive: '' };\n }\n const words = text.trim().split(/\\s+/).length;\n return {\n polite: `${guarded}Response complete, ${words} words.`,\n assertive: '',\n };\n}\n","/** How close to the bottom still counts as \"at the bottom\", in CSS pixels. */\nexport const STICK_TO_BOTTOM_THRESHOLD_PX = 32;\n\nexport interface ScrollGeometry {\n scrollTop: number;\n scrollHeight: number;\n clientHeight: number;\n}\n\n/**\n * Should an append scroll the transcript to the bottom?\n *\n * ★ The DECISION is extracted from the EFFECT on purpose. It is what lets a unit test\n * express \"the user scrolled up, so do not yank them back\" without a real scroller —\n * jsdom reports `scrollHeight`/`clientHeight` as 0 forever, so a test that drives a real\n * element can only ever observe \"at the bottom\" and the interesting branch never runs.\n *\n * ★ The rule itself carries a MEASURED defect forward. apps/form-builder's ChatPane once\n * keyed its scroll effect on the streaming message's content length, which queued a\n * smooth `scrollTo` per token — 10+ per second — and jittered the viewport. The fix there\n * was to key on message COUNT and use `behavior: 'auto'`. This adds the half that was\n * still missing: only stick if the reader was already at the bottom, so scrolling up to\n * re-read mid-stream is not undone.\n */\nexport function shouldStickToBottom(\n geometry: ScrollGeometry,\n thresholdPx: number = STICK_TO_BOTTOM_THRESHOLD_PX,\n): boolean {\n const { scrollTop, scrollHeight, clientHeight } = geometry;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n return distanceFromBottom <= thresholdPx;\n}\n","/**\n * Build a per-instance id-prefix generator.\n *\n * ★ The FACTORY is exported (pure, testable); the module SINGLETON that a provider uses\n * lives in src/host/idPrefix.ts. That split matters: the gallery's measurement is that\n * there must be exactly ONE counter per bundle, so two instances of the same control get\n * different prefixes. A constant prefix is the wrong fix and a per-call factory is too.\n */\nexport function createIdPrefixCounter(tag: string): () => string {\n let n = 0;\n return () => `${tag}${++n}-`;\n}\n","import * as React from 'react';\nimport { useVisuallyHiddenStyles } from './visuallyHidden';\n\nexport interface LiveAnnouncerProps {\n /** Read at the next pause. Changing this to a new non-empty value announces it. */\n polite?: string;\n /** Interrupts. Failures only. */\n assertive?: string;\n}\n\nfunction useAnnounceWithRepeat(\n next: string,\n set: React.Dispatch<React.SetStateAction<string>>,\n): void {\n React.useEffect(() => {\n if (!next) return;\n let cancelled = false;\n // Clear-then-set across two ticks. Screen readers SWALLOW a repeat: assigning a region\n // the text it already holds announces nothing, so two identical answers in a row would\n // be read once. Clearing first guarantees the region genuinely changes.\n set('');\n const id = setTimeout(() => {\n if (!cancelled) set(next);\n }, 0);\n return () => {\n cancelled = true;\n clearTimeout(id);\n };\n }, [next, set]);\n}\n\n/**\n * The two live regions for a conversation surface.\n *\n * ★ The transcript itself is NOT a live region, and that is the point. A live region on the\n * streaming node queues every token for announcement — NVDA and JAWS re-read the growing\n * string and never finish. The streaming bubble carries `aria-busy`, the typing indicator's\n * own `role=\"status\"` covers \"responding\", and this announces once per turn: the settled\n * answer (see `deriveAnnouncement` in ./core, which is where the rule lives).\n *\n * ★ `aria-atomic` so the whole message is read, not just the changed fragment.\n */\nexport function LiveAnnouncer({\n polite = '',\n assertive = '',\n}: LiveAnnouncerProps): React.ReactElement {\n const styles = useVisuallyHiddenStyles();\n const [politeText, setPoliteText] = React.useState('');\n const [assertiveText, setAssertiveText] = React.useState('');\n\n useAnnounceWithRepeat(polite, setPoliteText);\n useAnnounceWithRepeat(assertive, setAssertiveText);\n\n return (\n <>\n <div\n className={styles.root}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"agentkit-live-polite\"\n >\n {politeText}\n </div>\n <div\n className={styles.root}\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n data-testid=\"agentkit-live-assertive\"\n >\n {assertiveText}\n </div>\n </>\n );\n}\n","import { makeStyles } from '@fluentui/react-components';\n\n/**\n * Content available to assistive technology and not to sight.\n *\n * ★ NOT `display:none` and NOT `visibility:hidden` — both remove the node from the\n * accessibility tree, which is the opposite of the intent. The clip-rect recipe is the one\n * that keeps it announced.\n */\nexport const useVisuallyHiddenStyles = makeStyles({\n root: {\n position: 'absolute',\n width: '1px',\n height: '1px',\n margin: '-1px',\n padding: '0',\n overflow: 'hidden',\n clip: 'rect(0 0 0 0)',\n clipPath: 'inset(50%)',\n whiteSpace: 'nowrap',\n },\n});\n","import * as React from 'react';\n\n/**\n * Put focus somewhere sensible when the focused element disappears.\n *\n * ★ Fluent's tabster ships a `Restorer` and a `Deloser` for exactly this, and the kit needs\n * its own because the affordances that own focus in a transcript are the in-tree ones. A\n * chat surface removes focusable nodes constantly — a message is deleted, an approval card\n * resolves, a conversation closes. When that happens the browser puts focus on `<body>`:\n * the keyboard user's Tab position resets to the top of the page and the screen reader\n * loses its place.\n *\n * ★ It reads `document.activeElement` rather than tracking what it believes had focus,\n * because the interesting case is the one where focus has ALREADY been lost.\n */\nexport function useFocusRestore(containerRef: React.RefObject<HTMLElement>): () => void {\n return React.useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n // Only rescue focus that actually fell off. If it landed somewhere real, leave it alone.\n if (doc.activeElement && doc.activeElement !== doc.body) return;\n\n const focusable = container.querySelector<HTMLElement>(\n 'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])',\n );\n (focusable ?? container).focus();\n }, [containerRef]);\n}\n","import * as React from 'react';\n\nexport interface RovingTabindexOptions {\n orientation?: 'horizontal' | 'vertical';\n loop?: boolean;\n itemCount: number;\n onActivate?: (index: number) => void;\n}\n\nexport interface RovingTabindex {\n activeIndex: number;\n setActiveIndex: (index: number) => void;\n /** Spread onto each item. Exactly ONE item is tabbable at a time. */\n getItemProps: (index: number) => {\n tabIndex: 0 | -1;\n 'data-roving-item': true;\n onFocus: () => void;\n onKeyDown: (event: React.KeyboardEvent) => void;\n };\n}\n\n/**\n * One tab stop for a group, arrow keys within it — the WAI-ARIA roving tabindex.\n *\n * ★ Why this rather than Fluent's `Toolbar`: `react-toolbar` reaches\n * `useArrowNavigationGroup` → `getMover` → `core.attrHandlers.set`, which throws against a\n * Dynamics form's tabster (8.2.0, no `attrHandlers`) and unmounts the React tree. For a row\n * of buttons the ARIA pattern is ~40 lines, so this is the cheap side of the split-by-cost\n * decision; `TabList` and `Tree` are the expensive side and the kit uses Fluent's.\n *\n * ★ Without a roving index a transcript of 20 messages × 4 hover actions is 80 tab stops.\n */\nexport function useRovingTabindex(options: RovingTabindexOptions): RovingTabindex {\n const { orientation = 'horizontal', loop = true, itemCount, onActivate } = options;\n const [activeIndex, setActiveIndex] = React.useState(0);\n\n const clamp = React.useCallback(\n (index: number) => {\n if (itemCount === 0) return 0;\n return loop\n ? (index + itemCount) % itemCount\n : Math.min(Math.max(index, 0), itemCount - 1);\n },\n [itemCount, loop],\n );\n\n const getItemProps = React.useCallback(\n (index: number) => ({\n tabIndex: (index === activeIndex ? 0 : -1) as 0 | -1,\n 'data-roving-item': true as const,\n onFocus: () => setActiveIndex(index),\n onKeyDown: (event: React.KeyboardEvent) => {\n const prevKey = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n const nextKey = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n\n let target: number | null = null;\n if (event.key === nextKey) target = clamp(index + 1);\n else if (event.key === prevKey) target = clamp(index - 1);\n else if (event.key === 'Home') target = 0;\n else if (event.key === 'End') target = itemCount - 1;\n else if (event.key === 'Enter' || event.key === ' ') {\n onActivate?.(index);\n return;\n }\n if (target === null) return;\n\n event.preventDefault();\n event.stopPropagation();\n setActiveIndex(target);\n const group = (event.currentTarget as HTMLElement).parentElement;\n group?.querySelectorAll<HTMLElement>('[data-roving-item]')[target]?.focus();\n },\n }),\n [activeIndex, clamp, itemCount, onActivate, orientation],\n );\n\n return { activeIndex, setActiveIndex, getItemProps };\n}\n","import * as React from 'react';\n\nexport interface ReturnFocusOptions {\n /** When this goes true the surface is open; false returns focus to whatever opened it. */\n open: boolean;\n /** The surface. Focus moves to its first focusable node on open. */\n containerRef: React.RefObject<HTMLElement>;\n /** Skip moving focus IN on open. Focus is still returned on close. */\n manageInitialFocus?: boolean;\n}\n\n/**\n * Move focus into a surface when it opens, and put it back where it came from when it closes.\n *\n * ★★ THIS IS NOT A FOCUS TRAP, DELIBERATELY. A docked assistant drawer is NON-MODAL — the page\n * behind it stays readable and usable, which is the whole point of docking rather than\n * dialoging. Trapping focus in a surface that does not claim modality strands a keyboard user\n * with no way out, and the page carries no `aria-modal` or inert backdrop to justify it. A host\n * that genuinely wants modal behaviour should wrap in a real dialog and get the trap, the\n * backdrop and the `aria-modal` together rather than half of them here.\n *\n * ★★ THE OPENER IS CAPTURED ON THE OPENING TRANSITION, not on every render. Reading\n * `document.activeElement` at close time would return something inside the drawer — which is\n * exactly where focus is — so the return target has to be remembered before focus moves.\n *\n * ★ Returning focus is guarded on the element still being connected. A trigger can be unmounted\n * while the surface is open (a toolbar collapsing, a row removed); calling `.focus()` on a\n * detached node silently does nothing and leaves focus on `<body>`, so fall back to the body\n * check rather than pretending it worked.\n */\nexport function useReturnFocus({ open, containerRef, manageInitialFocus = true }: ReturnFocusOptions): void {\n const openerRef = React.useRef<HTMLElement | null>(null);\n const wasOpen = React.useRef(open);\n\n React.useEffect(() => {\n const container = containerRef.current;\n const doc = container?.ownerDocument ?? (typeof document !== 'undefined' ? document : undefined);\n if (!doc) return;\n\n // opening\n if (open && !wasOpen.current) {\n const active = doc.activeElement;\n openerRef.current = active instanceof HTMLElement && active !== doc.body ? active : null;\n if (manageInitialFocus && container) {\n const first = container.querySelector<HTMLElement>(\n 'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])',\n );\n (first ?? container).focus();\n }\n }\n\n // closing\n if (!open && wasOpen.current) {\n const opener = openerRef.current;\n if (opener && opener.isConnected) opener.focus();\n openerRef.current = null;\n }\n\n wasOpen.current = open;\n }, [open, containerRef, manageInitialFocus]);\n}\n","import * as React from 'react';\nimport { shouldStickToBottom } from '../core/scroll';\n\nexport interface StickyScroll {\n /** Put on the scrolling element. */\n onScroll: () => void;\n /** Call to jump to the bottom regardless (e.g. a \"jump to latest\" button). */\n scrollToBottom: () => void;\n /** False once the reader scrolls up — drives a \"jump to latest\" affordance. */\n isPinned: boolean;\n}\n\n/**\n * Keep a transcript pinned to the bottom — but only while the reader is already there.\n *\n * ★★ THIS CARRIES A MEASURED DEFECT FORWARD. apps/form-builder's ChatPane once keyed its\n * scroll effect on the streaming message's CONTENT LENGTH, which queued a smooth\n * `scrollTo` per token — often 10+ per second — and jittered the viewport. Its fix was to\n * key on message COUNT and use `behavior: 'auto'`; both are reproduced here.\n *\n * ★★ AND IT ADDS THE HALF THAT WAS STILL MISSING. Sticking unconditionally means a reader who\n * scrolls up to re-read something mid-stream is yanked back to the bottom on the next\n * append. `wasPinnedRef` is sampled from SCROLL EVENTS, so it reflects where the reader\n * was before the append, not after.\n *\n * ★ `behavior: 'auto'`, never `'smooth'`: a queued smooth scroll is what produced the\n * jitter, and an involuntary animation is a WCAG 2.2.2 hazard besides.\n */\nexport function useStickyScroll(\n ref: React.RefObject<HTMLElement>,\n messageCount: number,\n): StickyScroll {\n const wasPinnedRef = React.useRef(true);\n const [isPinned, setIsPinned] = React.useState(true);\n\n const onScroll = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const pinned = shouldStickToBottom({\n scrollTop: el.scrollTop,\n scrollHeight: el.scrollHeight,\n clientHeight: el.clientHeight,\n });\n wasPinnedRef.current = pinned;\n setIsPinned(pinned);\n }, [ref]);\n\n const scrollToBottom = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n el.scrollTo({ top: el.scrollHeight, behavior: 'auto' });\n wasPinnedRef.current = true;\n setIsPinned(true);\n }, [ref]);\n\n React.useEffect(() => {\n if (!wasPinnedRef.current) return;\n const el = ref.current;\n if (!el) return;\n el.scrollTo({ top: el.scrollHeight, behavior: 'auto' });\n // ★ messageCount ONLY. Adding the streaming text here is the original defect.\n }, [messageCount, ref]);\n\n return { onScroll, scrollToBottom, isPinned };\n}\n","import * as React from 'react';\nimport {\n applyAgentEvent,\n appendUserMessage,\n deriveAnnouncement,\n initialConversation,\n NO_ANNOUNCEMENT,\n type Announcement,\n type AgentAttachment,\n type AgentMessage,\n type ConversationState,\n type IAgentService,\n} from '../core';\n\nexport interface UseConversationOptions {\n service: IAgentService;\n seed?: readonly AgentMessage[];\n grounding?: Record<string, unknown>;\n conversationId?: string;\n /** Ids are injected so tests and Storybook are deterministic. */\n createId?: () => string;\n}\n\nexport interface Conversation {\n state: ConversationState;\n announcement: Announcement;\n busy: boolean;\n send: (text: string, attachments?: AgentAttachment[]) => Promise<void>;\n cancel: () => void;\n}\n\nlet fallbackId = 0;\n\n/**\n * Drive an `IAgentService` into a `ConversationState`.\n *\n * ★ The reducer and the announcement rule are both PURE and live in ./core — this hook only\n * owns the effectful parts: the abort controller, the iteration, and holding the previous\n * state so a transition can be detected. That split is what lets the interesting rules be\n * tested without a DOM.\n *\n * ★ `send()` NEVER throws. A transport that throws mid-stream (which an AsyncIterable can do,\n * and a Promise-shaped seam cannot) is converted into terminal state, because the\n * alternative is an unmounted tree — the React-layer analogue of the tabster crash.\n */\nexport function useConversation(options: UseConversationOptions): Conversation {\n const { service, seed, grounding, conversationId, createId } = options;\n const [state, setState] = React.useState<ConversationState>(() => initialConversation(seed));\n const [announcement, setAnnouncement] = React.useState<Announcement>(NO_ANNOUNCEMENT);\n const abortRef = React.useRef<AbortController | null>(null);\n const stateRef = React.useRef(state);\n stateRef.current = state;\n\n const nextId = React.useCallback(\n () => createId?.() ?? `m${++fallbackId}-${Date.now().toString(36)}`,\n [createId],\n );\n\n const commit = React.useCallback((next: ConversationState) => {\n const previous = stateRef.current;\n stateRef.current = next;\n setState(next);\n const derived = deriveAnnouncement(next, previous);\n if (derived.polite || derived.assertive) setAnnouncement(derived);\n }, []);\n\n const cancel = React.useCallback(() => {\n abortRef.current?.abort();\n }, []);\n\n const send = React.useCallback(\n async (text: string, attachments?: AgentAttachment[]) => {\n if (!text.trim()) return;\n // Abort any in-flight turn before starting another, or the previous iterator keeps\n // running and both write into the same state.\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n let next = appendUserMessage(stateRef.current, { id: nextId(), text, attachments });\n commit(next);\n\n try {\n for await (const event of service.send({\n text,\n history: next.messages,\n grounding,\n attachments,\n conversationId,\n cancelSignal: controller.signal,\n })) {\n next = applyAgentEvent(next, event);\n commit(next);\n }\n } catch (error) {\n commit({\n ...next,\n streamingMessageId: null,\n status: 'error',\n failure: {\n status: 'error',\n message: error instanceof Error ? error.message : String(error),\n recoverable: true,\n },\n });\n } finally {\n if (abortRef.current === controller) abortRef.current = null;\n }\n },\n [service, grounding, conversationId, nextId, commit],\n );\n\n React.useEffect(() => () => abortRef.current?.abort(), []);\n\n const busy = state.status === 'connecting' || state.status === 'streaming';\n return { state, announcement, busy, send, cancel };\n}\n","import * as React from 'react';\nimport { Avatar, makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { AgentMessage, AgentParticipant } from '../core';\nimport { useVisuallyHiddenStyles } from '../a11y';\nimport { StreamingText } from './StreamingText';\nimport { MessageActions, type MessageActionsProps } from './MessageActions';\n\nexport interface MessageBubbleProps extends Omit<MessageActionsProps, 'message'> {\n message: AgentMessage;\n author?: AgentParticipant;\n /** First message of a run — renders the avatar and name. */\n isRunStart?: boolean;\n locale?: string;\n}\n\nconst useStyles = makeStyles({\n row: {\n display: 'flex',\n gap: tokens.spacingHorizontalS,\n position: 'relative',\n paddingRight: tokens.spacingHorizontalXXL,\n },\n own: { flexDirection: 'row-reverse', paddingRight: 0, paddingLeft: tokens.spacingHorizontalXXL },\n gutter: { width: '32px', flexShrink: 0 },\n stack: { display: 'flex', flexDirection: 'column', gap: '2px', minWidth: 0, maxWidth: '80%' },\n name: { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 },\n bubble: {\n padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalM}`,\n borderRadius: tokens.borderRadiusLarge,\n backgroundColor: tokens.colorNeutralBackground3,\n color: tokens.colorNeutralForeground1,\n fontSize: tokens.fontSizeBase300,\n },\n ownBubble: {\n backgroundColor: tokens.colorBrandBackground,\n color: tokens.colorNeutralForegroundOnBrand,\n },\n actions: {\n position: 'absolute',\n top: '-12px',\n right: tokens.spacingHorizontalS,\n opacity: 0,\n pointerEvents: 'none',\n transitionProperty: 'opacity',\n transitionDuration: tokens.durationFaster,\n },\n // ★ hover OR focus-within. Without the second selector the row is unreachable by keyboard.\n actionsVisible: { opacity: 1, pointerEvents: 'auto' },\n});\n\nexport function MessageBubble(props: MessageBubbleProps): React.ReactElement {\n const { message, author, isRunStart = true, locale, ...actionHandlers } = props;\n const styles = useStyles();\n const hidden = useVisuallyHiddenStyles();\n const [revealed, setRevealed] = React.useState(false);\n\n const own = message.role === 'user';\n const name = author?.displayName ?? (own ? 'You' : (message.provider ?? 'Assistant'));\n const time = new Intl.DateTimeFormat(locale, { timeStyle: 'short' }).format(new Date(message.createdAt));\n\n return (\n <div\n className={mergeClasses(styles.row, own && styles.own)}\n onMouseEnter={() => setRevealed(true)}\n onMouseLeave={() => setRevealed(false)}\n onFocus={() => setRevealed(true)}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setRevealed(false);\n }}\n data-testid=\"agentkit-message\"\n >\n <div className={styles.gutter}>\n {isRunStart ? <Avatar name={name} size={32} image={author?.imageUrl ? { src: author.imageUrl } : undefined} /> : null}\n </div>\n\n <div className={styles.stack}>\n {/* ★ The author and timestamp are ALWAYS in the accessible tree, even on a grouped\n continuation where they are visually suppressed. Grouping is a visual affordance;\n a screen reader navigating message-by-message would otherwise hear nothing\n identifying messages 2..N of a run — in a UI whose entire point is the distinction\n between what the user said and what the model said. */}\n <span className={hidden.root}>\n {name}, <time dateTime={new Date(message.createdAt).toISOString()}>{time}</time>\n </span>\n\n {isRunStart ? (\n <span className={styles.name} aria-hidden=\"true\">\n {name} · {time}\n </span>\n ) : null}\n\n <div\n className={mergeClasses(styles.bubble, own && styles.ownBubble)}\n // ★ Tells a screen reader the answer is still arriving, WITHOUT making the\n // transcript a live region — see a11y/LiveAnnouncer.\n aria-busy={message.streaming || undefined}\n >\n <StreamingText text={message.text} streaming={message.streaming} />\n </div>\n </div>\n\n <div className={mergeClasses(styles.actions, revealed && styles.actionsVisible)}>\n <MessageActions message={message} {...actionHandlers} />\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface StreamingTextProps {\n text: string;\n streaming?: boolean;\n}\n\nconst useStyles = makeStyles({\n root: { whiteSpace: 'pre-wrap', wordBreak: 'break-word' },\n caret: {\n display: 'inline-block',\n width: '2px',\n height: '1em',\n marginLeft: '2px',\n verticalAlign: 'text-bottom',\n backgroundColor: tokens.colorBrandForeground1,\n animationName: { '0%,49%': { opacity: 1 }, '50%,100%': { opacity: 0 } },\n animationDuration: '1s',\n animationIterationCount: 'infinite',\n // WCAG 2.2.2: a blinking caret is motion, and some readers cannot tolerate it.\n '@media (prefers-reduced-motion: reduce)': { animationName: 'none', opacity: 1 },\n },\n});\n\n/**\n * The in-flight answer.\n *\n * ★ A STABLE element, deliberately. If this subtree remounted per token, any focus inside the\n * streaming bubble (a citation chip, a copy button) would be thrown to `<body>` mid-answer.\n * Only the text node changes; the element identity does not. `useStreamingText.test.tsx`\n * pins that as an invariant rather than leaving it to a comment.\n */\nexport function StreamingText({ text, streaming }: StreamingTextProps): React.ReactElement {\n const styles = useStyles();\n return (\n <span className={styles.root} data-testid=\"agentkit-streaming-text\">\n {text}\n {streaming ? <span className={styles.caret} aria-hidden=\"true\" /> : null}\n </span>\n );\n}\n","import * as React from 'react';\nimport { CopyRegular, ArrowClockwiseRegular, ThumbLikeRegular, ThumbDislikeRegular } from '@fluentui/react-icons';\nimport { ActionToolbar, type ToolbarAction } from '../internal';\nimport type { AgentMessage } from '../core';\n\nexport interface MessageActionsProps {\n message: AgentMessage;\n onCopy?: (message: AgentMessage) => void;\n onRetry?: (message: AgentMessage) => void;\n onFeedback?: (message: AgentMessage, vote: 'up' | 'down') => void;\n}\n\n/**\n * The hover row on a message.\n *\n * ★★ It is revealed by `:hover` **or `:focus-within`** — see MessageBubble's styles. A\n * hover-only affordance is a WCAG 2.1.1 (Keyboard, Level A) failure outright: there is no\n * pointer-free route to it at all. The other naive choice, leaving the row permanently in\n * the tab order, adds N tab stops per message. Reveal-on-focus plus a roving tabindex gives\n * exactly one tab stop per message and a keyboard route to every action.\n */\nexport function MessageActions({\n message,\n onCopy,\n onRetry,\n onFeedback,\n}: MessageActionsProps): React.ReactElement | null {\n const actions: ToolbarAction[] = [];\n if (onCopy) {\n actions.push({ key: 'copy', label: 'Copy message', icon: <CopyRegular />, onClick: () => onCopy(message) });\n }\n if (onRetry && message.role === 'assistant') {\n actions.push({ key: 'retry', label: 'Regenerate', icon: <ArrowClockwiseRegular />, onClick: () => onRetry(message) });\n }\n if (onFeedback && message.role === 'assistant') {\n actions.push(\n { key: 'up', label: 'Good response', icon: <ThumbLikeRegular />, onClick: () => onFeedback(message, 'up') },\n { key: 'down', label: 'Bad response', icon: <ThumbDislikeRegular />, onClick: () => onFeedback(message, 'down') },\n );\n }\n if (actions.length === 0) return null;\n\n return <ActionToolbar actions={actions} label={`Actions for this message`} />;\n}\n","import * as React from 'react';\nimport { Button, Tooltip, makeStyles, tokens, mergeClasses } from '@fluentui/react-components';\nimport { useRovingTabindex } from '../a11y/useRovingTabindex';\n\nexport interface ToolbarAction {\n key: string;\n label: string;\n icon: React.ReactElement;\n onClick: () => void;\n disabled?: boolean;\n}\n\nexport interface ActionToolbarProps {\n actions: ToolbarAction[];\n label: string;\n className?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'inline-flex',\n gap: tokens.spacingHorizontalXXS,\n alignItems: 'center',\n backgroundColor: tokens.colorNeutralBackground1,\n borderRadius: tokens.borderRadiusMedium,\n boxShadow: tokens.shadow4,\n padding: tokens.spacingHorizontalXXS,\n },\n button: {\n // ★ A focus ring that survives Windows forced-colors. Once the kit owns its own focus\n // management it owns the indicator too, and `outline: none` + box-shadow — the usual\n // custom-focus recipe — disappears entirely under forced-colors.\n ':focus-visible': {\n outline: `2px solid ${tokens.colorStrokeFocus2}`,\n outlineOffset: '1px',\n },\n },\n});\n\n/**\n * The in-tree replacement for Fluent's `Toolbar`.\n *\n * ★ Fluent's reaches `useArrowNavigationGroup` → `getMover` → `core.attrHandlers.set`, which\n * throws against a Dynamics form's tabster and unmounts the tree. For a row of buttons the\n * WAI-ARIA pattern is small enough to own, which is why this is on the in-tree side of the\n * split while `TabList` and `Tree` are not.\n *\n * ★ ONE tab stop for the whole row (roving tabindex), not one per button. A transcript of 20\n * messages × 4 actions would otherwise add 80 tab stops between the reader and the composer.\n */\nexport function ActionToolbar({ actions, label, className }: ActionToolbarProps): React.ReactElement {\n const styles = useStyles();\n const roving = useRovingTabindex({ itemCount: actions.length, orientation: 'horizontal' });\n\n return (\n <div role=\"toolbar\" aria-label={label} aria-orientation=\"horizontal\" className={mergeClasses(styles.root, className)}>\n {actions.map((action, index) => {\n const item = roving.getItemProps(index);\n return (\n <Tooltip key={action.key} content={action.label} relationship=\"label\" withArrow>\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={action.icon}\n disabled={action.disabled}\n onClick={action.onClick}\n className={styles.button}\n {...item}\n />\n </Tooltip>\n );\n })}\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\n\nexport interface CardSurfaceProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Renders a highlighted edge — used by ApprovalCard while a decision is pending. */\n emphasis?: 'none' | 'attention';\n children?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: tokens.spacingVerticalXS,\n padding: tokens.spacingVerticalM,\n borderRadius: tokens.borderRadiusMedium,\n backgroundColor: tokens.colorNeutralBackground1,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n boxShadow: tokens.shadow2,\n },\n attention: { borderLeft: `3px solid ${tokens.colorBrandStroke1}` },\n});\n\n/**\n * The in-tree replacement for Fluent's `Card`.\n *\n * ★★ Fluent's `Card` calls `useFocusableGroup()` UNCONDITIONALLY — `react-card/useCard.js:66`,\n * a hook call, so the `shouldApplyFocusAttributes` guard below it only decides whether the\n * ATTRIBUTES are applied, not whether the hook runs. That reaches `getGroupper` and\n * `core.attrHandlers.set`, which throws against a Dynamics form's tabster (8.2.0, no\n * `attrHandlers`) and unmounts the whole React tree.\n *\n * ★★ It is also the single easiest thing in this kit to get wrong: `Card` is the obvious\n * import for anything card-shaped, the estate's closest existing v9 chat component wraps\n * its ENTIRE surface in one, and the canonical grep in the PCF standard\n * (`useArrowNavigationGroup|useModalAttributes|useRestoreFocus`) does not find `react-card`\n * because it omits `useFocusableGroup`. eslint bans `Card` by name outside this directory.\n *\n * ★ What is lost is Groupper's \"card is one tab stop, Enter to enter, Escape to exit\". The\n * cards here hold at most a couple of buttons, so the plain tab order is correct and\n * cheaper; if a card ever holds many controls, revisit rather than reaching for `Card`.\n */\nexport const CardSurface = React.forwardRef<HTMLDivElement, CardSurfaceProps>(\n function CardSurface({ emphasis = 'none', className, children, ...rest }, ref) {\n const styles = useStyles();\n return (\n <div\n ref={ref}\n className={mergeClasses(styles.root, emphasis === 'attention' && styles.attention, className)}\n {...rest}\n >\n {children}\n </div>\n );\n },\n);\n","import * as React from 'react';\nimport { Button, makeStyles, tokens, Text } from '@fluentui/react-components';\nimport { CardSurface } from './CardSurface';\n\nexport interface ConfirmInlineProps {\n open: boolean;\n title: string;\n body: React.ReactNode;\n confirmLabel?: string;\n cancelLabel?: string;\n destructive?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nconst useStyles = makeStyles({\n root: { maxWidth: '420px' },\n actions: { display: 'flex', gap: tokens.spacingHorizontalS, justifyContent: 'flex-end', marginTop: tokens.spacingVerticalS },\n});\n\nconst FOCUSABLE =\n 'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * An in-tree confirmation, replacing Fluent's `Dialog`.\n *\n * ★ `react-dialog` reaches `useModalAttributes` → `getModalizer` + `getRestorer` →\n * `core.attrHandlers.set`. The gallery's `image-gallery-field` removed `Dialog` for exactly\n * this and cut its bundle 431,706 → 317,346 bytes, so the trade is well established.\n *\n * ★★ BUT THAT PRECEDENT SHIPS THREE FOCUS DEFECTS, AND THIS FIXES THEM. Read against it:\n * it focuses into the dialog and handles Escape, but it (1) never returns focus to the\n * trigger on close, (2) has no focus trap, so Tab walks straight out of a `role=\"alertdialog\"`,\n * and (3) omits `aria-modal` — so the role asserts a modality the implementation does not\n * provide, which is an ARIA lie rather than a missing nicety. Removing tabster means\n * removing its Modalizer and Restorer, and whatever they were doing has to be done here.\n */\nexport function ConfirmInline(props: ConfirmInlineProps): React.ReactElement | null {\n const { open, title, body, confirmLabel = 'Confirm', cancelLabel = 'Cancel', destructive, onConfirm, onCancel } = props;\n const styles = useStyles();\n const ref = React.useRef<HTMLDivElement>(null);\n const returnTo = React.useRef<HTMLElement | null>(null);\n const titleId = React.useId();\n const bodyId = React.useId();\n\n // (1) Remember where focus came from, and put it back. Without this the keyboard user is\n // returned to <body> — the top of the page — every time they cancel.\n React.useEffect(() => {\n if (!open) return;\n returnTo.current = (document.activeElement as HTMLElement | null) ?? null;\n const first = ref.current?.querySelector<HTMLElement>(FOCUSABLE);\n first?.focus();\n return () => {\n const target = returnTo.current;\n if (target && target.isConnected) target.focus();\n };\n }, [open]);\n\n if (!open) return null;\n\n // (2) The trap. A `role=\"alertdialog\"` that Tab can leave is announcing something untrue.\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onCancel();\n return;\n }\n if (event.key !== 'Tab') return;\n const items = [...(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])];\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n return (\n <CardSurface\n ref={ref}\n role=\"alertdialog\"\n // (3) The role without this is a claim the implementation does not honour.\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={bodyId}\n onKeyDown={onKeyDown}\n className={styles.root}\n emphasis=\"attention\"\n >\n <Text id={titleId} weight=\"semibold\">\n {title}\n </Text>\n <Text id={bodyId} size={200}>\n {body}\n </Text>\n <div className={styles.actions}>\n <Button size=\"small\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n <Button size=\"small\" appearance={destructive ? 'primary' : 'primary'} onClick={onConfirm}>\n {confirmLabel}\n </Button>\n </div>\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, mergeClasses } from '@fluentui/react-components';\nimport { ChevronRightRegular, ChevronDownRegular } from '@fluentui/react-icons';\n\nexport interface DisclosureProps {\n id: string;\n summary: React.ReactNode;\n children: React.ReactNode;\n defaultOpen?: boolean;\n className?: string;\n}\n\nconst useStyles = makeStyles({\n trigger: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalXS,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: `${tokens.spacingVerticalXXS} 0`,\n color: tokens.colorNeutralForeground2,\n font: 'inherit',\n fontSize: tokens.fontSizeBase200,\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '1px' },\n },\n panel: { paddingTop: tokens.spacingVerticalXS },\n});\n\n/**\n * The in-tree replacement for Fluent's `Accordion`.\n *\n * ★ APG's Disclosure pattern really is just `<button aria-expanded aria-controls>` plus a\n * labelled region — there is nothing else to it. `Accordion` adds arrow navigation between\n * headers, which a citation list or a trace does not need, and reaches\n * `useArrowNavigationGroup` to provide it. So this is the cheap side of the split.\n */\nexport function Disclosure({\n id,\n summary,\n children,\n defaultOpen = false,\n className,\n}: DisclosureProps): React.ReactElement {\n const styles = useStyles();\n const [open, setOpen] = React.useState(defaultOpen);\n const panelId = `${id}-panel`;\n\n return (\n <div className={className}>\n <button\n type=\"button\"\n id={id}\n className={styles.trigger}\n aria-expanded={open}\n aria-controls={panelId}\n onClick={() => setOpen((v) => !v)}\n >\n {open ? <ChevronDownRegular /> : <ChevronRightRegular />}\n {summary}\n </button>\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={id}\n hidden={!open}\n className={mergeClasses(styles.panel)}\n >\n {open ? children : null}\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport type { DayDividerLabel } from '../core';\n\nexport interface DayDividerProps {\n label: DayDividerLabel;\n locale?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalM,\n margin: `${tokens.spacingVerticalM} 0`,\n color: tokens.colorNeutralForeground3,\n fontSize: tokens.fontSizeBase200,\n },\n rule: { flex: 1, height: '1px', backgroundColor: tokens.colorNeutralStroke2 },\n});\n\n/** Map the pure descriptor to words. ★ The formatting lives HERE, not in ./core, so the host\n * can localise it and so the core function stays deterministic across CI locales. */\nexport function formatDayLabel(label: DayDividerLabel, locale?: string): string {\n switch (label.kind) {\n case 'today':\n return 'Today';\n case 'yesterday':\n return 'Yesterday';\n case 'weekday':\n return new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: 'UTC' }).format(\n new Date(`${label.iso}T00:00:00Z`),\n );\n case 'date':\n return new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeZone: 'UTC' }).format(\n new Date(`${label.iso}T00:00:00Z`),\n );\n }\n}\n\n/** ★ `role=\"separator\"` with an accessible name. A bare text node floating between list items\n * reads as a message. */\nexport function DayDivider({ label, locale }: DayDividerProps): React.ReactElement {\n const styles = useStyles();\n const text = formatDayLabel(label, locale);\n return (\n <div className={styles.root} role=\"separator\" aria-label={text}>\n <span className={styles.rule} aria-hidden=\"true\" />\n <span>{text}</span>\n <span className={styles.rule} aria-hidden=\"true\" />\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface TypingIndicatorProps {\n /** Announced. Keep it short — it interrupts nothing but is read on appearance. */\n label?: string;\n}\n\nconst useStyles = makeStyles({\n root: { display: 'inline-flex', gap: '4px', alignItems: 'center', padding: tokens.spacingVerticalXS },\n dot: {\n width: '6px',\n height: '6px',\n borderRadius: tokens.borderRadiusCircular,\n backgroundColor: tokens.colorNeutralForeground3,\n animationName: { '0%,80%,100%': { opacity: 0.3 }, '40%': { opacity: 1 } },\n animationDuration: '1.4s',\n animationIterationCount: 'infinite',\n '@media (prefers-reduced-motion: reduce)': { animationName: 'none', opacity: 0.6 },\n },\n d2: { animationDelay: '0.2s' },\n d3: { animationDelay: '0.4s' },\n});\n\n/**\n * ★ This carries \"the assistant is responding\" for screen readers, via its own `role=\"status\"`\n * firing when it MOUNTS. That is why `deriveAnnouncement` does not also announce the start —\n * doing both would say it twice.\n */\nexport function TypingIndicator({ label = 'Assistant is responding' }: TypingIndicatorProps): React.ReactElement {\n const styles = useStyles();\n return (\n <div className={styles.root} role=\"status\" aria-label={label} data-testid=\"agentkit-typing\">\n <span className={styles.dot} aria-hidden=\"true\" />\n <span className={`${styles.dot} ${styles.d2}`} aria-hidden=\"true\" />\n <span className={`${styles.dot} ${styles.d3}`} aria-hidden=\"true\" />\n </div>\n );\n}\n","import * as React from 'react';\nimport { Button, Textarea, makeStyles, mergeClasses, tokens, Tooltip } from '@fluentui/react-components';\nimport { SendRegular, StopRegular } from '@fluentui/react-icons';\nimport { useVisuallyHiddenStyles } from '../a11y/visuallyHidden';\n\nexport interface ComposerProps {\n value: string;\n onChange: (value: string) => void;\n onSend: (value: string) => void;\n onStop?: () => void;\n busy?: boolean;\n disabled?: boolean;\n placeholder?: string;\n maxLength?: number;\n /** 'enter' sends on Enter; 'mod+enter' needs Ctrl/Cmd. */\n sendOn?: 'enter' | 'mod+enter';\n /** Rendered inside the box, left of the send button — attachments, formatting, emoji. */\n toolbar?: React.ReactNode;\n}\n\n/** Hard-newline rows the field grows to before it starts scrolling. */\nconst MAX_ROWS = 6;\n\nconst useStyles = makeStyles({\n wrapper: {\n padding: tokens.spacingVerticalS,\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n // The Teams send box: ONE rounded container holding the field and the affordances.\n box: {\n display: 'flex',\n alignItems: 'flex-end',\n gap: tokens.spacingHorizontalXXS,\n paddingLeft: tokens.spacingHorizontalS,\n paddingRight: tokens.spacingHorizontalXXS,\n paddingTop: tokens.spacingVerticalXXS,\n paddingBottom: tokens.spacingVerticalXXS,\n borderRadius: tokens.borderRadiusXLarge,\n border: `1px solid ${tokens.colorNeutralStroke1}`,\n backgroundColor: tokens.colorNeutralBackground1,\n // ★ The ring moves to the CONTAINER because the field's own indicator is suppressed below.\n // It is an `outline`, not a box-shadow, so forced-colors still paints it (a11y rule 5).\n ':focus-within': {\n border: `1px solid ${tokens.colorCompoundBrandStroke}`,\n outline: `2px solid ${tokens.colorCompoundBrandStroke}`,\n outlineOffset: '-1px',\n },\n },\n boxDisabled: {\n backgroundColor: tokens.colorNeutralBackgroundDisabled,\n border: `1px solid ${tokens.colorNeutralStrokeDisabled}`,\n },\n // Fluent's Textarea has no transparent appearance, so its chrome is removed here and the\n // container above supplies it. `::after` is Fluent's focus underline.\n field: {\n flexGrow: 1,\n minWidth: 0,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: 0,\n '::after': { display: 'none' },\n },\n fieldInner: {\n backgroundColor: 'transparent',\n // ★ Fluent's Textarea ships `min-height: 52px` (measured). The affordance buttons are 32px,\n // so the default left the placeholder on one line and the icons on another — the single\n // visible difference from the Teams reference. Matching the button height puts them on\n // one baseline; growth past one row is then driven by `rows`, up to maxHeight.\n minHeight: '32px',\n maxHeight: '160px',\n paddingLeft: 0,\n paddingRight: 0,\n },\n actions: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalXXS,\n // ★ No extra bottom padding: `alignItems: flex-end` on the box already pins this row to the\n // field's last line, and padding on top of it pushed the send glyph visibly below the\n // baseline on a single-row box (measured against the Teams reference).\n },\n divider: {\n width: '1px',\n alignSelf: 'center',\n height: '20px',\n marginLeft: tokens.spacingHorizontalXXS,\n marginRight: tokens.spacingHorizontalXXS,\n backgroundColor: tokens.colorNeutralStroke2,\n },\n});\n\n/**\n * The send box, shaped like the Teams composer: one rounded container holding a borderless\n * field, the host's affordances, and the send button behind a divider.\n *\n * ★ `sendOn` is configurable, and defaults to Enter only because that is what users expect\n * from Teams. Enter-to-send in a multiline field is hostile to dictation and voice control,\n * and Shift+Enter is undiscoverable — hence the `aria-describedby` hint. The hint is\n * VISUALLY HIDDEN, not removed: Teams does not print it, but a screen-reader user has no\n * other way to learn the contract.\n *\n * ★ Growth is by HARD NEWLINE only, to `MAX_ROWS`, then the field scrolls. It does not grow on\n * soft wrap — that needs measurement, and a ResizeObserver here would be untestable in jsdom\n * (a stubbed one never fires). Stated rather than implied, because Teams does grow on wrap.\n *\n * ★ Deliberately NOT Fluent's `Toolbar` for the affordance row: it reaches\n * `useArrowNavigationGroup`. Consumers pass plain buttons, or the in-tree ActionToolbar.\n * The kit ships no emoji/GIF/format pickers — those are host concerns; `toolbar` is the slot.\n */\nexport function Composer(props: ComposerProps): React.ReactElement {\n const {\n value, onChange, onSend, onStop, busy = false, disabled = false,\n placeholder = 'Type a message', maxLength, sendOn = 'enter', toolbar,\n } = props;\n const styles = useStyles();\n const vh = useVisuallyHiddenStyles();\n const hintId = React.useId();\n\n const submit = () => {\n const text = value.trim();\n if (!text || busy || disabled) return;\n onSend(text);\n };\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key !== 'Enter') return;\n const wants = sendOn === 'enter' ? !event.shiftKey : event.metaKey || event.ctrlKey;\n if (!wants) return;\n event.preventDefault();\n submit();\n };\n\n const hint = sendOn === 'enter'\n ? 'Press Enter to send, Shift plus Enter for a new line.'\n : 'Press Control or Command plus Enter to send.';\n\n const rows = Math.min(MAX_ROWS, Math.max(1, value.split('\\n').length));\n\n return (\n <div className={styles.wrapper}>\n <div className={mergeClasses(styles.box, disabled && styles.boxDisabled)}>\n <Textarea\n className={styles.field}\n value={value}\n onChange={(_, data) => onChange(data.value)}\n onKeyDown={onKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n maxLength={maxLength}\n resize=\"none\"\n appearance=\"outline\"\n aria-label={placeholder}\n aria-describedby={hintId}\n textarea={{ 'aria-multiline': true, rows, className: styles.fieldInner }}\n />\n <div className={styles.actions}>\n {toolbar}\n {toolbar ? <span className={styles.divider} aria-hidden=\"true\" /> : null}\n {busy && onStop ? (\n <Tooltip content=\"Stop generating\" relationship=\"label\" withArrow>\n <Button appearance=\"subtle\" icon={<StopRegular />} onClick={onStop} />\n </Tooltip>\n ) : (\n <Tooltip content=\"Send\" relationship=\"label\" withArrow>\n <Button\n appearance=\"subtle\"\n icon={<SendRegular />}\n onClick={submit}\n disabled={!value.trim() || busy || disabled}\n />\n </Tooltip>\n )}\n </div>\n </div>\n <span id={hintId} className={vh.root}>{hint}</span>\n </div>\n );\n}\n","import * as React from 'react';\nimport { Button, makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\n\nexport interface SuggestedPromptsProps {\n prompts: readonly string[];\n onPick: (prompt: string) => void;\n heading?: string;\n /**\n * Row alignment. Defaults to `'start'`, which is right above a composer where the chips read as\n * a continuation of the transcript. `'center'` is for a centred zero state — see\n * `EmptyConversation`, where left-packed chips under a centred heading looked like a defect.\n */\n align?: 'start' | 'center';\n}\n\nconst useStyles = makeStyles({\n root: { display: 'flex', flexWrap: 'wrap', gap: tokens.spacingHorizontalXS, padding: tokens.spacingVerticalXS },\n // ★ The heading is `width: 100%`, so it takes the PARENT's text-align while the chips take the\n // flex row's justification. That split is why the label could look centred while the chips\n // stayed left-packed — the two are aligned by different mechanisms and must both be set.\n center: { justifyContent: 'center' },\n headingCenter: { textAlign: 'center' },\n heading: { width: '100%', fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 },\n});\n\n/** ★ Plain Buttons in a labelled list, not Fluent's `TagGroup` — `react-tags` reaches\n * `useArrowNavigationGroup`, and chips gain nothing from it here. */\nexport function SuggestedPrompts({\n prompts,\n onPick,\n heading = 'Suggested follow-ups',\n align = 'start',\n}: SuggestedPromptsProps): React.ReactElement | null {\n const styles = useStyles();\n if (prompts.length === 0) return null;\n const centered = align === 'center';\n return (\n <div\n className={mergeClasses(styles.root, centered && styles.center)}\n role=\"group\"\n aria-label={heading}\n >\n <span className={mergeClasses(styles.heading, centered && styles.headingCenter)}>{heading}</span>\n {prompts.map((prompt) => (\n <Button key={prompt} size=\"small\" appearance=\"outline\" onClick={() => onPick(prompt)}>\n {prompt}\n </Button>\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport { SuggestedPrompts } from './SuggestedPrompts';\n\nexport interface EmptyConversationProps {\n title?: string;\n description?: string;\n prompts?: readonly string[];\n onPick?: (prompt: string) => void;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: tokens.spacingVerticalS,\n height: '100%',\n padding: tokens.spacingVerticalXXL,\n textAlign: 'center',\n color: tokens.colorNeutralForeground3,\n },\n});\n\nexport function EmptyConversation({\n title = 'Ask the agent',\n description = 'It answers from the records you have open.',\n prompts = [],\n onPick,\n}: EmptyConversationProps): React.ReactElement {\n const styles = useStyles();\n return (\n <div className={styles.root}>\n <Text as=\"h2\" size={500} weight=\"semibold\">\n {title}\n </Text>\n <Text>{description}</Text>\n {onPick && prompts.length > 0 ? (\n <SuggestedPrompts prompts={prompts} onPick={onPick} heading=\"Try one of these\" align=\"center\" />\n ) : null}\n </div>\n );\n}\n","import * as React from 'react';\nimport {\n MessageBar,\n MessageBarBody,\n MessageBarTitle,\n MessageBarActions,\n Button,\n} from '@fluentui/react-components';\nimport type { AgentFailure } from '../core';\nimport { runStatusSeverity } from '../core';\n\nexport interface SystemNoticeProps {\n failure?: AgentFailure;\n guarded?: boolean;\n onRetry?: () => void;\n}\n\nconst INTENT = { success: 'success', warning: 'warning', error: 'error', info: 'info' } as const;\n\n/**\n * A terminal state the user needs to see.\n *\n * ★ `blocked` / `refused` / `notProvisioned` render as WARNING or INFO, not error — they are\n * different outcomes needing different fixes, and flattening them into \"something went\n * wrong\" is what makes an unprovisioned environment look broken.\n * ★ The state is in the TEXT, never only in the colour (WCAG 1.4.1).\n */\nexport function SystemNotice({ failure, guarded, onRetry }: SystemNoticeProps): React.ReactElement | null {\n if (!failure && !guarded) return null;\n\n if (!failure && guarded) {\n return (\n <MessageBar intent=\"warning\">\n <MessageBarBody>\n <MessageBarTitle>Response withheld</MessageBarTitle>\n The provider substituted safe text for the generated answer.\n </MessageBarBody>\n </MessageBar>\n );\n }\n if (!failure) return null;\n\n const title: Record<string, string> = {\n blocked: 'Response withheld',\n refused: 'The agent declined',\n error: 'Something went wrong',\n notProvisioned: 'Not configured',\n cancelled: 'Stopped',\n };\n\n return (\n <MessageBar intent={INTENT[runStatusSeverity(failure.status)]}>\n <MessageBarBody>\n <MessageBarTitle>{title[failure.status] ?? 'Notice'}</MessageBarTitle>\n {failure.message}\n </MessageBarBody>\n {failure.recoverable && onRetry ? (\n <MessageBarActions>\n <Button size=\"small\" onClick={onRetry}>\n Try again\n </Button>\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { Badge, Tooltip, type BadgeProps } from '@fluentui/react-components';\nimport {\n CheckmarkCircleRegular, ShieldErrorRegular, DismissCircleRegular,\n ErrorCircleRegular, PlugDisconnectedRegular, StopRegular,\n} from '@fluentui/react-icons';\nimport type { AgentRunStatus } from '../core';\n\nexport interface AgentStatusBadgeProps {\n status: AgentRunStatus;\n /** Shown in a tooltip — the provider's own message, when there is one. */\n reason?: string;\n size?: BadgeProps['size'];\n}\n\ninterface Presentation {\n label: string;\n color: NonNullable<BadgeProps['color']>;\n icon: React.ReactElement;\n}\n\n/**\n * ★★ SIX STATES, EACH WITH ITS OWN WORDS.\n *\n * The whole reason the run ladder is six-valued rather than {ok|error} is that these need\n * different reactions: `blocked` is a content filter, `refused` is the model declining,\n * `notProvisioned` is nobody having turned the service on, `cancelled` is the user pressing\n * stop. Collapsing any pair into a shared label throws that away — so the label is part of\n * the contract, and a test enumerates the union to prove each is distinct and non-empty.\n *\n * ★ The state is in the TEXT, never only the colour (WCAG 1.4.1). Four of these would otherwise\n * be shades of red.\n */\nconst PRESENTATION: Record<AgentRunStatus, Presentation> = {\n succeeded: { label: 'Succeeded', color: 'success', icon: <CheckmarkCircleRegular /> },\n blocked: { label: 'Blocked by content filter', color: 'warning', icon: <ShieldErrorRegular /> },\n refused: { label: 'Declined', color: 'warning', icon: <DismissCircleRegular /> },\n error: { label: 'Error', color: 'danger', icon: <ErrorCircleRegular /> },\n notProvisioned: { label: 'Not configured', color: 'informative', icon: <PlugDisconnectedRegular /> },\n cancelled: { label: 'Stopped', color: 'subtle', icon: <StopRegular /> },\n};\n\n/** Exported so the label contract can be asserted directly rather than scraped from markup. */\nexport function runStatusLabel(status: AgentRunStatus): string {\n return PRESENTATION[status].label;\n}\n\nexport function AgentStatusBadge({ status, reason, size = 'medium' }: AgentStatusBadgeProps): React.ReactElement {\n const { label, color, icon } = PRESENTATION[status];\n const badge = (\n <Badge appearance=\"tint\" color={color} icon={icon} size={size}>\n {label}\n </Badge>\n );\n return reason ? (\n <Tooltip content={reason} relationship=\"description\" withArrow>\n {badge}\n </Tooltip>\n ) : (\n badge\n );\n}\n","import * as React from 'react';\nimport { MessageBar, MessageBarBody, MessageBarTitle, MessageBarActions, Button } from '@fluentui/react-components';\nimport type { AgentAvailability } from '../core';\n\nexport interface AvailabilityBannerProps {\n availability?: AgentAvailability;\n onRetry?: () => void;\n /** Rendered beside Retry — a link to the setup doc, a \"Configure\" button. */\n actions?: React.ReactNode;\n}\n\n/**\n * Whether the agent can answer here, and if not, why.\n *\n * ★★ `notProvisioned` renders as INFORMATION, not an error. Nobody having configured the service\n * yet is a normal state in an on-demand Azure estate; dressing it as a failure is what makes a\n * working app look broken, and it needs a completely different response from an outage.\n *\n * ★ `reason` is displayed rather than summarised. \"Not licensed\" and \"not on this host\" need\n * different fixes, and the seam keeps them distinct precisely so the UI can say which.\n */\nexport function AvailabilityBanner({\n availability,\n onRetry,\n actions,\n}: AvailabilityBannerProps): React.ReactElement | null {\n if (!availability || availability.available) return null;\n\n const notProvisioned = availability.status === 'notProvisioned';\n return (\n <MessageBar intent={notProvisioned ? 'info' : 'warning'}>\n <MessageBarBody>\n <MessageBarTitle>\n {notProvisioned ? 'No agent configured' : 'The agent is unavailable'}\n </MessageBarTitle>\n {availability.reason ?? 'No reason was reported.'}\n </MessageBarBody>\n {onRetry || actions ? (\n <MessageBarActions>\n {actions}\n {onRetry ? (\n <Button size=\"small\" onClick={onRetry}>\n Check again\n </Button>\n ) : null}\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport type { AgentUsage } from '../core';\n\nexport interface UsageMeterProps {\n usage?: AgentUsage;\n show?: readonly ('tokens' | 'cost' | 'duration' | 'model')[];\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: tokens.spacingHorizontalM,\n fontSize: tokens.fontSizeBase100,\n color: tokens.colorNeutralForeground3,\n },\n item: { display: 'flex', gap: tokens.spacingHorizontalXXS },\n value: { fontFamily: tokens.fontFamilyMonospace },\n unknown: { fontStyle: 'italic' },\n});\n\n/**\n * Tokens, cost, latency.\n *\n * ★★ \"Not reported\" is rendered as such, never as 0. A provider that does not report cost and\n * one that cost nothing are completely different facts, and showing `$0.00` for the first is\n * a confident lie — the kind that gets believed because it looks like data.\n */\nexport function UsageMeter({\n usage,\n show = ['tokens', 'cost', 'duration'],\n}: UsageMeterProps): React.ReactElement | null {\n const styles = useStyles();\n if (!usage) return null;\n\n const items: { key: string; label: string; value: string; known: boolean }[] = [];\n\n if (show.includes('tokens')) {\n const known = usage.inputTokens !== undefined || usage.outputTokens !== undefined;\n items.push({\n key: 'tokens',\n label: 'Tokens',\n value: known\n ? `${usage.inputTokens ?? 0} in / ${usage.outputTokens ?? 0} out${\n usage.cachedTokens ? ` / ${usage.cachedTokens} cached` : ''\n }`\n : 'not reported',\n known,\n });\n }\n if (show.includes('cost')) {\n const known = usage.costUsd !== undefined;\n items.push({\n key: 'cost',\n label: 'Cost',\n value: known ? `$${usage.costUsd!.toFixed(6)}` : 'not reported',\n known,\n });\n }\n if (show.includes('duration')) {\n const known = usage.durationMs !== undefined;\n items.push({\n key: 'duration',\n label: 'Duration',\n value: known ? `${usage.durationMs} ms` : 'not reported',\n known,\n });\n }\n if (show.includes('model') && usage.model) {\n items.push({ key: 'model', label: 'Model', value: usage.model, known: true });\n }\n\n return (\n <div className={styles.root}>\n {items.map((item) => (\n <span key={item.key} className={styles.item}>\n {item.label}:{' '}\n <span className={item.known ? styles.value : styles.unknown}>{item.value}</span>\n </span>\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { MessageBar, MessageBarBody, MessageBarTitle, MessageBarActions, Button } from '@fluentui/react-components';\nimport type { AgentFailure } from '../core';\n\nexport interface ThrottleNoticeProps {\n failure?: AgentFailure;\n onRetry?: () => void;\n /** Injected so the countdown is testable without fake timers. */\n now?: () => number;\n}\n\n/**\n * A rate-limit notice that counts down.\n *\n * ★ It renders only for a failure that is BOTH retriable and carries `retryAfterMs`. A countdown\n * over an unknown wait would be invented, and a retry button that fires into an active throttle\n * just burns the next window.\n */\nexport function ThrottleNotice({ failure, onRetry, now = Date.now }: ThrottleNoticeProps): React.ReactElement | null {\n const retryAfterMs = failure?.retryAfterMs;\n const eligible = Boolean(failure?.recoverable && retryAfterMs && retryAfterMs > 0);\n\n const [remaining, setRemaining] = React.useState(retryAfterMs ?? 0);\n\n React.useEffect(() => {\n if (!eligible) return;\n const deadline = now() + (retryAfterMs ?? 0);\n setRemaining(retryAfterMs ?? 0);\n const id = setInterval(() => {\n const left = deadline - now();\n setRemaining(left > 0 ? left : 0);\n if (left <= 0) clearInterval(id);\n }, 250);\n return () => clearInterval(id);\n }, [eligible, retryAfterMs, now]);\n\n if (!eligible || !failure) return null;\n\n const seconds = Math.ceil(remaining / 1000);\n const ready = remaining <= 0;\n\n return (\n <MessageBar intent=\"warning\">\n <MessageBarBody>\n <MessageBarTitle>Rate limited</MessageBarTitle>\n {ready ? 'You can try again now.' : `${failure.message} Try again in ${seconds}s.`}\n </MessageBarBody>\n {onRetry ? (\n <MessageBarActions>\n <Button size=\"small\" onClick={onRetry} disabled={!ready}>\n Try again\n </Button>\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { Badge } from '@fluentui/react-components';\n\nexport interface ModelBadgeProps {\n provider?: string;\n model?: string;\n version?: string;\n}\n\n/** Which agent, which model, which version — so a run can be traced to a configuration. */\nexport function ModelBadge({ provider, model, version }: ModelBadgeProps): React.ReactElement | null {\n const parts = [provider, model, version ? `v${version}` : undefined].filter(Boolean);\n if (parts.length === 0) return null;\n return (\n <Badge appearance=\"outline\" color=\"informative\">\n {parts.join(' · ')}\n </Badge>\n );\n}\n","import * as React from 'react';\nimport { Dropdown, Option, Field } from '@fluentui/react-components';\nimport type { AgentDescriptor } from './types';\n\nexport interface AgentPickerProps {\n agents: readonly AgentDescriptor[];\n selectedId?: string;\n onSelect: (id: string) => void;\n label?: string;\n disabled?: boolean;\n}\n\n/**\n * Choose which agent answers.\n *\n * ★ Fluent's `Dropdown` — measured tabster-safe. `react-combobox` imports only\n * `useTabsterAttributes`, `useMergedTabsterAttributes_unstable`, `useSetKeyboardNavigation` and\n * `useOnKeyboardNavigationChange`; `useTabsterAttributes` calls `useTabster()` with NO argument,\n * and `useTabster`'s default factory is the identity, so it never reaches a `get*` factory or\n * `attrHandlers.set`. Two reviewers disagreed about this and the source settled it.\n *\n * ★ Selecting an agent is a CONFIG change, not a capability change: the seam still has no write\n * method whichever agent is chosen.\n */\nexport function AgentPicker({\n agents,\n selectedId,\n onSelect,\n label = 'Agent',\n disabled,\n}: AgentPickerProps): React.ReactElement {\n const selected = agents.find((a) => a.id === selectedId);\n\n return (\n <Field label={label}>\n <Dropdown\n disabled={disabled}\n value={selected ? selected.name : ''}\n selectedOptions={selectedId ? [selectedId] : []}\n onOptionSelect={(_, data) => {\n if (data.optionValue) onSelect(data.optionValue);\n }}\n placeholder=\"Select an agent\"\n >\n {agents.map((agent) => (\n <Option key={agent.id} value={agent.id} text={agent.name}>\n {agent.model ? `${agent.name} — ${agent.model}` : agent.name}\n </Option>\n ))}\n </Dropdown>\n </Field>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { AgentMessage, AgentToolCall } from '../core';\nimport { AgentStatusBadge } from './AgentStatusBadge';\nimport { UsageMeter } from './UsageMeter';\nimport { Disclosure } from '../internal';\n\nexport interface RunTimelineProps {\n message: AgentMessage;\n /** Collapsed by default: a trace is diagnostic, not the primary reading. */\n defaultOpen?: boolean;\n}\n\nconst useStyles = makeStyles({\n list: { listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n step: { display: 'flex', gap: tokens.spacingHorizontalS, alignItems: 'baseline' },\n index: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3, minWidth: '18px' },\n name: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase200 },\n status: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n section: { marginTop: tokens.spacingVerticalS },\n});\n\nconst TOOL_STATUS: Record<AgentToolCall['status'], string> = {\n proposed: 'proposed',\n running: 'running',\n succeeded: 'succeeded',\n failed: 'failed',\n denied: 'denied',\n};\n\n/**\n * What one turn actually did: its outcome, the tools it called, what it cited, what it cost.\n *\n * ★ An ORDERED LIST, not Fluent's `Tree`. `react-tree` reaches `useArrowNavigationGroup`, and a\n * trace is a sequence — the ordering is the information. If steps ever nest, revisit rather\n * than flattening a tree into a list.\n *\n * ★ Each step's status is in TEXT beside it. A row of coloured dots conveys nothing to a\n * screen reader and little to a colour-blind reader.\n */\nexport function RunTimeline({ message, defaultOpen = false }: RunTimelineProps): React.ReactElement | null {\n const styles = useStyles();\n const id = React.useId();\n\n const calls = message.toolCalls ?? [];\n const sources = message.sources ?? [];\n const hasAnything = calls.length > 0 || sources.length > 0 || message.usage || message.failure;\n if (!hasAnything) return null;\n\n const status = message.failure?.status ?? (message.guarded ? 'blocked' : 'succeeded');\n\n return (\n <Disclosure\n id={id}\n defaultOpen={defaultOpen}\n summary={`Trace — ${calls.length} tool call${calls.length === 1 ? '' : 's'}`}\n >\n <div className={styles.step}>\n <AgentStatusBadge status={status} reason={message.failure?.message} size=\"small\" />\n </div>\n\n {calls.length > 0 ? (\n <ol className={styles.list} aria-label=\"Tool calls\">\n {calls.map((call, index) => (\n <li key={call.id} className={styles.step}>\n <span className={styles.index}>{index + 1}.</span>\n <span className={styles.name}>{call.name}</span>\n <span className={styles.status}>{TOOL_STATUS[call.status]}</span>\n </li>\n ))}\n </ol>\n ) : null}\n\n {sources.length > 0 ? (\n <Text as=\"p\" size={200} className={styles.section}>\n {sources.length} source{sources.length === 1 ? '' : 's'} retrieved\n </Text>\n ) : null}\n\n <div className={styles.section}>\n <UsageMeter usage={message.usage} show={['tokens', 'cost', 'duration', 'model']} />\n </div>\n </Disclosure>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { AgentRunRecord } from './types';\nimport { AgentStatusBadge } from './AgentStatusBadge';\nimport { UsageMeter } from './UsageMeter';\n\nexport interface RunHistoryPanelProps {\n runs: readonly AgentRunRecord[];\n /**\n * A grid to render instead of the built-in list.\n *\n * ★★ THIS SLOT IS WHY THERE IS NO `RunHistoryList`. A run history is tabular, and this repo\n * already ships a grid — `@dataverse-kit/grid-kit/v9` — with sorting, virtualisation and\n * column chooser. Re-implementing a thin version here would be a second grid to maintain\n * and a worse one.\n *\n * It is a SLOT rather than a dependency because grid-kit/v9's `DataGrid` builds on\n * `react-table` and its toolbar on `Menu`, both of which reach tabster. A host that accepts\n * that passes a grid in; a host that does not gets the fallback list below. That is\n * surface-kit's documented \"pass grids in as children\" pattern, and it moves the tabster\n * decision to the host, where it belongs.\n */\n grid?: React.ReactNode;\n locale?: string;\n emptyLabel?: string;\n}\n\nconst useStyles = makeStyles({\n list: { listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n row: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n padding: tokens.spacingVerticalXS,\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, flexWrap: 'wrap' },\n time: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n prompt: { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },\n id: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n empty: { padding: tokens.spacingVerticalM, color: tokens.colorNeutralForeground3 },\n});\n\nexport function RunHistoryPanel({\n runs,\n grid,\n locale,\n emptyLabel = 'No runs yet.',\n}: RunHistoryPanelProps): React.ReactElement {\n const styles = useStyles();\n if (grid) return <>{grid}</>;\n if (runs.length === 0) {\n return (\n <Text className={styles.empty} size={200}>\n {emptyLabel}\n </Text>\n );\n }\n\n return (\n <ul className={styles.list} aria-label=\"Run history\">\n {runs.map((run) => (\n <li key={run.id} className={styles.row}>\n <div className={styles.head}>\n <AgentStatusBadge status={run.status} size=\"small\" />\n <span className={styles.time}>\n {new Intl.DateTimeFormat(locale, { dateStyle: 'short', timeStyle: 'short' }).format(\n new Date(run.startedAt),\n )}\n </span>\n {/* ★ The correlation id is surfaced, not hidden: it is the only handle someone has\n when finding this run in App Insights at 3am. */}\n {run.correlationId ? <span className={styles.id}>{run.correlationId}</span> : null}\n </div>\n {run.prompt ? <span className={styles.prompt}>{run.prompt}</span> : null}\n <UsageMeter usage={run.usage} />\n </li>\n ))}\n </ul>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { AgentAvailability } from '../core';\nimport type { AgentDescriptor, AgentRunRecord } from './types';\nimport { AvailabilityBanner } from './AvailabilityBanner';\nimport { AgentPicker } from './AgentPicker';\nimport { ModelBadge } from './ModelBadge';\nimport { RunHistoryPanel } from './RunHistoryPanel';\n\nexport interface AgentOpsPanelProps {\n availability?: AgentAvailability;\n agents?: readonly AgentDescriptor[];\n selectedAgentId?: string;\n onSelectAgent?: (id: string) => void;\n runs?: readonly AgentRunRecord[];\n /** Passed straight through to RunHistoryPanel — see that component for why it is a slot. */\n runsGrid?: React.ReactNode;\n onRefresh?: () => void;\n locale?: string;\n}\n\nconst useStyles = makeStyles({\n root: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalM, minWidth: 0 },\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, flexWrap: 'wrap' },\n section: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n caps: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n});\n\n/** The composed ops surface: is it available, which agent, what has it done. */\nexport function AgentOpsPanel(props: AgentOpsPanelProps): React.ReactElement {\n const { availability, agents, selectedAgentId, onSelectAgent, runs = [], runsGrid, onRefresh, locale } = props;\n const styles = useStyles();\n const selected = agents?.find((a) => a.id === selectedAgentId);\n const caps = availability?.capabilities;\n\n return (\n <div className={styles.root}>\n <AvailabilityBanner availability={availability} onRetry={onRefresh} />\n\n {agents && agents.length > 0 && onSelectAgent ? (\n <div className={styles.section}>\n <AgentPicker agents={agents} selectedId={selectedAgentId} onSelect={onSelectAgent} />\n <div className={styles.head}>\n <ModelBadge provider={selected?.name} model={selected?.model} version={selected?.version} />\n </div>\n </div>\n ) : null}\n\n {caps ? (\n <span className={styles.caps}>\n {/* Capabilities in words: an affordance the provider cannot honour is worse than a\n missing one, so a host can hide the stop button when `cancel` is false. */}\n Supports:{' '}\n {(Object.entries(caps) as [string, boolean][])\n .filter(([, on]) => on)\n .map(([name]) => name)\n .join(', ') || 'nothing reported'}\n </span>\n ) : null}\n\n <div className={styles.section}>\n <Text weight=\"semibold\" size={300}>\n Recent runs\n </Text>\n <RunHistoryPanel runs={runs} grid={runsGrid} locale={locale} />\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, mergeClasses, tokens, Badge } from '@fluentui/react-components';\nimport type { LauncherItem } from './types';\n\nexport interface AgentLauncherProps {\n items: readonly LauncherItem[];\n onSelect: (id: string) => void;\n /** Which edge it docks to. Default 'right'. */\n side?: 'left' | 'right';\n /** Accessible name for the group. */\n label?: string;\n /** Hide it without unmounting, so a host can keep its state. */\n hidden?: boolean;\n}\n\nconst useStyles = makeStyles({\n root: {\n position: 'absolute',\n top: '30%',\n display: 'flex',\n flexDirection: 'column',\n zIndex: 100,\n },\n right: { right: 0, alignItems: 'flex-end' },\n left: { left: 0, alignItems: 'flex-start' },\n hidden: { display: 'none' },\n pill: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalS,\n border: 'none',\n cursor: 'pointer',\n padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,\n color: tokens.colorNeutralForegroundOnBrand,\n fontFamily: tokens.fontFamilyBase,\n fontSize: tokens.fontSizeBase300,\n // ★ Collapsed shows the icon only; the LABEL IS STILL IN THE DOM (see below), so the\n // expand-on-hover is purely visual and the button is named for AT at every width.\n maxWidth: '44px',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n transitionProperty: 'max-width',\n transitionDuration: tokens.durationNormal,\n ':hover': { maxWidth: '260px' },\n ':hover .fui-launcher-label': { opacity: 1 },\n ':focus-within .fui-launcher-label': { opacity: 1 },\n // ★ :focus-within as well as :hover — a keyboard user must get the same reveal, and this is\n // the affordance the M365 reference only shows on pointer hover.\n ':focus-within': { maxWidth: '260px' },\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '-2px' },\n },\n primary: { backgroundColor: tokens.colorBrandBackground, ':hover': { backgroundColor: tokens.colorBrandBackgroundHover, maxWidth: '260px' } },\n secondary: { backgroundColor: tokens.colorBrandBackgroundStatic, ':hover': { backgroundColor: tokens.colorBrandBackgroundStatic, maxWidth: '260px' } },\n firstRight: { borderTopLeftRadius: tokens.borderRadiusXLarge },\n lastRight: { borderBottomLeftRadius: tokens.borderRadiusXLarge },\n firstLeft: { borderTopRightRadius: tokens.borderRadiusXLarge },\n lastLeft: { borderBottomRightRadius: tokens.borderRadiusXLarge },\n // ★★ flexShrink BELONGS ON THE ICON, NOT THE TEXT. With it on the text, a collapsed 44px pill\n // (20px of content box after padding) gave the unshrinkable label the whole width and squeezed\n // the icon to ZERO — so the collapsed rail showed two clipped letters instead of a glyph.\n // MEASURED on Chromatic build 18: svgWidth 0, reported as \"the content is off screen\".\n icon: { flexShrink: 0, display: 'flex', fontSize: '20px', lineHeight: 1 },\n // ★ The label FADES rather than relying on the clip. `overflow: hidden` cuts at the PADDING box,\n // so a 44px pill still showed ~4px of the first letter beside the icon. Opacity keeps the label\n // in the accessible name (see the class docstring) while hiding it from sight.\n text: {\n flexShrink: 1, minWidth: 0, opacity: 0,\n transitionProperty: 'opacity', transitionDuration: tokens.durationNormal,\n '@media (prefers-reduced-motion: reduce)': { transitionDuration: '1ms' },\n },\n});\n\n/**\n * The edge-docked entry point — the collapsed pills that expand on hover, as the M365 admin\n * centre presents \"Help & support\" and \"Give Feedback\".\n *\n * ★★ IN-TREE, and that is a measured decision rather than a stylistic one. A Fluent `Menu` costs\n * **+185 KB and 2 `attrHandlers.set` calls** in a PCF bundle (measured 2026-09-25 against\n * `ConversationHeader`), which is the whole tabster-singleton hazard. A stack of buttons needs\n * none of it, so a host that embeds only the launcher needs no `targetDocument` isolation.\n *\n * ★★ THE LABEL IS ALWAYS RENDERED, never swapped in on hover. Collapsing is done with `max-width`\n * and `overflow: hidden`, so the accessible name is identical collapsed and expanded. Revealing\n * text on hover only — the reference behaviour — would leave a screen-reader user with an\n * unnamed button, and `title` is not a substitute.\n */\nexport function AgentLauncher({\n items,\n onSelect,\n side = 'right',\n label = 'Assistant',\n hidden = false,\n}: AgentLauncherProps): React.ReactElement | null {\n const styles = useStyles();\n if (items.length === 0) return null;\n return (\n <div\n className={mergeClasses(styles.root, side === 'right' ? styles.right : styles.left, hidden && styles.hidden)}\n role=\"group\"\n aria-label={label}\n >\n {items.map((item, i) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => onSelect(item.id)}\n className={mergeClasses(\n styles.pill,\n i === 0 ? styles.primary : styles.secondary,\n i === 0 && (side === 'right' ? styles.firstRight : styles.firstLeft),\n i === items.length - 1 && (side === 'right' ? styles.lastRight : styles.lastLeft),\n )}\n >\n <span className={styles.icon} aria-hidden=\"true\">{item.icon}</span>\n <span className={mergeClasses(styles.text, 'fui-launcher-label')}>{item.label}</span>\n {item.badgeCount ? <Badge appearance=\"filled\" color=\"danger\">{item.badgeCount}</Badge> : null}\n </button>\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { Button, Switch, Text, Tooltip, makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport { DismissRegular, ArrowDownloadRegular, SpeakerMuteRegular, Speaker2Regular } from '@fluentui/react-icons';\nimport { useRovingTabindex } from '../a11y/useRovingTabindex';\nimport { useReturnFocus } from '../a11y/useReturnFocus';\nimport type { AssistantTab } from './types';\n\nexport interface AssistantPanelProps {\n title: string;\n tabs: readonly AssistantTab[];\n activeTabId: string;\n onTabChange: (id: string) => void;\n onClose?: () => void;\n /** The on/off switch in the header. Omit both to hide it. */\n enabled?: boolean;\n onEnabledChange?: (enabled: boolean) => void;\n /**\n * The pre-arrival line (\"Support Assistant will be with you in a moment\").\n * ★ Chrome, not transcript content — it is never announced as a message.\n */\n status?: string;\n onDownloadTranscript?: () => void;\n muted?: boolean;\n onMutedChange?: (muted: boolean) => void;\n /** The transcript + composer. Slot in `MessageList` and `Composer`. */\n children?: React.ReactNode;\n /**\n * Drives the slide-in and focus handling. Defaults to `true` — a panel a host simply places\n * stays open and unanimated, which is the behaviour that shipped in 0.3.0.\n */\n open?: boolean;\n /** Called on Escape. Omit and Escape does nothing — the panel never closes itself silently. */\n onDismiss?: () => void;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex', flexDirection: 'column', height: '100%', minWidth: '320px',\n backgroundColor: tokens.colorNeutralBackground1,\n borderLeft: `1px solid ${tokens.colorNeutralStroke2}`,\n // ★ transform, not width/left — those two lay out on every frame and a transcript is an\n // expensive subtree to reflow 60 times a second.\n transform: 'translateX(0)',\n transitionProperty: 'transform',\n transitionDuration: tokens.durationGentle,\n transitionTimingFunction: tokens.curveDecelerateMid,\n // ★★ prefers-reduced-motion is honoured, and it is not decoration: a full-height panel\n // sliding across the viewport is exactly the vestibular trigger the setting exists for.\n '@media (prefers-reduced-motion: reduce)': { transitionDuration: '1ms' },\n },\n closed: {\n transform: 'translateX(100%)',\n // ★ Hidden from AT as well as sight. A translated-off panel is still in the a11y tree and\n // still tabbable, so a keyboard user would tab into a drawer they cannot see.\n visibility: 'hidden',\n },\n header: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, padding: tokens.spacingVerticalS },\n tabstrip: { display: 'flex', gap: tokens.spacingHorizontalXXS, flexGrow: 1 },\n tab: {\n display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS,\n border: 'none', background: 'none', cursor: 'pointer',\n padding: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalS}`,\n color: tokens.colorNeutralForeground2, fontFamily: tokens.fontFamilyBase,\n borderBottom: `2px solid transparent`,\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '-2px' },\n },\n tabSelected: { color: tokens.colorNeutralForeground1, borderBottom: `2px solid ${tokens.colorCompoundBrandStroke}` },\n title: { padding: `0 ${tokens.spacingHorizontalM} ${tokens.spacingVerticalS}` },\n status: {\n padding: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalM}`,\n color: tokens.colorNeutralForeground3, fontSize: tokens.fontSizeBase200,\n },\n body: { flexGrow: 1, minHeight: 0, display: 'flex', flexDirection: 'column' },\n footer: {\n display: 'flex', alignItems: 'center', justifyContent: 'space-between',\n padding: tokens.spacingVerticalXS, borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n});\n\n/**\n * The docked assistant drawer, as the M365 admin centre presents Support Assistant: a small tab\n * strip, a title, an on/off switch, the transcript, a pre-arrival status line, and a footer with\n * transcript-download and mute.\n *\n * ★★ THE TAB STRIP IS IN-TREE, not Fluent's `TabList`, and the reason is measured: one Fluent\n * `Menu` cost **+185 KB and 2 `attrHandlers.set` calls** in a PCF bundle (2026-09-25). For a\n * two- or three-tab strip the APG pattern is small — roving tabindex, `aria-selected`,\n * `aria-controls` — and the kit already owns `useRovingTabindex`. Paying the tabster-singleton\n * hazard for that would be a bad trade. `TabList` remains the right call where the strip is\n * large, RTL-aware and needs Home/End/PgUp/PgDn.\n *\n * ★ `status` is CHROME. It renders outside the transcript and is not routed through\n * `LiveAnnouncer`, because \"will be with you in a moment\" is not a message and announcing it\n * would interleave with the reply the user is waiting for.\n */\nexport function AssistantPanel(props: AssistantPanelProps): React.ReactElement {\n const {\n title, tabs, activeTabId, onTabChange, onClose,\n enabled, onEnabledChange, status,\n onDownloadTranscript, muted, onMutedChange, children,\n open = true, onDismiss,\n } = props;\n const styles = useStyles();\n const baseId = React.useId();\n const rootRef = React.useRef<HTMLElement>(null);\n useReturnFocus({ open, containerRef: rootRef as React.RefObject<HTMLElement> });\n const selectedIndex = Math.max(0, tabs.findIndex((t) => t.id === activeTabId));\n const roving = useRovingTabindex({\n itemCount: tabs.length,\n orientation: 'horizontal',\n // ★ MANUAL ACTIVATION: arrows move focus, Enter/Space selects. That is what the kit's\n // useRovingTabindex does everywhere, and it is the APG pattern for tabs whose panel is not\n // free to render. Do not special-case it here; consistency is worth more than the one\n // keystroke, and a divergent strip is the kind of thing nobody notices until it is shipped.\n onActivate: (i) => tabs[i] && onTabChange(tabs[i].id),\n });\n\n // ★ The tab stop must follow an EXTERNALLY changed tab. Without this the hook keeps its own\n // index, so a host calling setActiveTab('history') leaves the single tabbable item on 'chat' —\n // focus lands on a tab that is not the selected one, which reads as a broken strip to a\n // keyboard user and to nobody else.\n const { setActiveIndex } = roving;\n React.useEffect(() => { setActiveIndex(selectedIndex); }, [selectedIndex, setActiveIndex]);\n\n return (\n <section\n ref={rootRef}\n className={mergeClasses(styles.root, !open && styles.closed)}\n aria-label={title}\n aria-hidden={!open || undefined}\n tabIndex={-1}\n onKeyDown={(e) => {\n if (e.key !== 'Escape' || !onDismiss) return;\n e.stopPropagation();\n onDismiss();\n }}\n >\n <div className={styles.header}>\n <div className={styles.tabstrip} role=\"tablist\" aria-label={`${title} views`}>\n {tabs.map((tab, i) => {\n const item = roving.getItemProps(i);\n const selected = tab.id === activeTabId;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n id={`${baseId}-tab-${tab.id}`}\n aria-selected={selected}\n aria-controls={`${baseId}-panel`}\n className={mergeClasses(styles.tab, selected && styles.tabSelected)}\n {...item}\n onClick={() => { roving.setActiveIndex(i); onTabChange(tab.id); }}\n >\n {tab.icon}\n <span>{tab.label}</span>\n </button>\n );\n })}\n </div>\n {onEnabledChange ? (\n <Switch checked={enabled ?? true} onChange={(_, d) => onEnabledChange(d.checked)} label={enabled ?? true ? 'On' : 'Off'} />\n ) : null}\n {onClose ? (\n <Tooltip content=\"Close\" relationship=\"label\" withArrow>\n <Button appearance=\"subtle\" icon={<DismissRegular />} onClick={onClose} />\n </Tooltip>\n ) : null}\n </div>\n\n <Text as=\"h2\" size={600} weight=\"semibold\" className={styles.title}>{title}</Text>\n\n <div className={styles.body} id={`${baseId}-panel`} role=\"tabpanel\" aria-labelledby={`${baseId}-tab-${activeTabId}`}>\n {status ? <div className={styles.status}>{status}</div> : null}\n {children}\n </div>\n\n {onDownloadTranscript || onMutedChange ? (\n <div className={styles.footer}>\n {onDownloadTranscript ? (\n <Tooltip content=\"Download transcript\" relationship=\"label\" withArrow>\n <Button appearance=\"subtle\" icon={<ArrowDownloadRegular />} onClick={onDownloadTranscript} />\n </Tooltip>\n ) : <span />}\n {onMutedChange ? (\n <Tooltip content={muted ? 'Unmute' : 'Mute'} relationship=\"label\" withArrow>\n <Button\n appearance=\"subtle\"\n aria-pressed={!!muted}\n icon={muted ? <SpeakerMuteRegular /> : <Speaker2Regular />}\n onClick={() => onMutedChange(!muted)}\n />\n </Tooltip>\n ) : <span />}\n </div>\n ) : null}\n </section>\n );\n}\n","import * as React from 'react';\nimport {\n Button, Radio, RadioGroup, Text, Textarea, makeStyles, mergeClasses, tokens,\n} from '@fluentui/react-components';\nimport { StarRegular, StarFilled } from '@fluentui/react-icons';\nimport { useRovingTabindex } from '../a11y/useRovingTabindex';\nimport type { FeedbackValue } from './types';\n\nexport interface FeedbackPanelProps {\n value: FeedbackValue;\n onChange: (value: FeedbackValue) => void;\n onSubmit: (value: FeedbackValue) => void;\n onCancel?: () => void;\n heading?: string;\n ratingLabel?: string;\n /** Rendered under \"Add more details\" — a host's screenshot/attachment affordance. */\n attachments?: React.ReactNode;\n /** Shown above the buttons. The reference names the signed-in user and links its policy. */\n privacyNote?: React.ReactNode;\n busy?: boolean;\n}\n\nconst STARS = [1, 2, 3, 4, 5] as const;\n\nconst useStyles = makeStyles({\n root: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalM, padding: tokens.spacingVerticalL, maxWidth: '680px' },\n field: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS },\n stars: { display: 'flex', gap: tokens.spacingHorizontalXS },\n star: {\n border: 'none', background: 'none', cursor: 'pointer', padding: tokens.spacingVerticalXXS,\n color: tokens.colorNeutralForeground2, fontSize: '26px', lineHeight: 1,\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '2px' },\n },\n starOn: { color: tokens.colorCompoundBrandForeground1 },\n footer: { display: 'flex', justifyContent: 'flex-end', gap: tokens.spacingHorizontalS },\n note: { color: tokens.colorNeutralForeground3, fontSize: tokens.fontSizeBase200 },\n});\n\n/**\n * Structured feedback capture, as the M365 admin centre's \"Submit feedback to Microsoft\": a star\n * rating, free text, a host attachment slot, a REQUIRED contact-consent choice, and a privacy note.\n *\n * ★★ THE RATING IS AN APG RADIOGROUP, in-tree. Five buttons with roving tabindex and\n * `aria-checked` is the whole pattern; reaching for a Fluent component here would buy the\n * tabster-singleton hazard (measured: one Fluent `Menu` = +185 KB and 2 `attrHandlers.set`) for\n * nothing. `RadioGroup` IS used for the consent pair, which is a genuine native radio group.\n *\n * ★★ SUBMIT IS DISABLED UNTIL BOTH A RATING AND A CONSENT ANSWER EXIST, and the reason is not\n * tidiness: the reference marks consent required, and a feedback record submitted without it\n * cannot lawfully be followed up. `mayContact === undefined` is \"not answered\" and is NOT the\n * same as `false` — collapsing the two would silently record a refusal the user never gave.\n */\nexport function FeedbackPanel(props: FeedbackPanelProps): React.ReactElement {\n const {\n value, onChange, onSubmit, onCancel,\n heading = 'Send feedback',\n ratingLabel = 'Rate your experience',\n attachments, privacyNote, busy = false,\n } = props;\n const styles = useStyles();\n const baseId = React.useId();\n const roving = useRovingTabindex({\n itemCount: STARS.length,\n orientation: 'horizontal',\n onActivate: (i) => onChange({ ...value, rating: i + 1 }),\n });\n\n const canSubmit = value.rating > 0 && value.mayContact !== undefined && !busy;\n\n return (\n <div className={styles.root}>\n <Text as=\"h2\" size={600} weight=\"semibold\">{heading}</Text>\n\n <div className={styles.field}>\n <Text id={`${baseId}-rating`}>{ratingLabel}</Text>\n <div className={styles.stars} role=\"radiogroup\" aria-labelledby={`${baseId}-rating`}>\n {STARS.map((n, i) => {\n const item = roving.getItemProps(i);\n const on = value.rating >= n;\n return (\n <button\n key={n}\n type=\"button\"\n role=\"radio\"\n aria-checked={value.rating === n}\n aria-label={`${n} of 5`}\n className={mergeClasses(styles.star, on && styles.starOn)}\n {...item}\n onClick={() => { roving.setActiveIndex(i); onChange({ ...value, rating: n }); }}\n >\n {on ? <StarFilled /> : <StarRegular />}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className={styles.field}>\n <Text id={`${baseId}-detail`}>Explain in more detail</Text>\n <Textarea\n aria-labelledby={`${baseId}-detail`}\n placeholder=\"Do not include any private or sensitive information.\"\n value={value.comment}\n onChange={(_, d) => onChange({ ...value, comment: d.value })}\n resize=\"vertical\"\n />\n </div>\n\n {attachments ? (\n <div className={styles.field}>\n <Text>Add more details</Text>\n {attachments}\n </div>\n ) : null}\n\n <div className={styles.field}>\n <Text id={`${baseId}-consent`}>May we contact you about your feedback?</Text>\n <RadioGroup\n aria-labelledby={`${baseId}-consent`}\n value={value.mayContact === undefined ? '' : value.mayContact ? 'yes' : 'no'}\n onChange={(_, d) => onChange({ ...value, mayContact: d.value === 'yes' })}\n >\n <Radio value=\"yes\" label=\"Yes, you may contact me\" />\n <Radio value=\"no\" label=\"No, don't contact me\" />\n </RadioGroup>\n </div>\n\n {privacyNote ? <div className={styles.note}>{privacyNote}</div> : null}\n\n <div className={styles.footer}>\n {onCancel ? <Button appearance=\"secondary\" onClick={onCancel}>Cancel</Button> : null}\n <Button appearance=\"primary\" disabled={!canSubmit} onClick={() => onSubmit(value)}>Submit</Button>\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Button } from '@fluentui/react-components';\nimport { NavigationRegular } from '@fluentui/react-icons';\nimport { BREAKPOINTS, resolveBreakpoint, useContainerWidth } from '@dataverse-kit/surface-kit/v9';\n\nexport interface AgentAppShellProps {\n /** The left icon rail. Hidden below `sm`. */\n rail?: React.ReactNode;\n /** The conversation list. Collapses to an overlay below `md`. */\n sidebar?: React.ReactNode;\n /** The conversation header, above the main region. */\n header?: React.ReactNode;\n /** The transcript + composer. */\n children?: React.ReactNode;\n /** The detail pane. Hidden below `lg` — the consumer decides what to do with it there. */\n rightPane?: React.ReactNode;\n sidebarWidth?: number;\n /**\n * Drive the layout from a KNOWN width instead of measuring.\n *\n * ★ Mirrors `FormSurface.containerWidth` in surface-kit/v9, and exists for the same reason: a\n * PCF host already knows its `context.allocatedWidth`, so making it wait for a\n * ResizeObserver round-trip is a needless reflow. It is also what makes the collapse\n * TESTABLE — jsdom's ResizeObserver is a stub that never fires, so a measured width stays 0\n * forever and only the roomy branch would ever run.\n */\n containerWidth?: number;\n /** Controlled sidebar visibility on narrow widths. */\n sidebarOpen?: boolean;\n onSidebarOpenChange?: (open: boolean) => void;\n label?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n height: '100%',\n minHeight: 0,\n backgroundColor: tokens.colorNeutralBackground2,\n position: 'relative',\n overflow: 'hidden',\n },\n sidebar: {\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n backgroundColor: tokens.colorNeutralBackground1,\n borderRight: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n // Below `md` the list overlays the conversation instead of shrinking it to nothing.\n sidebarOverlay: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n zIndex: 2,\n boxShadow: tokens.shadow16,\n },\n scrim: { position: 'absolute', inset: '0', zIndex: 1, backgroundColor: tokens.colorBackgroundOverlay },\n main: { flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, minHeight: 0 },\n body: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' },\n toggle: { position: 'absolute', top: tokens.spacingVerticalS, left: tokens.spacingHorizontalS, zIndex: 3 },\n});\n\n/**\n * The Teams-like frame: rail │ list │ conversation │ detail pane.\n *\n * ★★ BOUNDARY WITH surface-kit, in one sentence: **surface-kit owns record/form geometry;\n * agent-kit owns conversation geometry.** `FormSurface`/`Section`/`PivotSurface` are for a\n * Dataverse record; this is for a thread. `MasterDetailSurface` is not this — it is v8-only\n * and two-pane. When surface-kit's deferred v9 composites land, this row is the one to check\n * for overlap.\n *\n * ★★ IT IS NOT A SECOND BREAKPOINT AUTHORITY. The cutoffs come from\n * `@dataverse-kit/surface-kit/v9` (`BREAKPOINTS`, `resolveBreakpoint`), which surface-kit's\n * CLAUDE.md states as an invariant: \"every responsive stacking decision flows through\n * responsive/builders.ts\". Redeclaring 480/768 here is how two files start disagreeing.\n *\n * ★ It measures its CONTAINER, not the viewport (`useContainerWidth`). A PCF control or a\n * custom page occupies a pane, not a window — `context.allocatedWidth`, not `window.innerWidth`\n * — so a viewport media query would collapse the wrong way in the host this kit targets.\n */\nexport function AgentAppShell(props: AgentAppShellProps): React.ReactElement {\n const {\n rail, sidebar, header, children, rightPane,\n sidebarWidth = 280, sidebarOpen, onSidebarOpenChange, label = 'Agent workspace',\n } = props;\n const styles = useStyles();\n\n const [containerRef, measuredWidth] = useContainerWidth<HTMLDivElement>();\n // ★ `useContainerWidth` starts at 0 and stays 0 until a ResizeObserver entry lands — so 0\n // means NOT YET MEASURED, not \"zero pixels wide\". Treating it as a real width would collapse\n // the whole shell on first paint and expand it a frame later, which is a visible jolt.\n // An explicit `containerWidth` wins outright.\n const width = props.containerWidth ?? (measuredWidth > 0 ? measuredWidth : undefined);\n const effective = width ?? BREAKPOINTS.xl;\n const breakpoint = resolveBreakpoint(effective);\n\n const railVisible = effective >= BREAKPOINTS.sm;\n const sidebarInline = effective >= BREAKPOINTS.md;\n const rightPaneVisible = effective >= BREAKPOINTS.lg;\n\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const overlayOpen = sidebarOpen ?? uncontrolledOpen;\n const setOverlayOpen = (open: boolean) => {\n onSidebarOpenChange?.(open);\n if (sidebarOpen === undefined) setUncontrolledOpen(open);\n };\n\n return (\n <div ref={containerRef} className={styles.root} data-breakpoint={breakpoint} aria-label={label}>\n {rail && railVisible ? rail : null}\n\n {sidebar && sidebarInline ? (\n <div className={styles.sidebar} style={{ width: sidebarWidth }}>\n {sidebar}\n </div>\n ) : null}\n\n {sidebar && !sidebarInline && overlayOpen ? (\n <>\n <div\n className={styles.scrim}\n onClick={() => setOverlayOpen(false)}\n // Decorative: Escape and the toggle are the real affordances.\n aria-hidden=\"true\"\n />\n <div className={`${styles.sidebar} ${styles.sidebarOverlay}`} style={{ width: sidebarWidth }}>\n {sidebar}\n </div>\n </>\n ) : null}\n\n <div className={styles.main}>\n {sidebar && !sidebarInline ? (\n <Button\n className={styles.toggle}\n size=\"small\"\n appearance=\"subtle\"\n icon={<NavigationRegular />}\n aria-label={overlayOpen ? 'Hide conversations' : 'Show conversations'}\n aria-expanded={overlayOpen}\n onClick={() => setOverlayOpen(!overlayOpen)}\n />\n ) : null}\n {header}\n <div className={styles.body}>{children}</div>\n </div>\n\n {rightPaneVisible ? rightPane : null}\n </div>\n );\n}\n","import * as React from 'react';\nimport {\n Button, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Tooltip,\n makeStyles, mergeClasses, tokens,\n} from '@fluentui/react-components';\nimport { MoreHorizontalRegular } from '@fluentui/react-icons';\nimport type { RailItem } from './types';\n\nexport interface AppRailProps {\n items: readonly RailItem[];\n selectedId?: string;\n onSelect: (id: string) => void;\n /** Items beyond this many move into the overflow menu. */\n maxVisible?: number;\n label?: string;\n footer?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: tokens.spacingVerticalXS,\n padding: tokens.spacingVerticalS,\n backgroundColor: tokens.colorNeutralBackground3,\n borderRight: `1px solid ${tokens.colorNeutralStroke2}`,\n minHeight: 0,\n },\n spacer: { flex: 1 },\n button: {\n position: 'relative',\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '1px' },\n },\n selected: { backgroundColor: tokens.colorNeutralBackground1Selected },\n badge: {\n position: 'absolute',\n top: '2px',\n right: '2px',\n minWidth: '16px',\n height: '16px',\n padding: '0 3px',\n borderRadius: tokens.borderRadiusCircular,\n backgroundColor: tokens.colorPaletteRedBackground3,\n color: tokens.colorNeutralForegroundOnBrand,\n fontSize: '10px',\n lineHeight: '16px',\n },\n});\n\n/**\n * The left icon rail.\n *\n * ★★ The overflow uses Fluent's real `Menu`, which reaches `useArrowNavigationGroup` → tabster.\n * That is DELIBERATE, per the split-by-cost decision: a menu is a genuine APG widget (focus\n * trap, typeahead, Escape, roving) and hand-rolling it is 100+ LOC, whereas a PCF host closes\n * the tabster gap in one line with `targetDocument`. The coexistence spike (see CLAUDE.md)\n * measured two cores on one window and found no double-handling, so this is safe under\n * isolation. `Menu` is the ONE tabster-touching component in the shell.\n *\n * ★ Each rail button is its own tab stop deliberately: the rail is app-level navigation, not a\n * composite widget, and roving it would hide destinations from a Tab-only user.\n */\nexport function AppRail(props: AppRailProps): React.ReactElement {\n const { items, selectedId, onSelect, maxVisible = 6, label = 'Apps', footer } = props;\n const styles = useStyles();\n\n const visible = items.slice(0, maxVisible);\n const overflow = items.slice(maxVisible);\n\n return (\n <nav className={styles.root} aria-label={label}>\n {visible.map((item) => (\n <Tooltip key={item.id} content={item.label} relationship=\"label\" positioning=\"after\" withArrow>\n <Button\n appearance=\"subtle\"\n icon={item.icon}\n className={mergeClasses(styles.button, item.id === selectedId && styles.selected)}\n aria-pressed={item.id === selectedId}\n aria-label={\n item.badgeCount\n ? `${item.label}, ${item.badgeCount} unread`\n : item.label\n }\n onClick={() => onSelect(item.id)}\n >\n {item.badgeCount ? (\n <span className={styles.badge} aria-hidden=\"true\">\n {item.badgeCount}\n </span>\n ) : null}\n </Button>\n </Tooltip>\n ))}\n\n {overflow.length > 0 ? (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <Button\n appearance=\"subtle\"\n icon={<MoreHorizontalRegular />}\n className={styles.button}\n aria-label={`More apps, ${overflow.length} hidden`}\n />\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {overflow.map((item) => (\n <MenuItem key={item.id} icon={item.icon} onClick={() => onSelect(item.id)}>\n {item.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n ) : null}\n\n <div className={styles.spacer} />\n {footer}\n </nav>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens, Text } from '@fluentui/react-components';\nimport type { ConversationSummary } from './types';\nimport { ConversationListItem } from './ConversationListItem';\n\nexport interface ConversationListProps {\n items: readonly ConversationSummary[];\n selectedId?: string;\n onSelect: (id: string) => void;\n label?: string;\n locale?: string;\n empty?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n padding: tokens.spacingHorizontalXS,\n overflowY: 'auto',\n minHeight: 0,\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '-2px' },\n },\n empty: { padding: tokens.spacingVerticalM, color: tokens.colorNeutralForeground3 },\n});\n\n/**\n * The chat list.\n *\n * ★★ A LISTBOX with `aria-activedescendant`, not a stack of buttons and not a `Tree`.\n *\n * A bare button list is not a simpler tree — it is a widget with no collection semantics at\n * all: N tab stops, no selected state, no set size or position, no arrow navigation. A\n * listbox is ONE tab stop, Up/Down/Home/End move an active option, and `aria-selected` says\n * which conversation is open.\n *\n * `Tree` would be right if this nested (teams → channels); it does not — see ./types.ts,\n * where that decision is written down.\n *\n * ★ Modelled on the estate's existing activedescendant listbox\n * (`shared/pcf-gallery/controls/choice-grid/.../ChoiceGridApp.tsx`), including the detail that\n * `scrollIntoView` is guarded on the METHOD (`?.()`), not just the element: it is not\n * implemented everywhere a React tree runs, and an unguarded call inside an effect does not\n * degrade — it throws, React unmounts, and the list renders nothing.\n */\nexport function ConversationList(props: ConversationListProps): React.ReactElement {\n const { items, selectedId, onSelect, label = 'Conversations', locale, empty } = props;\n const styles = useStyles();\n const listRef = React.useRef<HTMLDivElement>(null);\n const idBase = React.useId();\n\n const selectedIndex = Math.max(0, items.findIndex((i) => i.id === selectedId));\n const [active, setActive] = React.useState(selectedIndex);\n\n // Follow an externally-driven selection, and never point past the end if the list shrinks.\n React.useEffect(() => {\n setActive((current) => {\n if (items.length === 0) return 0;\n if (selectedIndex >= 0 && items[selectedIndex]) return selectedIndex;\n return Math.min(current, items.length - 1);\n });\n }, [selectedIndex, items]);\n\n const optionId = (index: number) => `${idBase}-opt-${index}`;\n\n React.useEffect(() => {\n // ★ getElementById, not querySelector('#id'): React useId values contain colons, and jsdom\n // does not expose CSS.escape to sanitise them.\n // ★★ The optional call is on the METHOD. `scrollIntoView` is not implemented everywhere a\n // React tree runs — jsdom being the obvious case — and an unguarded call inside an effect\n // does not degrade: it THROWS, React unmounts, and the list renders nothing at all. A\n // cosmetic nicety must never be able to take the shell down.\n const el = listRef.current?.ownerDocument.getElementById(optionId(active));\n el?.scrollIntoView?.({ block: 'nearest' });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [active, idBase]);\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n const last = items.length - 1;\n if (last < 0) return;\n let next: number | null = null;\n if (event.key === 'ArrowDown') next = Math.min(last, active + 1);\n else if (event.key === 'ArrowUp') next = Math.max(0, active - 1);\n else if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = last;\n else if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n const picked = items[active];\n // The list can shrink while focus is held; checking the ENTRY rather than defaulting the\n // id makes that a no-op instead of selecting something wrong.\n if (picked) onSelect(picked.id);\n return;\n }\n if (next === null) return;\n event.preventDefault();\n setActive(next);\n };\n\n if (items.length === 0) {\n return (\n <div className={styles.root}>\n {empty ?? (\n <Text className={styles.empty} size={200}>\n No conversations yet.\n </Text>\n )}\n </div>\n );\n }\n\n return (\n <div\n ref={listRef}\n className={styles.root}\n role=\"listbox\"\n aria-label={label}\n // ONE tab stop for the whole list.\n tabIndex={0}\n aria-activedescendant={optionId(active)}\n onKeyDown={onKeyDown}\n >\n {items.map((summary, index) => (\n <ConversationListItem\n key={summary.id}\n id={optionId(index)}\n summary={summary}\n selected={summary.id === selectedId}\n active={index === active}\n locale={locale}\n onSelect={onSelect}\n />\n ))}\n </div>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { ConversationSummary } from './types';\nimport { AgentAvatar } from './AgentAvatar';\n\nexport interface ConversationListItemProps {\n summary: ConversationSummary;\n selected: boolean;\n active: boolean;\n id: string;\n locale?: string;\n onSelect: (id: string) => void;\n}\n\nconst useStyles = makeStyles({\n row: {\n display: 'flex',\n gap: tokens.spacingHorizontalS,\n alignItems: 'center',\n padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalS}`,\n borderRadius: tokens.borderRadiusMedium,\n cursor: 'pointer',\n ':hover': { backgroundColor: tokens.colorNeutralBackground1Hover },\n },\n // ★ The ACTIVE row (aria-activedescendant target) gets a visible focus indicator, because\n // real DOM focus stays on the listbox — without this the keyboard user sees nothing move.\n active: { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '-2px' },\n selected: { backgroundColor: tokens.colorNeutralBackground1Selected },\n body: { flex: 1, minWidth: 0 },\n title: {\n display: 'block',\n fontSize: tokens.fontSizeBase300,\n fontWeight: tokens.fontWeightSemibold,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n muted: { fontWeight: tokens.fontWeightRegular, color: tokens.colorNeutralForeground3 },\n preview: {\n display: 'block',\n fontSize: tokens.fontSizeBase200,\n color: tokens.colorNeutralForeground3,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n meta: { display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: '2px' },\n time: { fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3 },\n unread: {\n minWidth: '18px',\n height: '18px',\n padding: `0 ${tokens.spacingHorizontalXXS}`,\n borderRadius: tokens.borderRadiusCircular,\n backgroundColor: tokens.colorBrandBackground,\n color: tokens.colorNeutralForegroundOnBrand,\n fontSize: tokens.fontSizeBase100,\n lineHeight: '18px',\n textAlign: 'center',\n },\n});\n\n/**\n * Build the row's accessible name.\n *\n * ★★ Unread count and presence go in the NAME, not only in a badge and a colour dot. A screen\n * reader hearing \"Contoso\" forty times learns nothing about which conversations are waiting,\n * and a colour-only unread indicator is a WCAG 1.4.1 failure. Exported so it can be asserted\n * directly rather than inferred from rendered markup.\n */\nexport function conversationAccessibleName(\n summary: ConversationSummary,\n locale?: string,\n): string {\n const parts = [summary.title];\n if (summary.presence && summary.presence !== 'unknown') parts.push(summary.presence);\n if (!summary.muted && summary.unreadCount) {\n parts.push(`${summary.unreadCount} unread`);\n }\n if (summary.muted) parts.push('muted');\n if (summary.timestamp) {\n parts.push(new Intl.DateTimeFormat(locale, { timeStyle: 'short' }).format(new Date(summary.timestamp)));\n }\n return parts.join(', ');\n}\n\nexport function ConversationListItem(props: ConversationListItemProps): React.ReactElement {\n const { summary, selected, active, id, locale, onSelect } = props;\n const styles = useStyles();\n const time = summary.timestamp\n ? new Intl.DateTimeFormat(locale, { timeStyle: 'short' }).format(new Date(summary.timestamp))\n : undefined;\n\n return (\n <div\n id={id}\n role=\"option\"\n aria-selected={selected}\n aria-label={conversationAccessibleName(summary, locale)}\n className={mergeClasses(styles.row, selected && styles.selected, active && styles.active)}\n onClick={() => onSelect(summary.id)}\n data-conversation-option\n >\n <AgentAvatar participant={summary.participant} presence={summary.presence} size={32} />\n {/* The visible text is aria-hidden: the row's own aria-label is the accessible name, and\n without this a screen reader reads the title twice. */}\n <div className={styles.body} aria-hidden=\"true\">\n <span className={mergeClasses(styles.title, summary.muted && styles.muted)}>{summary.title}</span>\n {summary.preview ? <span className={styles.preview}>{summary.preview}</span> : null}\n </div>\n <div className={styles.meta} aria-hidden=\"true\">\n {time ? <span className={styles.time}>{time}</span> : null}\n {!summary.muted && summary.unreadCount ? (\n <span className={styles.unread}>{summary.unreadCount}</span>\n ) : null}\n </div>\n </div>\n );\n}\n","import * as React from 'react';\nimport { Avatar, type PresenceBadgeStatus } from '@fluentui/react-components';\nimport type { AgentParticipant } from '../core';\nimport type { PresenceState } from './types';\n\nexport interface AgentAvatarProps {\n participant?: AgentParticipant;\n presence?: PresenceState;\n size?: 24 | 28 | 32 | 36 | 40 | 48;\n name?: string;\n}\n\nconst STATUS: Record<PresenceState, PresenceBadgeStatus | undefined> = {\n available: 'available',\n busy: 'busy',\n away: 'away',\n offline: 'offline',\n dnd: 'do-not-disturb',\n unknown: 'unknown',\n};\n\n/**\n * ★ `Avatar` and `PresenceBadge` are measured tabster-safe (`react-avatar` imports only\n * `createCustomFocusIndicatorStyle`; `react-badge` has no tabster dependency at all), so\n * these are Fluent's rather than in-tree.\n *\n * ★ `AvatarGroup` is NOT — it pulls `react-popover`, which reaches `useModalAttributes`. If a\n * facepile is ever wanted, that is the component to check first.\n */\nexport function AgentAvatar({ participant, presence, size = 32, name }: AgentAvatarProps): React.ReactElement {\n const displayName = name ?? participant?.displayName ?? 'Unknown';\n return (\n <Avatar\n name={displayName}\n initials={participant?.initials}\n image={participant?.imageUrl ? { src: participant.imageUrl } : undefined}\n size={size}\n badge={presence ? { status: STATUS[presence] ?? 'unknown' } : undefined}\n // The badge is decorative here: presence is carried in the ROW's accessible name, so a\n // screen reader does not hear it twice.\n aria-hidden={undefined}\n />\n );\n}\n","import * as React from 'react';\nimport {\n Button, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Tab, TabList, Text,\n makeStyles, tokens,\n} from '@fluentui/react-components';\nimport { MoreHorizontalRegular } from '@fluentui/react-icons';\nimport type { AgentParticipant } from '../core';\nimport type { PresenceState } from './types';\nimport { AgentAvatar } from './AgentAvatar';\n\nexport interface ConversationTab {\n id: string;\n label: string;\n}\n\nexport interface HeaderAction {\n key: string;\n label: string;\n icon?: React.ReactElement;\n onClick: () => void;\n}\n\nexport interface ConversationHeaderProps {\n title: string;\n subtitle?: string;\n participant?: AgentParticipant;\n presence?: PresenceState;\n tabs?: readonly ConversationTab[];\n selectedTabId?: string;\n onTabSelect?: (id: string) => void;\n actions?: readonly HeaderAction[];\n /** Rendered right of the tabs — a search box, a right-pane toggle. */\n trailing?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: tokens.spacingVerticalXS,\n padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalM} 0`,\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n },\n top: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS },\n identity: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, minWidth: 0 },\n titles: { display: 'flex', flexDirection: 'column', minWidth: 0 },\n subtitle: { color: tokens.colorNeutralForeground3, fontSize: tokens.fontSizeBase200 },\n spacer: { flex: 1 },\n tabRow: { display: 'flex', alignItems: 'flex-end', gap: tokens.spacingHorizontalS },\n});\n\n/**\n * The bar above the transcript: who you are talking to, the tab strip, and the actions.\n *\n * ★★ The tab strip is Fluent's real `TabList`, and that is DELIBERATE. `react-tabs` reaches\n * `useArrowNavigationGroup` → `getMover` → tabster, but rebuilding it by hand is not the\n * \"simple horizontal list\" it looks like: tabster's Mover carries RTL inversion,\n * Home/End/PageUp/PageDown, cyclic wrap, disabled-item skipping, and a caret-position guard\n * that declines arrow keys while the caret is inside a text input — roughly 120-180 LOC to\n * reproduce, against a widget nobody has tested. Per the split-by-cost decision the kit uses\n * Fluent's and the PCF host supplies an isolated `targetDocument`; the coexistence spike\n * measured that two tabster cores share a window without double-handling.\n *\n * ★ Manual activation (Fluent's default, `selectTabOnFocus` off): arrowing through the tabs must\n * not fire N conversation loads on the way past.\n *\n * ★ `aria-controls` is NOT set here. The panel these tabs govern is rendered by the consumer,\n * elsewhere in the tree, so the id contract would have to cross components — and an\n * `aria-controls` pointing at nothing is worse than none. Pass `panelId` when that contract\n * exists; until then the relationship is left unstated rather than stated falsely.\n */\nexport function ConversationHeader(props: ConversationHeaderProps): React.ReactElement {\n const {\n title, subtitle, participant, presence, tabs, selectedTabId, onTabSelect, actions, trailing,\n } = props;\n const styles = useStyles();\n\n const inline = (actions ?? []).slice(0, 2);\n const overflow = (actions ?? []).slice(2);\n\n return (\n <header className={styles.root}>\n <div className={styles.top}>\n <div className={styles.identity}>\n <AgentAvatar participant={participant} presence={presence} size={32} name={title} />\n <div className={styles.titles}>\n <Text weight=\"semibold\" truncate wrap={false}>\n {title}\n </Text>\n {subtitle ? <span className={styles.subtitle}>{subtitle}</span> : null}\n </div>\n </div>\n\n <div className={styles.spacer} />\n {trailing}\n\n {inline.map((action) => (\n <Button\n key={action.key}\n appearance=\"subtle\"\n size=\"small\"\n icon={action.icon}\n aria-label={action.label}\n onClick={action.onClick}\n />\n ))}\n\n {overflow.length > 0 ? (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<MoreHorizontalRegular />}\n aria-label={`More actions, ${overflow.length} available`}\n />\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {overflow.map((action) => (\n <MenuItem key={action.key} icon={action.icon} onClick={action.onClick}>\n {action.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n ) : null}\n </div>\n\n {tabs && tabs.length > 0 ? (\n <div className={styles.tabRow}>\n <TabList\n selectedValue={selectedTabId}\n onTabSelect={(_, data) => onTabSelect?.(data.value as string)}\n size=\"small\"\n >\n {tabs.map((tab) => (\n <Tab key={tab.id} value={tab.id}>\n {tab.label}\n </Tab>\n ))}\n </TabList>\n </div>\n ) : null}\n </header>\n );\n}\n","import * as React from 'react';\nimport { Button, makeStyles, tokens, Text } from '@fluentui/react-components';\nimport { DismissRegular } from '@fluentui/react-icons';\n\nexport interface RightPaneProps {\n open: boolean;\n title: string;\n onClose: () => void;\n children?: React.ReactNode;\n width?: number;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n borderLeft: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n minHeight: 0,\n },\n head: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: tokens.spacingHorizontalS,\n padding: tokens.spacingVerticalS,\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n },\n body: { flex: 1, overflowY: 'auto', padding: tokens.spacingVerticalM },\n});\n\n/**\n * The detail pane beside the conversation — sources, a record, a trace.\n *\n * ★ A plain `<aside>`, NOT Fluent's `Drawer`. `react-drawer` composes dialog internals, and an\n * inline pane needs none of a drawer's modality: it sits in the layout rather than over it.\n */\nexport function RightPane({ open, title, onClose, children, width = 320 }: RightPaneProps): React.ReactElement | null {\n const styles = useStyles();\n const labelId = React.useId();\n if (!open) return null;\n\n return (\n <aside className={styles.root} style={{ width }} aria-labelledby={labelId}>\n <div className={styles.head}>\n <Text id={labelId} weight=\"semibold\">\n {title}\n </Text>\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<DismissRegular />}\n onClick={onClose}\n aria-label={`Close ${title}`}\n />\n </div>\n <div className={styles.body}>{children}</div>\n </aside>\n );\n}\n","import * as React from 'react';\nimport { SearchBox, makeStyles } from '@fluentui/react-components';\n\nexport interface GlobalSearchBarProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n placeholder?: string;\n}\n\nconst useStyles = makeStyles({\n root: { width: '100%', maxWidth: '640px' },\n});\n\n/** ★ `SearchBox` is `react-search`, which has no tabster dependency — safe. */\nexport function GlobalSearchBar({\n value,\n onChange,\n onSubmit,\n placeholder = 'Search conversations',\n}: GlobalSearchBarProps): React.ReactElement {\n const styles = useStyles();\n return (\n <SearchBox\n className={styles.root}\n value={value}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(_, data) => onChange(data.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && onSubmit) onSubmit(value);\n }}\n />\n );\n}\n","import * as React from 'react';\nimport { Tooltip, makeStyles, tokens } from '@fluentui/react-components';\nimport type { AgentSource } from '../core';\n\nexport interface CitationChipProps {\n marker: string;\n source?: AgentSource;\n onOpen?: (source: AgentSource) => void;\n}\n\nconst useStyles = makeStyles({\n chip: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: '18px',\n height: '18px',\n padding: `0 ${tokens.spacingHorizontalXXS}`,\n marginLeft: '2px',\n verticalAlign: 'super',\n fontSize: tokens.fontSizeBase100,\n lineHeight: '18px',\n borderRadius: tokens.borderRadiusSmall,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground3,\n color: tokens.colorNeutralForeground2,\n cursor: 'pointer',\n ':hover': { backgroundColor: tokens.colorNeutralBackground3Hover },\n ':focus-visible': { outline: `2px solid ${tokens.colorStrokeFocus2}`, outlineOffset: '1px' },\n },\n inert: { cursor: 'default' },\n});\n\n/** An inline `[1]`. ★ `Tooltip` is measured tabster-safe (`react-tooltip` imports only\n * `useIsNavigatingWithKeyboard`), so this one is Fluent's rather than in-tree. */\nexport function CitationChip({ marker, source, onOpen }: CitationChipProps): React.ReactElement {\n const styles = useStyles();\n const label = source ? `Source ${marker}: ${source.title}` : `Source ${marker}`;\n\n if (!source || !onOpen) {\n return (\n <span className={`${styles.chip} ${styles.inert}`} aria-label={label}>\n {marker}\n </span>\n );\n }\n return (\n <Tooltip content={source.title} relationship=\"description\" withArrow>\n <button type=\"button\" className={styles.chip} aria-label={label} onClick={() => onOpen(source)}>\n {marker}\n </button>\n </Tooltip>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport { renumberCitations, type AgentSource } from '../core';\nimport { Disclosure } from '../internal';\nimport { SourceCard } from './SourceCard';\n\nexport interface CitationListProps {\n /** The answer text — used to work out which sources were actually cited. */\n text: string;\n sources: readonly AgentSource[];\n onOpenSource?: (source: AgentSource) => void;\n defaultOpen?: boolean;\n}\n\nconst useStyles = makeStyles({\n list: { display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalXS, listStyle: 'none', margin: 0, padding: 0 },\n});\n\n/**\n * The sources under an answer.\n *\n * ★★ IT SHOWS ONLY THE SOURCES THE TEXT ACTUALLY CITES. A retriever commonly returns a dozen\n * chunks for a two-citation answer, and listing all twelve implies the answer rests on\n * twelve things when it rests on two. That overstated provenance is what makes a citation\n * panel decorative instead of trustworthy, so `renumberCitations` drops the uncited ones\n * and renumbers what remains into first-appearance order.\n *\n * ★ A Disclosure, not Fluent's `Accordion`: APG's disclosure pattern is `<button aria-expanded\n * aria-controls>` and a labelled region, and `Accordion` reaches `useArrowNavigationGroup`\n * to add arrow-key movement between headers that a single source list does not need.\n */\nexport function CitationList({\n text,\n sources,\n onOpenSource,\n defaultOpen = false,\n}: CitationListProps): React.ReactElement | null {\n const styles = useStyles();\n const id = React.useId();\n const { used, citations } = React.useMemo(() => renumberCitations(text, sources), [text, sources]);\n\n if (used.length === 0) return null;\n\n const markerFor = (sourceId: string) => citations.find((c) => c.sourceId === sourceId)?.marker;\n\n return (\n <Disclosure\n id={id}\n defaultOpen={defaultOpen}\n summary={`${used.length} source${used.length === 1 ? '' : 's'}`}\n >\n <ul className={styles.list}>\n {used.map((source) => (\n <li key={source.id}>\n <SourceCard source={source} marker={markerFor(source.id)} onOpen={onOpenSource} />\n </li>\n ))}\n </ul>\n </Disclosure>\n );\n}\n","import * as React from 'react';\nimport { Button, Text, makeStyles, tokens } from '@fluentui/react-components';\nimport {\n DocumentRegular, DatabaseRegular, GlobeRegular, BookRegular, DocumentBulletListRegular,\n} from '@fluentui/react-icons';\nimport type { AgentSource } from '../core';\nimport { CardSurface } from '../internal';\n\nexport interface SourceCardProps {\n source: AgentSource;\n /** The marker this source was cited as, if any. */\n marker?: string;\n onOpen?: (source: AgentSource) => void;\n showSnippet?: boolean;\n}\n\nconst ICONS = {\n dataverse: DatabaseRegular,\n document: DocumentRegular,\n web: GlobeRegular,\n knowledge: BookRegular,\n other: DocumentBulletListRegular,\n} as const;\n\nconst useStyles = makeStyles({\n root: { gap: tokens.spacingVerticalXXS },\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS },\n marker: { color: tokens.colorNeutralForeground3, fontSize: tokens.fontSizeBase200 },\n snippet: { color: tokens.colorNeutralForeground2, fontSize: tokens.fontSizeBase200 },\n meta: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, marginTop: tokens.spacingVerticalXXS },\n});\n\nexport function SourceCard({ source, marker, onOpen, showSnippet = true }: SourceCardProps): React.ReactElement {\n const styles = useStyles();\n const Icon = ICONS[source.kind] ?? ICONS.other;\n\n return (\n <CardSurface className={styles.root}>\n <div className={styles.head}>\n <Icon aria-hidden=\"true\" />\n {marker ? <span className={styles.marker}>[{marker}]</span> : null}\n <Text weight=\"semibold\">{source.title}</Text>\n </div>\n {showSnippet && source.snippet ? <span className={styles.snippet}>{source.snippet}</span> : null}\n <div className={styles.meta}>\n {/* ★ The kit never calls Xrm. It raises a callback and the HOST navigates. */}\n {onOpen && (source.recordId || source.url) ? (\n <Button size=\"small\" appearance=\"subtle\" onClick={() => onOpen(source)}>\n {source.recordId ? 'Open record' : 'Open'}\n </Button>\n ) : null}\n {/* ★ \"not reported\" is shown as such, never as zero confidence — a retriever that\n returns no score and one that returns 0 mean completely different things. */}\n <span className={styles.snippet}>\n {source.score === undefined ? 'Relevance not reported' : `Relevance ${Math.round(source.score * 100)}%`}\n </span>\n </div>\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { makeStyles } from '@fluentui/react-components';\nimport { splitTextByCitations, type AgentCitation, type AgentSource } from '../core';\nimport { CitationChip } from './CitationChip';\n\nexport interface AnswerWithCitationsProps {\n text: string;\n citations?: readonly AgentCitation[];\n sources?: readonly AgentSource[];\n onOpenSource?: (source: AgentSource) => void;\n}\n\nconst useStyles = makeStyles({ root: { whiteSpace: 'pre-wrap', wordBreak: 'break-word' } });\n\n/** Renders the answer with a chip where each marker was. */\nexport function AnswerWithCitations({\n text,\n citations = [],\n sources = [],\n onOpenSource,\n}: AnswerWithCitationsProps): React.ReactElement {\n const styles = useStyles();\n const segments = React.useMemo(() => splitTextByCitations(text, citations), [text, citations]);\n const byId = React.useMemo(() => new Map(sources.map((s) => [s.id, s])), [sources]);\n\n return (\n <span className={styles.root}>\n {segments.map((segment, i) =>\n segment.kind === 'text' ? (\n <React.Fragment key={i}>{segment.text}</React.Fragment>\n ) : (\n <CitationChip\n key={i}\n marker={segment.marker ?? ''}\n source={segment.sourceId ? byId.get(segment.sourceId) : undefined}\n onOpen={onOpenSource}\n />\n ),\n )}\n </span>\n );\n}\n","import * as React from 'react';\nimport { Text, makeStyles, tokens } from '@fluentui/react-components';\nimport { Disclosure } from '../internal';\n\nexport interface GroundingPanelProps {\n /** The SAME object passed as `AgentTurn.grounding`. */\n grounding?: Record<string, unknown>;\n title?: string;\n defaultOpen?: boolean;\n}\n\nconst useStyles = makeStyles({\n grid: {\n display: 'grid',\n gridTemplateColumns: 'minmax(96px, max-content) 1fr',\n gap: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalM}`,\n margin: 0,\n fontSize: tokens.fontSizeBase200,\n },\n key: { color: tokens.colorNeutralForeground3, margin: 0 },\n value: { margin: 0, wordBreak: 'break-word', fontFamily: tokens.fontFamilyMonospace },\n empty: { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 },\n});\n\nfunction render(value: unknown): string {\n if (value === null || value === undefined) return '—';\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * What the model was told.\n *\n * ★★ It renders the SAME object the turn carried (`AgentTurn.grounding`), which is the point:\n * the facts the host computed deterministically and the facts shown on screen cannot drift\n * apart, because there is only one of them. The model EXPLAINS these; it must never be the\n * thing that derives them — a hallucinated identifier is worse than no answer.\n *\n * ★ A definition list on a CSS grid, not a `Table`: `react-table` reaches\n * `useArrowNavigationGroup`, and key/value pairs are not tabular data.\n */\nexport function GroundingPanel({\n grounding,\n title = 'What this answer used',\n defaultOpen = false,\n}: GroundingPanelProps): React.ReactElement | null {\n const styles = useStyles();\n const id = React.useId();\n const entries = Object.entries(grounding ?? {});\n if (entries.length === 0) return null;\n\n return (\n <Disclosure id={id} defaultOpen={defaultOpen} summary={title}>\n <dl className={styles.grid}>\n {entries.map(([key, value]) => (\n <React.Fragment key={key}>\n <dt className={styles.key}>{key}</dt>\n <dd className={styles.value}>{render(value)}</dd>\n </React.Fragment>\n ))}\n </dl>\n <Text as=\"p\" className={styles.empty}>\n These facts were supplied by the app, not produced by the model.\n </Text>\n </Disclosure>\n );\n}\n","import * as React from 'react';\nimport { makeStyles, tokens } from '@fluentui/react-components';\nimport { ShieldErrorRegular } from '@fluentui/react-icons';\nimport type { AgentMessage } from '../core';\n\nexport interface ProviderAttributionProps {\n provider?: string;\n model?: string;\n guarded?: boolean;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacingHorizontalXXS,\n fontSize: tokens.fontSizeBase100,\n color: tokens.colorNeutralForeground3,\n },\n guarded: { color: tokens.colorPaletteDarkOrangeForeground1 },\n});\n\n/**\n * Who produced this answer.\n *\n * ★★ WHEN `guarded` IS SET THE VISIBLE TEXT MUST CHANGE, and that is the whole contract.\n * `guarded` means the provider WITHHELD its generated answer and substituted safe text.\n * Attributing that substitute to the model as if it were the model's words is the\n * misattribution this component exists to prevent — so the difference is in words a reader\n * sees, not a colour, an icon or a `data-` attribute. The gate asserts BOTH directions.\n */\nexport function ProviderAttribution({ provider, model, guarded }: ProviderAttributionProps): React.ReactElement | null {\n const styles = useStyles();\n if (!provider && !model && !guarded) return null;\n\n const who = [provider, model].filter(Boolean).join(' · ');\n\n if (guarded) {\n return (\n <span className={`${styles.root} ${styles.guarded}`}>\n <ShieldErrorRegular aria-hidden=\"true\" />\n Withheld and replaced with safe text{who ? ` — not ${who}'s words` : ''}\n </span>\n );\n }\n return <span className={styles.root}>Answered by {who || 'the agent'}</span>;\n}\n\n/** Convenience: read the attribution straight off a message. */\nexport function messageAttribution(message: AgentMessage): ProviderAttributionProps {\n return { provider: message.provider, model: message.usage?.model, guarded: message.guarded };\n}\n","import * as React from 'react';\nimport { Text, makeStyles, tokens } from '@fluentui/react-components';\nimport { CardSurface } from '../internal';\n\nexport interface ActionCardProps {\n title: string;\n description?: React.ReactNode;\n icon?: React.ReactElement;\n /** Renders an emphasised edge while a decision is outstanding. */\n pending?: boolean;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n}\n\nconst useStyles = makeStyles({\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS },\n description: { color: tokens.colorNeutralForeground2, fontSize: tokens.fontSizeBase200 },\n footer: { display: 'flex', gap: tokens.spacingHorizontalS, justifyContent: 'flex-end', marginTop: tokens.spacingVerticalXS },\n});\n\n/** The container the action family shares. ★ Built on the in-tree `CardSurface`, never Fluent's\n * `Card` — see internal/CardSurface.tsx for why that one unmounts the tree on a form. */\nexport function ActionCard({ title, description, icon, pending, children, footer }: ActionCardProps): React.ReactElement {\n const styles = useStyles();\n return (\n <CardSurface emphasis={pending ? 'attention' : 'none'}>\n <div className={styles.head}>\n {icon ? React.cloneElement(icon, { 'aria-hidden': 'true' } as Record<string, unknown>) : null}\n <Text weight=\"semibold\">{title}</Text>\n </div>\n {description ? <span className={styles.description}>{description}</span> : null}\n {children}\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { Button, Spinner, makeStyles, tokens } from '@fluentui/react-components';\nimport { CheckmarkRegular, DismissRegular, EditRegular } from '@fluentui/react-icons';\nimport type { AgentToolCall } from '../core';\nimport { ActionCard } from './ActionCard';\nimport { ParameterReview } from './ParameterReview';\nimport { ActionResult } from './ActionResult';\n\nexport interface ApprovalCardProps {\n toolCall: AgentToolCall;\n onApprove: (call: AgentToolCall, argumentsJson: string) => void;\n onDeny: (call: AgentToolCall) => void;\n /** Enables in-place editing of the proposed arguments before approval. */\n allowEdit?: boolean;\n busy?: boolean;\n}\n\nconst useStyles = makeStyles({\n busy: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS, fontSize: tokens.fontSizeBase200 },\n});\n\n/**\n * A tool call awaiting a human decision.\n *\n * ★★ THE KIT DOES NOT RUN THE TOOL. It renders the request and raises a callback; the HOST\n * executes and feeds the outcome back as a `tool_result` event. That is what keeps \"the kit\n * has no tools\" a structural statement about this package rather than a promise about a\n * prompt — `IAgentService` has no method that could invoke one.\n *\n * ★★ IT CANNOT DOUBLE-SUBMIT, and that is asserted two ways, because counting the callback\n * alone is a one-field signature: it shows what the component SENT, and a card that\n * re-enables after an async settle would still submit twice later. The gate asserts one\n * `onApprove` across two synchronous clicks AND that the control is disabled afterwards.\n */\nexport function ApprovalCard({\n toolCall, onApprove, onDeny, allowEdit = false, busy = false,\n}: ApprovalCardProps): React.ReactElement {\n const styles = useStyles();\n const [args, setArgs] = React.useState(toolCall.argumentsJson);\n const [editing, setEditing] = React.useState(false);\n // Latched locally: the decision is final from this card's point of view the moment it is\n // made, regardless of how long the host takes to report a status back.\n const [decided, setDecided] = React.useState(false);\n\n const settled =\n toolCall.status === 'succeeded' || toolCall.status === 'failed' || toolCall.status === 'denied';\n\n if (settled) {\n return (\n <ActionCard title={toolCall.name} description=\"Tool call\">\n <ParameterReview argumentsJson={toolCall.argumentsJson} />\n <ActionResult\n status={toolCall.status === 'succeeded' ? 'succeeded' : toolCall.status === 'denied' ? 'denied' : 'failed'}\n message={toolCall.resultText ?? toolCall.failure?.message ?? 'Completed.'}\n correlationId={toolCall.failure?.correlationId}\n />\n </ActionCard>\n );\n }\n\n const locked = decided || busy || toolCall.status === 'running';\n\n const approve = () => {\n if (locked) return;\n setDecided(true);\n onApprove(toolCall, args);\n };\n const deny = () => {\n if (locked) return;\n setDecided(true);\n onDeny(toolCall);\n };\n\n return (\n <ActionCard\n title={toolCall.name}\n description=\"The agent is asking to run this. Check the details before approving.\"\n pending={!locked}\n footer={\n locked ? (\n <span className={styles.busy}>\n <Spinner size=\"tiny\" /> Submitting…\n </span>\n ) : (\n <>\n {allowEdit ? (\n <Button size=\"small\" icon={<EditRegular />} onClick={() => setEditing((v) => !v)}>\n {editing ? 'Done editing' : 'Edit'}\n </Button>\n ) : null}\n <Button size=\"small\" icon={<DismissRegular />} onClick={deny} disabled={locked}>\n Deny\n </Button>\n <Button size=\"small\" appearance=\"primary\" icon={<CheckmarkRegular />} onClick={approve} disabled={locked}>\n Approve\n </Button>\n </>\n )\n }\n >\n <ParameterReview argumentsJson={args} readOnly={!editing} onChange={setArgs} />\n </ActionCard>\n );\n}\n","import * as React from 'react';\nimport { Input, makeStyles, tokens, Text } from '@fluentui/react-components';\n\nexport interface ParameterReviewProps {\n /** RAW arguments as the model emitted them. */\n argumentsJson: string;\n readOnly?: boolean;\n onChange?: (next: string) => void;\n}\n\nconst useStyles = makeStyles({\n grid: {\n display: 'grid',\n gridTemplateColumns: 'minmax(110px, max-content) 1fr',\n gap: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalM}`,\n alignItems: 'center',\n margin: 0,\n },\n key: { margin: 0, color: tokens.colorNeutralForeground2, fontSize: tokens.fontSizeBase200 },\n value: { margin: 0 },\n raw: {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n fontFamily: tokens.fontFamilyMonospace,\n fontSize: tokens.fontSizeBase200,\n color: tokens.colorNeutralForeground2,\n },\n});\n\n/**\n * The arguments a tool call is proposing, laid out for a human to check before approving.\n *\n * ★ A definition list on a CSS grid, NOT a `Table`/`DataGrid` — both reach\n * `useArrowNavigationGroup`, and this is key/value data rather than a grid.\n *\n * ★★ It falls back to showing the RAW string when the JSON does not parse, and that matters:\n * a half-streamed arguments blob is not valid JSON, and an approval UI that silently\n * rendered nothing would ask the user to approve something they cannot see. Showing the raw\n * text is honest; showing an empty table is not.\n */\nexport function ParameterReview({ argumentsJson, readOnly = true, onChange }: ParameterReviewProps): React.ReactElement {\n const styles = useStyles();\n\n const parsed = React.useMemo<Record<string, unknown> | null>(() => {\n try {\n const value: unknown = JSON.parse(argumentsJson);\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n }, [argumentsJson]);\n\n if (!parsed) {\n return (\n <div>\n <Text size={200}>Arguments (unparsed)</Text>\n <pre className={styles.raw}>{argumentsJson || '(empty)'}</pre>\n </div>\n );\n }\n\n const set = (key: string, next: string) => {\n if (!onChange) return;\n onChange(JSON.stringify({ ...parsed, [key]: next }));\n };\n\n return (\n <dl className={styles.grid}>\n {Object.entries(parsed).map(([key, value]) => (\n <React.Fragment key={key}>\n <dt className={styles.key}>{key}</dt>\n <dd className={styles.value}>\n {readOnly ? (\n <span className={styles.raw}>{typeof value === 'string' ? value : JSON.stringify(value)}</span>\n ) : (\n <Input\n size=\"small\"\n aria-label={key}\n value={typeof value === 'string' ? value : JSON.stringify(value)}\n onChange={(_, data) => set(key, data.value)}\n />\n )}\n </dd>\n </React.Fragment>\n ))}\n </dl>\n );\n}\n","import * as React from 'react';\nimport { MessageBar, MessageBarBody, MessageBarTitle, MessageBarActions, Button, makeStyles, tokens } from '@fluentui/react-components';\n\nexport interface ActionResultProps {\n status: 'succeeded' | 'failed' | 'denied';\n message: string;\n correlationId?: string;\n onRetry?: () => void;\n}\n\nconst INTENT = { succeeded: 'success', failed: 'error', denied: 'warning' } as const;\nconst TITLE = { succeeded: 'Done', failed: 'Failed', denied: 'Not approved' } as const;\n\nconst useStyles = makeStyles({\n id: { display: 'block', marginTop: tokens.spacingVerticalXXS, fontSize: tokens.fontSizeBase100, color: tokens.colorNeutralForeground3, fontFamily: tokens.fontFamilyMonospace },\n});\n\n/** ★ The correlation id is surfaced, not hidden: it is the only thing that lets someone paged\n * at 3am find this specific run in App Insights. */\nexport function ActionResult({ status, message, correlationId, onRetry }: ActionResultProps): React.ReactElement {\n const styles = useStyles();\n return (\n <MessageBar intent={INTENT[status]}>\n <MessageBarBody>\n <MessageBarTitle>{TITLE[status]}</MessageBarTitle>\n {message}\n {correlationId ? <span className={styles.id}>Correlation id: {correlationId}</span> : null}\n </MessageBarBody>\n {status === 'failed' && onRetry ? (\n <MessageBarActions>\n <Button size=\"small\" onClick={onRetry}>Try again</Button>\n </MessageBarActions>\n ) : null}\n </MessageBar>\n );\n}\n","import * as React from 'react';\nimport { Badge, Spinner, makeStyles, tokens } from '@fluentui/react-components';\nimport type { AgentToolCall, ToolCallStatus } from '../core';\nimport { Disclosure, CardSurface } from '../internal';\nimport { ParameterReview } from './ParameterReview';\n\nexport interface ToolCallCardProps {\n toolCall: AgentToolCall;\n defaultExpanded?: boolean;\n}\n\nconst LABEL: Record<ToolCallStatus, string> = {\n proposed: 'Proposed',\n running: 'Running',\n succeeded: 'Succeeded',\n failed: 'Failed',\n denied: 'Denied',\n};\nconst COLOUR: Record<ToolCallStatus, 'informative' | 'success' | 'danger' | 'warning'> = {\n proposed: 'informative',\n running: 'informative',\n succeeded: 'success',\n failed: 'danger',\n denied: 'warning',\n};\n\nconst useStyles = makeStyles({\n head: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalXS },\n name: { fontFamily: tokens.fontFamilyMonospace, fontSize: tokens.fontSizeBase200 },\n result: {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n fontFamily: tokens.fontFamilyMonospace,\n fontSize: tokens.fontSizeBase200,\n marginTop: tokens.spacingVerticalXS,\n },\n});\n\n/** A tool call that needed no approval — collapsed by default, expandable for the arguments.\n * ★ A Disclosure rather than `Accordion`: see internal/Disclosure.tsx. */\nexport function ToolCallCard({ toolCall, defaultExpanded = false }: ToolCallCardProps): React.ReactElement {\n const styles = useStyles();\n const id = React.useId();\n\n return (\n <CardSurface>\n <Disclosure\n id={id}\n defaultOpen={defaultExpanded}\n summary={\n <span className={styles.head}>\n <span className={styles.name}>{toolCall.name}</span>\n {/* ★ The status is in the LABEL, not only in the badge colour (WCAG 1.4.1). */}\n <Badge appearance=\"tint\" color={COLOUR[toolCall.status]}>\n {LABEL[toolCall.status]}\n </Badge>\n {toolCall.status === 'running' ? <Spinner size=\"extra-tiny\" /> : null}\n </span>\n }\n >\n <ParameterReview argumentsJson={toolCall.argumentsJson} />\n {toolCall.resultText ? <div className={styles.result}>{toolCall.resultText}</div> : null}\n {toolCall.failure ? <div className={styles.result}>{toolCall.failure.message}</div> : null}\n </Disclosure>\n </CardSurface>\n );\n}\n","import * as React from 'react';\nimport { FluentProvider, IdPrefixProvider, type Theme } from '@fluentui/react-components';\nimport { resolveHostTheme } from '../theme';\nimport { nextAgentIdPrefix } from './idPrefix';\n\nexport interface AgentKitHostProviderProps {\n children?: React.ReactNode;\n /** An explicit theme wins over everything. */\n theme?: Theme;\n /** The Dynamics host's theme — `context.fluentDesignLanguage?.tokenTheme` in a PCF. */\n hostTheme?: Theme;\n isDarkTheme?: boolean;\n /**\n * The document Fluent should treat as its own.\n *\n * ★★ THIS IS THE PCF ESCAPE HATCH, and it is why it is a prop rather than something the\n * kit decides. Fluent v9's tabster is a per-WINDOW singleton: `createTabster` returns\n * `win.__tabsterInstance` if one exists. A Dynamics form installs tabster 8.2.0, whose\n * core has no `attrHandlers`, while a bundled control ships 8.8.x — so the moment a\n * component reaches a `get*` factory (`TabList` -> `useArrowNavigationGroup` -> `getMover`),\n * `core.attrHandlers.set` throws and React unmounts the whole tree.\n *\n * `useTabster` reads `targetDocument` from Fluent's context and hands\n * `targetDocument.defaultView` to `createTabster`. So a host that passes a proxied\n * document with a private `__tabsterInstance` slot gets its own core, and everything\n * below inherits it — with no change to any agent-kit component.\n *\n * The proxy itself is NOT shipped here; it lives with the PCF gallery\n * (`controls/_shared/tabsterIsolation.ts`). A host writes one line:\n * `targetDocument={createIsolatedTargetDocument(document)}`\n *\n * ★ It isolates tabster and portal mount nodes, NOT Griffel: `FluentProvider` consumes\n * the ambient Griffel renderer rather than building one from this prop. That is\n * harmless for the proxy case (styles land in the real <head> either way) but means\n * this prop alone does NOT make the kit work in a separate document or shadow root —\n * that additionally needs `<RendererProvider renderer={createDOMRenderer(doc)}>`.\n */\n targetDocument?: Document;\n /** Override the generated prefix. Only for tests that need a stable value. */\n idPrefix?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * The host wrapper: `IdPrefixProvider` ▸ `FluentProvider` ▸ children.\n *\n * ★ No agent-kit COMPONENT renders a provider — that is surface-kit's convention and this\n * kit keeps it, so a host that already has a `FluentProvider` is not given a second one.\n * This is an opt-in export for hosts that do not, and it exists for a second reason: a\n * rule that lives only in a README is a rule nothing can test. Shipping the wrapper gives\n * the IdPrefix gate a subject inside `src/`, so its sabotage lands on real code instead of\n * on the test's own fixture.\n *\n * ★ Ordering is load-bearing: `IdPrefixProvider` must be OUTSIDE `FluentProvider`, because\n * the provider reads the prefix while generating the id for its own theme <style> tag.\n */\nexport function AgentKitHostProvider(props: AgentKitHostProviderProps): React.ReactElement {\n const { children, theme, hostTheme, isDarkTheme, targetDocument, className, style } = props;\n\n // Generated ONCE per mounted instance — not per render, and not shared across instances.\n const [generated] = React.useState(nextAgentIdPrefix);\n const idPrefix = props.idPrefix ?? generated;\n\n const resolved = React.useMemo(\n () => resolveHostTheme({ theme, hostTheme, isDarkTheme }),\n [theme, hostTheme, isDarkTheme],\n );\n\n return (\n <IdPrefixProvider value={idPrefix}>\n <FluentProvider\n theme={resolved}\n targetDocument={targetDocument}\n className={className}\n style={style}\n >\n {children}\n </FluentProvider>\n </IdPrefixProvider>\n );\n}\n","import type { BrandVariants, Theme } from '@fluentui/react-components';\nimport {\n createDynamicsV9Theme,\n createDynamicsV9DarkTheme,\n dynamicsBrandRamp,\n} from '@dataverse-kit/fluent-theme';\nimport { typography, radius } from '@dataverse-kit/design-tokens';\n\n/**\n * The Dynamics CE look, for conversational surfaces.\n *\n * ★ The brand ramp and the base builders are NOT declared here — they come from\n * `@dataverse-kit/fluent-theme`, the single declaration shared with grid-kit/v9 and\n * surface-kit/v9. agent-kit adds only the two things that differ for a chat surface.\n */\nfunction applyAgentOverrides(base: Theme): Theme {\n return {\n ...base,\n // Fluent's web theme is close to CE but does not pin the Web variant of Segoe.\n fontFamilyBase: typography.fontFamily,\n // CE is squarer than Fluent web's default. Bubbles opt back up to borderRadiusLarge.\n borderRadiusMedium: radius.card,\n };\n}\n\nexport function createAgentTheme(brand: BrandVariants = dynamicsBrandRamp as BrandVariants): Theme {\n return applyAgentOverrides(createDynamicsV9Theme(brand));\n}\n\nexport function createAgentDarkTheme(\n brand: BrandVariants = dynamicsBrandRamp as BrandVariants,\n): Theme {\n return applyAgentOverrides(createDynamicsV9DarkTheme(brand));\n}\n\n/** Memoized module singletons. */\nexport const agentTheme: Theme = createAgentTheme();\nexport const agentDarkTheme: Theme = createAgentDarkTheme();\n\nexport interface ResolveHostThemeInput {\n /** An explicit theme always wins. */\n theme?: Theme;\n /** The Dynamics host's own theme — `context.fluentDesignLanguage?.tokenTheme` in a PCF. */\n hostTheme?: Theme;\n isDarkTheme?: boolean;\n}\n\n/**\n * Decide which theme to render with. ONE ladder, called by both `AgentKitHostProvider` and\n * the Storybook decorator so the two cannot drift.\n *\n * ★ The host theme wins over the kit's. That is the rule worth a gate, and the test that can\n * see it must supply a host theme whose brand DIFFERS from the kit's — a resolver that\n * silently ignored `hostTheme` looks identical to a correct one when the two happen to\n * agree.\n *\n * ★ The fallback is the Dynamics theme, not stock `webLightTheme`. The gallery controls fall\n * back to `webLightTheme` because in-host they always receive a real theme; a standalone\n * SWA or custom page has none, and stock Fluent does not read as Dynamics CE.\n */\nexport function resolveHostTheme(input: ResolveHostThemeInput = {}): Theme {\n if (input.theme) return input.theme;\n if (input.hostTheme) return input.hostTheme;\n return input.isDarkTheme ? agentDarkTheme : agentTheme;\n}\n","import { createIdPrefixCounter } from '../core/ids';\n\n/**\n * ★★★ ONE counter per bundle. This module-level singleton is the whole mechanism.\n *\n * React 18's `useId` restarts its counter per root. Put two Fluent v9 React roots on one\n * Dynamics form and both name their theme `<style>` tag `fui-FluentProviderr0`; the second\n * provider ADOPTS the first's tag and writes no rules into it, and whichever unmounts first\n * `.remove()`s it unconditionally. The result is a `<style>` with zero CSS rules — invisible\n * inside the form, because custom properties inherit, and fatal for anything PORTALLED\n * (menu listbox, tooltip, dialog, toaster), which mounts on `document.body` and renders\n * untheméd.\n *\n * ★ A CONSTANT prefix does not fix it: two instances of THIS control on one form would\n * collide with each other. Measured in the gallery, where a constant prefix was a real\n * candidate fix and was wrong.\n * ★ No dev harness can show this — a harness mounts one v9 root, so there is nothing to\n * collide with. The gate is a unit test: two renders, assert the provider classes differ.\n */\nexport const nextAgentIdPrefix = createIdPrefixCounter('dvkak');\n","import type { AgentRunStatus, AgentSource, AgentToolCall } from '../core/protocol';\n\n/**\n * What the mock can be driven to do. There is one scenario per terminal state plus the\n * interesting mid-stream shapes, because a Storybook that cannot SHOW a state is a Storybook\n * in which that state is never reviewed — and a test suite that cannot REACH one is a suite\n * in which it is never asserted.\n */\nexport type MockScenarioName =\n | 'happy'\n | 'grounded'\n | 'toolApproval'\n | 'toolAuto'\n | 'blocked'\n | 'refused'\n | 'error'\n | 'notProvisioned'\n | 'cancelled'\n | 'longAnswer'\n | 'throws';\n\nexport interface MockScenario {\n /** The answer, streamed word by word unless `chunks` overrides it. */\n text: string;\n chunks?: string[];\n status: AgentRunStatus;\n guarded?: boolean;\n failureMessage?: string;\n failureCode?: string;\n recoverable?: boolean;\n retryAfterMs?: number;\n sources?: AgentSource[];\n /** Emitted mid-stream, before the terminal event. */\n toolCall?: AgentToolCall;\n /** When set, the tool resolves itself rather than waiting for host approval. */\n autoToolResult?: string;\n suggestions?: string[];\n thinking?: string;\n /** Throw from inside the iterator — the failure channel a Promise-shaped seam does not have. */\n throwsMidStream?: boolean;\n /** Never becomes available; `send()` still yields a well-formed turn. */\n unavailable?: boolean;\n}\n\nconst SOURCES: AgentSource[] = [\n { id: 'src-acct', title: 'Contoso Ltd', kind: 'dataverse', entityLogicalName: 'account', recordId: '11111111-1111-1111-1111-111111111111', snippet: 'Annual revenue £4.2m, 38 employees.' },\n { id: 'src-case', title: 'Case 4417 — invoice mismatch', kind: 'dataverse', entityLogicalName: 'incident', recordId: '22222222-2222-2222-2222-222222222222', snippet: 'Raised 12 Mar, priority High.' },\n { id: 'src-kb', title: 'KB-208: credit note policy', kind: 'knowledge', url: 'https://example.invalid/kb/208', snippet: 'Credit notes above £5,000 require finance approval.', score: 0.82 },\n { id: 'src-doc', title: 'Statement-Mar.pdf', kind: 'document', snippet: 'Page 3 lists the disputed line.' },\n { id: 'src-web', title: 'Companies House filing', kind: 'web', url: 'https://example.invalid/ch' },\n];\n\nexport const mockScenarios: Record<MockScenarioName, MockScenario> = {\n happy: {\n text: 'Contoso has three open cases. The oldest, case 4417, has been waiting eleven days for a credit note.',\n status: 'succeeded',\n suggestions: ['Draft a credit note', 'Show all three cases', 'Who owns case 4417?'],\n },\n\n // ★ FIVE sources, but the text cites only [3] and [1] — and out of order. The panel must\n // show TWO, renumbered 1 and 2 in first-appearance order. A fixture where every source\n // is cited cannot tell a correct implementation from one that lists everything it was given.\n grounded: {\n text: 'Credit notes over £5,000 need finance approval [3], and case 4417 is for £6,200 [1]. So this one needs sign-off.',\n status: 'succeeded',\n sources: SOURCES,\n },\n\n toolApproval: {\n text: 'I can raise the credit note for you — approve the details below and I will submit it.',\n status: 'succeeded',\n toolCall: {\n id: 'call-1',\n name: 'create_credit_note',\n argumentsJson: '{\"accountId\":\"11111111-1111-1111-1111-111111111111\",\"amount\":6200,\"currency\":\"GBP\",\"reason\":\"Invoice mismatch, case 4417\"}',\n status: 'proposed',\n requiresApproval: true,\n },\n },\n\n toolAuto: {\n text: 'I checked the balance for you.',\n status: 'succeeded',\n toolCall: { id: 'call-2', name: 'get_account_balance', argumentsJson: '{\"accountId\":\"1111\"}', status: 'running' },\n autoToolResult: '{\"balance\":6200,\"currency\":\"GBP\"}',\n },\n\n // ★ blocked and refused MUST look different on screen: a content filter fired, versus the\n // model declining. They need different fixes, so they are different states.\n blocked: {\n text: 'I can’t help with that request.',\n status: 'blocked',\n guarded: true,\n failureMessage: 'The response was withheld by the content filter.',\n failureCode: 'content_filter',\n recoverable: false,\n },\n\n refused: {\n text: 'I don’t have enough information to answer that safely. Could you say which account you mean?',\n status: 'refused',\n failureMessage: 'The agent declined to answer.',\n recoverable: true,\n },\n\n error: {\n text: '',\n status: 'error',\n failureMessage: 'The agent is rate limited. Try again shortly.',\n failureCode: 'rate_limited',\n recoverable: true,\n retryAfterMs: 4000,\n },\n\n notProvisioned: {\n text: '',\n status: 'notProvisioned',\n failureMessage: 'No Foundry project is configured for this environment.',\n failureCode: 'not_provisioned',\n recoverable: false,\n unavailable: true,\n },\n\n cancelled: {\n text: 'Let me pull the last six months of activity for Contoso and work through it case by case, starting with the oldest…',\n status: 'cancelled',\n failureMessage: 'Stopped.',\n },\n\n // The fixture the autoscroll and live-region gates run against: enough deltas that\n // \"once, not per token\" is a meaningful distinction.\n longAnswer: {\n text: Array.from({ length: 200 }, (_, i) => `word${i + 1}`).join(' '),\n status: 'succeeded',\n },\n\n throws: {\n text: 'partial…',\n status: 'error',\n throwsMidStream: true,\n failureMessage: 'never reached — the iterator throws instead',\n },\n};\n","import type {\n AgentAvailability,\n AgentEvent,\n AgentTurn,\n AgentTurnResult,\n IAgentService,\n} from '../core/protocol';\nimport { mockScenarios, type MockScenario, type MockScenarioName } from './scenarios';\n\n/** Injectable so tests run at zero delay and Storybook runs at human speed. */\nexport type Scheduler = (ms: number) => Promise<void>;\n\nexport const realScheduler: Scheduler = (ms) =>\n new Promise((resolve) => setTimeout(resolve, ms));\nexport const immediateScheduler: Scheduler = () => Promise.resolve();\n\nexport interface MockAgentServiceOptions {\n scenario?: MockScenarioName;\n scheduler?: Scheduler;\n /** Delay before the first token, so the typing indicator is visible and screenshottable. */\n firstTokenMs?: number;\n chunkMs?: number;\n /**\n * ★ A CONSTRUCTOR ARGUMENT, never module state.\n *\n * tsup runs with `splitting: false`, so every entry gets a self-contained bundle and any\n * module-level `let` is physically duplicated per entry — a story importing from `.` and a\n * test importing from `./services` would get two independent counters. Measured on\n * surface-kit: three copies of the same function body across its entries.\n */\n seed?: number;\n /** Override availability; otherwise derived from the scenario. */\n availability?: AgentAvailability;\n}\n\n/** A tiny deterministic PRNG so Chromatic snapshots do not drift. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * The in-package fake. It is the only \"provider\" agent-kit ships: real transports (Foundry,\n * Copilot Studio, a broker) live in the consuming app, so the kit never holds a credential.\n *\n * ★ It can reach EVERY `AgentRunStatus`. A test asserts that, because a mock that cannot\n * produce a state is a state nothing downstream is ever tested against.\n */\nexport class MockAgentService implements IAgentService {\n readonly name = 'mock';\n\n private readonly scenario: MockScenario;\n private readonly scenarioName: MockScenarioName;\n private readonly scheduler: Scheduler;\n private readonly firstTokenMs: number;\n private readonly chunkMs: number;\n private readonly rand: () => number;\n private readonly availabilityOverride?: AgentAvailability;\n\n constructor(options: MockAgentServiceOptions = {}) {\n this.scenarioName = options.scenario ?? 'happy';\n this.scenario = mockScenarios[this.scenarioName];\n this.scheduler = options.scheduler ?? realScheduler;\n this.firstTokenMs = options.firstTokenMs ?? 400;\n this.chunkMs = options.chunkMs ?? 28;\n this.rand = mulberry32(options.seed ?? 1);\n this.availabilityOverride = options.availability;\n }\n\n async isAvailable(): Promise<AgentAvailability> {\n if (this.availabilityOverride) return this.availabilityOverride;\n if (this.scenario.unavailable) {\n return {\n available: false,\n status: 'notProvisioned',\n reason: this.scenario.failureMessage ?? 'Not provisioned.',\n };\n }\n return {\n available: true,\n capabilities: { streaming: true, tools: true, citations: true, attachments: true, cancel: true },\n };\n }\n\n /**\n * A prompt can select a scenario (`/blocked`, `/tool`, `/error`), so one story can walk\n * every state without remounting.\n */\n private resolveScenario(promptText: string): { name: MockScenarioName; scenario: MockScenario } {\n const slash = promptText.trim().match(/^\\/(\\w+)/)?.[1] as MockScenarioName | undefined;\n if (slash && slash in mockScenarios) {\n return { name: slash, scenario: mockScenarios[slash] };\n }\n return { name: this.scenarioName, scenario: this.scenario };\n }\n\n async *send(turn: AgentTurn): AsyncIterable<AgentEvent> {\n const { scenario } = this.resolveScenario(turn.text);\n const messageId = `mock-${Math.floor(this.rand() * 1e9).toString(36)}`;\n const turnId = `turn-${messageId}`;\n const provider = this.name;\n\n const finish = (result: Omit<AgentTurnResult, 'provider'>): AgentEvent => ({\n type: 'turn_end',\n turnId,\n messageId,\n result: { ...result, provider },\n });\n\n yield { type: 'turn_start', turnId, messageId, provider, model: 'mock-1' };\n\n if (turn.cancelSignal?.aborted) {\n yield finish({ status: 'cancelled', text: '', failure: { status: 'cancelled', message: 'Stopped.' } });\n return;\n }\n\n // Terminal-before-any-text scenarios still emit a well-formed turn.\n if (scenario.status === 'notProvisioned' || (scenario.status === 'error' && !scenario.text)) {\n await this.scheduler(this.firstTokenMs);\n yield finish({\n status: scenario.status,\n text: '',\n failure: {\n status: scenario.status,\n message: scenario.failureMessage ?? 'Failed.',\n code: scenario.failureCode,\n recoverable: scenario.recoverable,\n retryAfterMs: scenario.retryAfterMs,\n },\n });\n return;\n }\n\n if (scenario.sources) {\n yield { type: 'status', messageId, label: 'Searching Dataverse…' };\n await this.scheduler(this.firstTokenMs);\n yield { type: 'sources', messageId, sources: scenario.sources };\n }\n\n if (scenario.thinking) {\n yield { type: 'thinking_delta', messageId, text: scenario.thinking };\n }\n\n if (scenario.toolCall) {\n yield { type: 'tool_call', messageId, call: scenario.toolCall };\n if (scenario.autoToolResult !== undefined) {\n await this.scheduler(this.chunkMs);\n yield {\n type: 'tool_result',\n messageId,\n callId: scenario.toolCall.id,\n status: 'succeeded',\n resultText: scenario.autoToolResult,\n };\n }\n }\n\n const chunks = scenario.chunks ?? scenario.text.split(/(?<=\\s)/);\n await this.scheduler(this.firstTokenMs);\n\n let emitted = '';\n for (const [i, chunk] of chunks.entries()) {\n if (turn.cancelSignal?.aborted) {\n yield finish({\n status: 'cancelled',\n text: emitted,\n failure: { status: 'cancelled', message: 'Stopped.' },\n });\n return;\n }\n if (scenario.throwsMidStream && i === Math.floor(chunks.length / 2)) {\n // The failure channel an AsyncIterable has and a Promise does not. A consumer must\n // surface this as a notice, not by unmounting the tree.\n throw new Error('mock transport exploded mid-stream');\n }\n emitted += chunk;\n yield { type: 'text_delta', messageId, text: chunk };\n await this.scheduler(this.chunkMs);\n }\n\n if (scenario.suggestions) {\n yield { type: 'suggestions', messageId, prompts: scenario.suggestions };\n }\n\n const failed = scenario.status !== 'succeeded';\n yield finish({\n status: scenario.status,\n text: emitted,\n guarded: scenario.guarded,\n usage: {\n inputTokens: 128,\n outputTokens: chunks.length,\n costUsd: Number((chunks.length * 0.000002).toFixed(6)),\n durationMs: this.firstTokenMs + chunks.length * this.chunkMs,\n model: 'mock-1',\n },\n failure: failed\n ? {\n status: scenario.status as Exclude<typeof scenario.status, 'succeeded'>,\n message: scenario.failureMessage ?? 'Failed.',\n code: scenario.failureCode,\n recoverable: scenario.recoverable,\n retryAfterMs: scenario.retryAfterMs,\n }\n : undefined,\n });\n }\n}\n","import type { AgentAvailability, AgentEvent, AgentTurn, IAgentService } from '../core/protocol';\n\n/**\n * The default provider: answers nothing, politely.\n *\n * ★ `none` is the DEFAULT and must stay so. A kit dropped into a host nobody has wired must\n * not silently start talking to a service because someone shipped a new build. Carried\n * from `ILlmService`, where the same rule is load-bearing in a regulated process.\n *\n * ★ It still yields a well-formed turn — `turn_start` then one `turn_end` — rather than\n * throwing or yielding nothing. An unconfigured kit should render \"not configured\", not\n * a spinner that never resolves.\n */\nexport class NullAgentService implements IAgentService {\n readonly name = 'none';\n\n async isAvailable(): Promise<AgentAvailability> {\n return {\n available: false,\n status: 'notProvisioned',\n reason: 'No agent provider is configured for this host.',\n };\n }\n\n async *send(turn: AgentTurn): AsyncIterable<AgentEvent> {\n const messageId = `null-${Date.now()}`;\n const turnId = `turn-${messageId}`;\n void turn;\n yield { type: 'turn_start', turnId, messageId, provider: this.name };\n yield {\n type: 'turn_end',\n turnId,\n messageId,\n result: {\n status: 'notProvisioned',\n text: '',\n provider: this.name,\n failure: {\n status: 'notProvisioned',\n message: 'No agent provider is configured for this host.',\n code: 'not_provisioned',\n recoverable: false,\n },\n },\n };\n }\n}\n","import type { AgentServiceConfig, IAgentService } from '../core/protocol';\nimport { MockAgentService } from './MockAgentService';\nimport { NullAgentService } from './NullAgentService';\n\nexport interface ServiceDecision {\n provider: IAgentService;\n /** Why this one was chosen — surfaced in diagnostics so a misconfiguration is legible. */\n reason: string;\n}\n\n/**\n * Provider selection, as ONE ladder.\n *\n * ★ `decide()` is exported alongside `createAgentService()` and they share a return type, so\n * the factory and any diagnostics view cannot drift — the shape `ServiceFactory.decide()`\n * uses in `@dataverse-kit/api-service` for exactly the same reason.\n *\n * ★ An UNRECOGNISED provider name falls back to `none`, never to a working provider. Carried\n * from `createLlmService`: a typo must produce silence, not an unintended call to a model.\n */\nexport function decide(config: AgentServiceConfig): ServiceDecision {\n switch (config.provider) {\n case 'custom':\n return config.factory\n ? { provider: config.factory(), reason: 'explicit factory (provider: custom)' }\n : { provider: new NullAgentService(), reason: 'provider: custom but no factory supplied' };\n case 'mock':\n return { provider: new MockAgentService(), reason: 'provider: mock' };\n case 'none':\n return { provider: new NullAgentService(), reason: 'provider: none (the default)' };\n default:\n return {\n provider: new NullAgentService(),\n reason: `unrecognised provider ${String(config.provider)} — falling back to none`,\n };\n }\n}\n\nexport function createAgentService(\n config: AgentServiceConfig = { provider: 'none' },\n): IAgentService {\n return decide(config).provider;\n}\n"],"mappings":"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","names":["React","Button","makeStyles","tokens","dayKey","TERMINAL","React","React","React","React","React","React","makeStyles","mergeClasses","tokens","makeStyles","jsx","jsxs","makeStyles","tokens","jsx","useStyles","makeStyles","tokens","React","makeStyles","mergeClasses","tokens","jsx","useStyles","CardSurface","React","Button","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Button","React","makeStyles","tokens","mergeClasses","jsx","jsxs","useStyles","jsx","jsx","jsxs","useStyles","makeStyles","tokens","mergeClasses","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","jsx","jsxs","useStyles","jsx","jsxs","useStyles","makeStyles","tokens","Button","React","Button","makeStyles","mergeClasses","tokens","Tooltip","jsx","jsxs","useStyles","makeStyles","tokens","mergeClasses","Tooltip","Button","Button","makeStyles","mergeClasses","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","tokens","Text","Button","jsx","jsxs","Button","Tooltip","StopRegular","jsx","MessageBar","MessageBarBody","MessageBarTitle","MessageBarActions","Button","jsx","jsxs","makeStyles","tokens","jsx","jsxs","useStyles","React","MessageBar","MessageBarBody","MessageBarTitle","MessageBarActions","Button","jsx","jsxs","Badge","jsx","jsx","React","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","tokens","Text","Fragment","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","tokens","Text","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","mergeClasses","tokens","Badge","jsx","jsxs","useStyles","React","Button","Text","Tooltip","makeStyles","mergeClasses","tokens","jsx","jsxs","useStyles","makeStyles","tokens","mergeClasses","Tooltip","Button","Text","React","Button","Text","Textarea","makeStyles","mergeClasses","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","mergeClasses","Textarea","Button","React","makeStyles","tokens","Button","Fragment","jsx","jsxs","useStyles","Button","Tooltip","makeStyles","mergeClasses","tokens","jsx","jsxs","useStyles","React","makeStyles","tokens","Text","makeStyles","mergeClasses","tokens","Avatar","jsx","jsx","jsxs","useStyles","makeStyles","tokens","mergeClasses","jsx","useStyles","makeStyles","tokens","Text","Button","Menu","MenuTrigger","MenuPopover","MenuList","MenuItem","Text","makeStyles","tokens","MoreHorizontalRegular","jsx","jsxs","useStyles","makeStyles","tokens","Text","Button","Menu","MenuTrigger","MoreHorizontalRegular","MenuPopover","MenuList","MenuItem","React","Button","makeStyles","tokens","Text","DismissRegular","jsx","jsxs","useStyles","makeStyles","jsx","useStyles","Tooltip","makeStyles","tokens","jsx","useStyles","React","makeStyles","tokens","Button","Text","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","Button","jsx","useStyles","makeStyles","tokens","React","makeStyles","jsx","useStyles","makeStyles","React","Text","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","makeStyles","tokens","ShieldErrorRegular","jsx","jsxs","useStyles","React","Text","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Text","React","Button","makeStyles","tokens","DismissRegular","React","makeStyles","tokens","Text","jsx","jsxs","useStyles","MessageBar","MessageBarBody","MessageBarTitle","MessageBarActions","Button","makeStyles","tokens","jsx","jsxs","INTENT","useStyles","Fragment","jsx","jsxs","useStyles","makeStyles","tokens","Button","DismissRegular","React","Badge","Spinner","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","Badge","Spinner","React","jsx"]}
|