@flytedan/flytebot-design-system 0.71.7 → 0.72.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/dist/index.d.cts CHANGED
@@ -363,10 +363,15 @@ interface DrawerProps {
363
363
  onClose?: () => void;
364
364
  /** Plain content, or a render function receiving `close` — call it to trigger the closing animation before onClose fires. */
365
365
  footer?: React.ReactNode | ((close: () => void) => React.ReactNode);
366
- children?: React.ReactNode;
366
+ /** The drawer's content owns the whole panel: no header bar and no body padding, and the panel is the
367
+ * full viewport height. For content that already has its own header and close control (a chat panel).
368
+ * `title` is then only the dialog's accessible name; Escape, scrim click and focus handling are unchanged. */
369
+ bare?: boolean;
370
+ /** Plain content, or (like `footer`) a render function receiving `close`. */
371
+ children?: React.ReactNode | ((close: () => void) => React.ReactNode);
367
372
  className?: string;
368
373
  }
369
- declare function Drawer({ open, title, onClose, footer, children, className, ...rest }: DrawerProps): React.ReactPortal | null;
374
+ declare function Drawer({ open, title, onClose, footer, bare, children, className, ...rest }: DrawerProps): React.ReactPortal | null;
370
375
 
371
376
  /** A focused decision on a scrim. Max 560px, 760 with `wide` for data. Escape closes.
372
377
  * MP-212/MP-248: a trapping layer in the shared layer stack (kits/layerStack.tsx):
@@ -2017,12 +2022,18 @@ interface StepListProps {
2017
2022
  showDurations?: boolean;
2018
2023
  dense?: boolean;
2019
2024
  className?: string;
2025
+ /**
2026
+ * The work these steps belong to is not finished (a turn still waiting on background work). The head then
2027
+ * reads as a neutral "Steps so far" disclosure, never the green "Worked for …" completion check, so a
2028
+ * person never sees finished and working at once. A running step still shows its own spinner.
2029
+ */
2030
+ active?: boolean;
2020
2031
  }
2021
2032
  /**
2022
2033
  * A flat, collapsible list of work steps — one row per step, never one card per
2023
2034
  * call. A long run stays readable: it is a list, not a stack.
2024
2035
  */
2025
- declare function StepList({ steps, label, defaultOpen, open: openProp, onToggle, showDurations, dense, className, }: StepListProps): React.JSX.Element | null;
2036
+ declare function StepList({ steps, label, defaultOpen, open: openProp, onToggle, showDurations, dense, className, active, }: StepListProps): React.JSX.Element | null;
2026
2037
 
2027
2038
  /** Number of rows kept mounted above and below the visible band. Two buffers this size
2028
2039
  * (one per edge) plus the visible band itself is what keeps the mounted node count
@@ -4143,6 +4154,18 @@ interface ChatMessage {
4143
4154
  model?: string;
4144
4155
  usage?: unknown;
4145
4156
  resumed?: boolean;
4157
+ /**
4158
+ * This message is a background task that is still in progress (a queued or running query's card). Set by the
4159
+ * adapter. `working` keeps meaning only "the turn is in flight"; a pending message shows no working row of
4160
+ * its own. A task-pending message is what a working turn waits on (see `waitingFor`).
4161
+ */
4162
+ taskPending?: boolean;
4163
+ /**
4164
+ * What a still-working turn is waiting on, in words ("Running 2 queries"): set by the engine, never the
4165
+ * adapter, on the working turn whenever messages of the thread are `taskPending`. The working indicator then
4166
+ * shows this in place of "Working" as the turn's one state. Never an id.
4167
+ */
4168
+ waitingFor?: string;
4146
4169
  metadata?: {
4147
4170
  type?: string;
4148
4171
  [k: string]: unknown;
@@ -4200,6 +4223,12 @@ interface ChatEngineOptions {
4200
4223
  * is always authoritative: a terminal status seen at any time wins over this.
4201
4224
  */
4202
4225
  pendingTimeoutMs?: number;
4226
+ /**
4227
+ * Words for the background work a working turn is waiting on: called with the thread's `taskPending` messages
4228
+ * (a running query's card), whenever there is at least one. Default "Waiting on N background
4229
+ * task(s)". Return the app's own phrasing, e.g. "Running 2 queries".
4230
+ */
4231
+ describeWaiting?: (pending: ChatMessage[]) => string;
4203
4232
  store?: {
4204
4233
  get(k: string): string | null;
4205
4234
  set(k: string, v: string): void;
@@ -4358,6 +4387,8 @@ interface AgentChatPanelProps {
4358
4387
  onApplyPacket?: (p: Packet) => void;
4359
4388
  /** Give-up time for a queued/running turn, in ms. Default 180000. The server's terminal job status always wins. */
4360
4389
  pendingTimeoutMs?: number;
4390
+ /** Words for the background work a live turn waits on, given the still-working cards ("Running 2 queries"). */
4391
+ describeWaiting?: (pending: ChatMessage[]) => string;
4361
4392
  onOpenAttachment?: (a: Attachment) => void;
4362
4393
  /** Map a backend error code to human copy. */
4363
4394
  errorCopy?: (code: string) => React.ReactNode;
@@ -4418,7 +4449,7 @@ interface AgentChatPanelProps {
4418
4449
  * renders only when its input is supplied. A panel with no telemetry shows no
4419
4450
  * telemetry, not zeroes.
4420
4451
  */
4421
- declare function AgentChatPanel({ contextType, contextId, apiAdapter, threadId, title, subtitle, showHeader, headerActions, onClose, assistantName, userName, assistantAvatar, userAvatar, assistantIcon, showAvatars, markdown, maxVisibleChars, messageActions, showSteps, showThinking, emptyTitle, emptyDescription, emptyIcon, suggestions, renderEmpty, packetSchemas, packetRenderers, onApplyPacket, pendingTimeoutMs, onOpenAttachment, errorCopy, placeholder, maxLength, hint, fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold, slashCommands, mentionSources, voiceHandler, initialMessage, contextUsage, sessionStats, usageLimits, models, model, onModelChange, effortLevels, effort, onEffortChange, fastMode, onFastModeChange, moreModels, threads, onSelectThread, onNewThread, onDeleteThread, surface, width, minWidth, maxWidth, resizable, height, className, style, onPacket, onThreadReady, onError, onSend, onClear, onFeedback, onEditMessage, }: AgentChatPanelProps): React.JSX.Element;
4452
+ declare function AgentChatPanel({ contextType, contextId, apiAdapter, threadId, title, subtitle, showHeader, headerActions, onClose, assistantName, userName, assistantAvatar, userAvatar, assistantIcon, showAvatars, markdown, maxVisibleChars, messageActions, showSteps, showThinking, emptyTitle, emptyDescription, emptyIcon, suggestions, renderEmpty, packetSchemas, packetRenderers, onApplyPacket, pendingTimeoutMs, describeWaiting, onOpenAttachment, errorCopy, placeholder, maxLength, hint, fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold, slashCommands, mentionSources, voiceHandler, initialMessage, contextUsage, sessionStats, usageLimits, models, model, onModelChange, effortLevels, effort, onEffortChange, fastMode, onFastModeChange, moreModels, threads, onSelectThread, onNewThread, onDeleteThread, surface, width, minWidth, maxWidth, resizable, height, className, style, onPacket, onThreadReady, onError, onSend, onClear, onFeedback, onEditMessage, }: AgentChatPanelProps): React.JSX.Element;
4422
4453
 
4423
4454
  /**
4424
4455
  * Staged files, the queue strip, the markdown editor, slash/mention triggers, send + stop.
package/dist/index.d.ts CHANGED
@@ -363,10 +363,15 @@ interface DrawerProps {
363
363
  onClose?: () => void;
364
364
  /** Plain content, or a render function receiving `close` — call it to trigger the closing animation before onClose fires. */
365
365
  footer?: React.ReactNode | ((close: () => void) => React.ReactNode);
366
- children?: React.ReactNode;
366
+ /** The drawer's content owns the whole panel: no header bar and no body padding, and the panel is the
367
+ * full viewport height. For content that already has its own header and close control (a chat panel).
368
+ * `title` is then only the dialog's accessible name; Escape, scrim click and focus handling are unchanged. */
369
+ bare?: boolean;
370
+ /** Plain content, or (like `footer`) a render function receiving `close`. */
371
+ children?: React.ReactNode | ((close: () => void) => React.ReactNode);
367
372
  className?: string;
368
373
  }
369
- declare function Drawer({ open, title, onClose, footer, children, className, ...rest }: DrawerProps): React.ReactPortal | null;
374
+ declare function Drawer({ open, title, onClose, footer, bare, children, className, ...rest }: DrawerProps): React.ReactPortal | null;
370
375
 
371
376
  /** A focused decision on a scrim. Max 560px, 760 with `wide` for data. Escape closes.
372
377
  * MP-212/MP-248: a trapping layer in the shared layer stack (kits/layerStack.tsx):
@@ -2017,12 +2022,18 @@ interface StepListProps {
2017
2022
  showDurations?: boolean;
2018
2023
  dense?: boolean;
2019
2024
  className?: string;
2025
+ /**
2026
+ * The work these steps belong to is not finished (a turn still waiting on background work). The head then
2027
+ * reads as a neutral "Steps so far" disclosure, never the green "Worked for …" completion check, so a
2028
+ * person never sees finished and working at once. A running step still shows its own spinner.
2029
+ */
2030
+ active?: boolean;
2020
2031
  }
2021
2032
  /**
2022
2033
  * A flat, collapsible list of work steps — one row per step, never one card per
2023
2034
  * call. A long run stays readable: it is a list, not a stack.
2024
2035
  */
2025
- declare function StepList({ steps, label, defaultOpen, open: openProp, onToggle, showDurations, dense, className, }: StepListProps): React.JSX.Element | null;
2036
+ declare function StepList({ steps, label, defaultOpen, open: openProp, onToggle, showDurations, dense, className, active, }: StepListProps): React.JSX.Element | null;
2026
2037
 
2027
2038
  /** Number of rows kept mounted above and below the visible band. Two buffers this size
2028
2039
  * (one per edge) plus the visible band itself is what keeps the mounted node count
@@ -4143,6 +4154,18 @@ interface ChatMessage {
4143
4154
  model?: string;
4144
4155
  usage?: unknown;
4145
4156
  resumed?: boolean;
4157
+ /**
4158
+ * This message is a background task that is still in progress (a queued or running query's card). Set by the
4159
+ * adapter. `working` keeps meaning only "the turn is in flight"; a pending message shows no working row of
4160
+ * its own. A task-pending message is what a working turn waits on (see `waitingFor`).
4161
+ */
4162
+ taskPending?: boolean;
4163
+ /**
4164
+ * What a still-working turn is waiting on, in words ("Running 2 queries"): set by the engine, never the
4165
+ * adapter, on the working turn whenever messages of the thread are `taskPending`. The working indicator then
4166
+ * shows this in place of "Working" as the turn's one state. Never an id.
4167
+ */
4168
+ waitingFor?: string;
4146
4169
  metadata?: {
4147
4170
  type?: string;
4148
4171
  [k: string]: unknown;
@@ -4200,6 +4223,12 @@ interface ChatEngineOptions {
4200
4223
  * is always authoritative: a terminal status seen at any time wins over this.
4201
4224
  */
4202
4225
  pendingTimeoutMs?: number;
4226
+ /**
4227
+ * Words for the background work a working turn is waiting on: called with the thread's `taskPending` messages
4228
+ * (a running query's card), whenever there is at least one. Default "Waiting on N background
4229
+ * task(s)". Return the app's own phrasing, e.g. "Running 2 queries".
4230
+ */
4231
+ describeWaiting?: (pending: ChatMessage[]) => string;
4203
4232
  store?: {
4204
4233
  get(k: string): string | null;
4205
4234
  set(k: string, v: string): void;
@@ -4358,6 +4387,8 @@ interface AgentChatPanelProps {
4358
4387
  onApplyPacket?: (p: Packet) => void;
4359
4388
  /** Give-up time for a queued/running turn, in ms. Default 180000. The server's terminal job status always wins. */
4360
4389
  pendingTimeoutMs?: number;
4390
+ /** Words for the background work a live turn waits on, given the still-working cards ("Running 2 queries"). */
4391
+ describeWaiting?: (pending: ChatMessage[]) => string;
4361
4392
  onOpenAttachment?: (a: Attachment) => void;
4362
4393
  /** Map a backend error code to human copy. */
4363
4394
  errorCopy?: (code: string) => React.ReactNode;
@@ -4418,7 +4449,7 @@ interface AgentChatPanelProps {
4418
4449
  * renders only when its input is supplied. A panel with no telemetry shows no
4419
4450
  * telemetry, not zeroes.
4420
4451
  */
4421
- declare function AgentChatPanel({ contextType, contextId, apiAdapter, threadId, title, subtitle, showHeader, headerActions, onClose, assistantName, userName, assistantAvatar, userAvatar, assistantIcon, showAvatars, markdown, maxVisibleChars, messageActions, showSteps, showThinking, emptyTitle, emptyDescription, emptyIcon, suggestions, renderEmpty, packetSchemas, packetRenderers, onApplyPacket, pendingTimeoutMs, onOpenAttachment, errorCopy, placeholder, maxLength, hint, fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold, slashCommands, mentionSources, voiceHandler, initialMessage, contextUsage, sessionStats, usageLimits, models, model, onModelChange, effortLevels, effort, onEffortChange, fastMode, onFastModeChange, moreModels, threads, onSelectThread, onNewThread, onDeleteThread, surface, width, minWidth, maxWidth, resizable, height, className, style, onPacket, onThreadReady, onError, onSend, onClear, onFeedback, onEditMessage, }: AgentChatPanelProps): React.JSX.Element;
4452
+ declare function AgentChatPanel({ contextType, contextId, apiAdapter, threadId, title, subtitle, showHeader, headerActions, onClose, assistantName, userName, assistantAvatar, userAvatar, assistantIcon, showAvatars, markdown, maxVisibleChars, messageActions, showSteps, showThinking, emptyTitle, emptyDescription, emptyIcon, suggestions, renderEmpty, packetSchemas, packetRenderers, onApplyPacket, pendingTimeoutMs, describeWaiting, onOpenAttachment, errorCopy, placeholder, maxLength, hint, fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold, slashCommands, mentionSources, voiceHandler, initialMessage, contextUsage, sessionStats, usageLimits, models, model, onModelChange, effortLevels, effort, onEffortChange, fastMode, onFastModeChange, moreModels, threads, onSelectThread, onNewThread, onDeleteThread, surface, width, minWidth, maxWidth, resizable, height, className, style, onPacket, onThreadReady, onError, onSend, onClear, onFeedback, onEditMessage, }: AgentChatPanelProps): React.JSX.Element;
4422
4453
 
4423
4454
  /**
4424
4455
  * Staged files, the queue strip, the markdown editor, slash/mention triggers, send + stop.
package/dist/index.js CHANGED
@@ -940,7 +940,7 @@ function Collapsible({
940
940
  import * as React6 from "react";
941
941
  import { createPortal as createPortal2 } from "react-dom";
942
942
  import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
943
- function Drawer({ open: open2 = true, title, onClose, footer, children, className = "", ...rest }) {
943
+ function Drawer({ open: open2 = true, title, onClose, footer, bare = false, children, className = "", ...rest }) {
944
944
  const asideRef = React6.useRef(null);
945
945
  const [closing, setClosing] = React6.useState(false);
946
946
  const close2 = React6.useCallback(() => {
@@ -954,12 +954,12 @@ function Drawer({ open: open2 = true, title, onClose, footer, children, classNam
954
954
  return createPortal2(
955
955
  /* @__PURE__ */ jsxs6(StackedLayerProvider, { layer, children: [
956
956
  /* @__PURE__ */ jsx9("div", { className: "fd-scrim" + (closing ? " is-closing" : ""), style: { display: "block", zIndex: zIndex - LAYER_STEP }, onClick: close2 }),
957
- /* @__PURE__ */ jsxs6("aside", { ref: asideRef, className: ["fd-drawer", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", ...rest, style: { zIndex }, children: [
958
- /* @__PURE__ */ jsxs6("div", { className: "fd-card-head", style: { flex: "none" }, children: [
957
+ /* @__PURE__ */ jsxs6("aside", { ref: asideRef, className: ["fd-drawer", bare ? "is-bare" : "", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", "aria-label": bare && typeof title === "string" ? title : void 0, ...rest, style: { zIndex }, children: [
958
+ bare ? null : /* @__PURE__ */ jsxs6("div", { className: "fd-card-head", style: { flex: "none" }, children: [
959
959
  /* @__PURE__ */ jsx9("span", { className: "fd-card-head-title", title: truncationTitle(title), children: title }),
960
960
  onClose ? /* @__PURE__ */ jsx9("button", { type: "button", className: "fd-btn-icon", "aria-label": "Close", onClick: close2, children: /* @__PURE__ */ jsx9("i", { className: "ph ph-x" }) }) : null
961
961
  ] }),
962
- /* @__PURE__ */ jsx9("div", { style: { flex: "1 1 auto", minHeight: 0, overflow: "auto", padding: 20 }, children }),
962
+ /* @__PURE__ */ jsx9("div", { style: bare ? { flex: "1 1 auto", minHeight: 0, display: "flex", flexDirection: "column" } : { flex: "1 1 auto", minHeight: 0, overflow: "auto", padding: 20 }, children: typeof children === "function" ? children(close2) : children }),
963
963
  footer ? /* @__PURE__ */ jsx9("div", { className: "fd-card-foot", style: { flex: "none" }, children: typeof footer === "function" ? footer(close2) : footer }) : null
964
964
  ] })
965
965
  ] }),
@@ -5897,7 +5897,8 @@ function StepList({
5897
5897
  onToggle,
5898
5898
  showDurations = true,
5899
5899
  dense = false,
5900
- className = ""
5900
+ className = "",
5901
+ active = false
5901
5902
  }) {
5902
5903
  const [openState, setOpenState] = React39.useState(defaultOpen);
5903
5904
  const open2 = openProp == null ? openState : openProp;
@@ -5907,15 +5908,15 @@ function StepList({
5907
5908
  const failed = steps.filter((s) => s.status === "error").length;
5908
5909
  const total = steps.reduce((n, s) => n + (s.durationMs || 0), 0);
5909
5910
  const current2 = steps.filter((s) => s.status === "running").slice(-1)[0];
5910
- const summary = label || (running ? current2 ? current2.label : "Working" : total ? "Worked for " + formatDuration(total) : "Steps");
5911
+ const summary = label || (running ? current2 ? current2.label : "Working" : active ? "Steps so far" : total ? "Worked for " + formatDuration(total) : "Steps");
5911
5912
  const toggle = () => {
5912
5913
  const next = !open2;
5913
5914
  if (openProp == null) setOpenState(next);
5914
5915
  onToggle && onToggle(next);
5915
5916
  };
5916
- return /* @__PURE__ */ jsxs51("div", { className: ["fd-steps", dense ? "is-dense" : "", open2 ? "is-open" : "", className].filter(Boolean).join(" "), children: [
5917
+ return /* @__PURE__ */ jsxs51("div", { className: ["fd-steps", dense ? "is-dense" : "", active ? "is-active" : "", open2 ? "is-open" : "", className].filter(Boolean).join(" "), children: [
5917
5918
  /* @__PURE__ */ jsxs51("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open2, children: [
5918
- running ? /* @__PURE__ */ jsx61("span", { className: "fd-steps-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx61("i", { className: "ph ph-" + (failed ? "warning-circle" : "check-circle"), "aria-hidden": "true" }),
5919
+ running ? /* @__PURE__ */ jsx61("span", { className: "fd-steps-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx61("i", { className: "ph ph-" + (failed ? "warning-circle" : active ? "list-checks" : "check-circle"), "aria-hidden": "true" }),
5919
5920
  /* @__PURE__ */ jsx61("span", { className: "fd-steps-title", title: truncationTitle(summary), children: summary }),
5920
5921
  /* @__PURE__ */ jsxs51("span", { className: "fd-steps-count fd-tabular", children: [
5921
5922
  steps.length,
@@ -12427,6 +12428,20 @@ function jobBucket(status) {
12427
12428
  if (JOB_SUCCESS.indexOf(s) !== -1) return "success";
12428
12429
  return "failure";
12429
12430
  }
12431
+ function defaultDescribeWaiting(pending) {
12432
+ return "Waiting on " + pending.length + " background " + (pending.length === 1 ? "task" : "tasks");
12433
+ }
12434
+ function withWaiting(list, describe) {
12435
+ const pending = list.filter((m) => m.taskPending);
12436
+ let turn = -1;
12437
+ list.forEach((m, i) => {
12438
+ if (m.working) turn = i;
12439
+ });
12440
+ return list.map((m, i) => {
12441
+ const want = i === turn && pending.length ? describe(pending) : void 0;
12442
+ return m.waitingFor === want ? m : Object.assign({}, m, { waitingFor: want });
12443
+ });
12444
+ }
12430
12445
  function useChatEngine(opts) {
12431
12446
  const {
12432
12447
  contextType,
@@ -12436,6 +12451,7 @@ function useChatEngine(opts) {
12436
12451
  threadId: threadIdProp,
12437
12452
  pollIntervalMs = 1500,
12438
12453
  pendingTimeoutMs = 18e4,
12454
+ describeWaiting = defaultDescribeWaiting,
12439
12455
  store = safeStore,
12440
12456
  onPacket,
12441
12457
  onThreadReady,
@@ -12470,9 +12486,12 @@ function useChatEngine(opts) {
12470
12486
  mounted.current = false;
12471
12487
  };
12472
12488
  }, []);
12489
+ const describeWaitingRef = React70.useRef(describeWaiting);
12490
+ describeWaitingRef.current = describeWaiting;
12473
12491
  const commit = (next) => {
12474
- listRef.current = next;
12475
- if (mounted.current) setMessages(next);
12492
+ const derived = withWaiting(next, (pending) => describeWaitingRef.current(pending));
12493
+ listRef.current = derived;
12494
+ if (mounted.current) setMessages(derived);
12476
12495
  };
12477
12496
  const patch = (id, p) => commit(listRef.current.map((m) => m.id === id ? Object.assign({}, m, typeof p === "function" ? p(m) : p) : m));
12478
12497
  const push = (...msgs) => commit(listRef.current.concat(msgs));
@@ -12949,7 +12968,7 @@ function MessageBody({ message: m, ctx }) {
12949
12968
  const showMd = ctx.markdown && !isUser;
12950
12969
  return /* @__PURE__ */ jsxs88("div", { className: "fdc-body", children: [
12951
12970
  m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx101(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
12952
- m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx101(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
12971
+ m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx101(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), active: !!m.working, dense: true }) : null,
12953
12972
  body ? /* @__PURE__ */ jsxs88("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
12954
12973
  showMd ? /* @__PURE__ */ jsx101(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx101("div", { className: "fdc-plain", children: body }),
12955
12974
  m.streaming ? /* @__PURE__ */ jsx101("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
@@ -12981,8 +13000,8 @@ function MessageBody({ message: m, ctx }) {
12981
13000
  /* @__PURE__ */ jsx101("span", {})
12982
13001
  ] }),
12983
13002
  /* @__PURE__ */ jsxs88("span", { className: "fdc-working-label", children: [
12984
- m.resumed ? "Resuming" : "Working",
12985
- m.job && m.job.status ? /* @__PURE__ */ jsxs88("span", { className: "fdc-working-job", children: [
13003
+ m.waitingFor || (m.resumed ? "Resuming" : "Working"),
13004
+ !m.waitingFor && m.job && m.job.status ? /* @__PURE__ */ jsxs88("span", { className: "fdc-working-job", children: [
12986
13005
  " \xB7 ",
12987
13006
  m.job.status
12988
13007
  ] }) : null,
@@ -12990,8 +13009,7 @@ function MessageBody({ message: m, ctx }) {
12990
13009
  " \xB7 ",
12991
13010
  m.job.detail
12992
13011
  ] }) : null
12993
- ] }),
12994
- m.jobId ? /* @__PURE__ */ jsx101("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
13012
+ ] })
12995
13013
  ] }) : null,
12996
13014
  m.stopped ? /* @__PURE__ */ jsxs88("div", { className: "fdc-stopped", children: [
12997
13015
  /* @__PURE__ */ jsx101("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
@@ -13688,6 +13706,7 @@ function AgentChatPanel({
13688
13706
  packetRenderers,
13689
13707
  onApplyPacket,
13690
13708
  pendingTimeoutMs,
13709
+ describeWaiting,
13691
13710
  onOpenAttachment,
13692
13711
  errorCopy,
13693
13712
  /* composer */
@@ -13750,6 +13769,7 @@ function AgentChatPanel({
13750
13769
  initialMessage,
13751
13770
  threadId,
13752
13771
  pendingTimeoutMs,
13772
+ describeWaiting,
13753
13773
  onPacket,
13754
13774
  onThreadReady,
13755
13775
  onError,