@ai-matrx/chat 0.3.6 → 0.3.11

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/agents/components/context-items/bodies/WebpageBody.js +3 -8
  3. package/dist/agents/components/inputs/smart-input/InputActionButtons.d.ts +4 -0
  4. package/dist/agents/components/inputs/smart-input/InputActionButtons.js +16 -9
  5. package/dist/agents/components/inputs/smart-input/RunControlsMenu.d.ts +2 -0
  6. package/dist/agents/components/inputs/smart-input/RunControlsMenu.js +2 -0
  7. package/dist/agents/components/inputs/smart-input/SmartAgentInputStacked.js +1 -1
  8. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +4 -6
  9. package/dist/agents/components/inputs/smart-input/composer/ComposerMenu.js +16 -2
  10. package/dist/agents/components/inputs/smart-input/composer/ComposerOutput.js +9 -4
  11. package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.d.ts +3 -1
  12. package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +2 -2
  13. package/dist/agents/components/inputs/smart-input/composer/composer-types.d.ts +5 -0
  14. package/dist/agents/components/inputs/variable-input-variations/AgentVariableCards.js +1 -1
  15. package/dist/agents/components/live-run/LiveRunDisplay.d.ts +7 -1
  16. package/dist/agents/components/live-run/LiveRunDisplay.js +10 -3
  17. package/dist/agents/components/messages-display/TranscriptIntegrityCopyButton.js +4 -10
  18. package/dist/agents/components/shared/AgentOptionsMenu.js +2 -2
  19. package/dist/agents/constants/system-agent-registry.d.ts +0 -3
  20. package/dist/agents/constants/system-agent-registry.js +0 -3
  21. package/dist/agents/hooks/useFloatingAgentRun.d.ts +19 -0
  22. package/dist/agents/hooks/useFloatingAgentRun.js +32 -9
  23. package/dist/agents/prompt-preview/PromptPreviewContent.js +2 -6
  24. package/dist/agents/redux/execution-system/message-crud/edit-message.thunk.js +3 -6
  25. package/dist/agents/redux/execution-system/message-crud/fork-and-resubmit-from-message.thunk.js +1 -1
  26. package/dist/compute/targets.d.ts +2 -6
  27. package/dist/context/sources/scopes.d.ts +3 -3
  28. package/dist/host/db-types.d.ts +350 -168
  29. package/dist/host/window-openers.d.ts +23 -5
  30. package/dist/surfaces/manifests/chat.manifest.js +3 -1
  31. package/dist/ui/mandates-storage/mandateStorage.d.ts +15 -0
  32. package/dist/ui/mandates-storage/shortcutStorage.d.ts +3 -0
  33. package/dist/utils/rich-editor/in-place/caret-handoff.js +2 -1
  34. package/dist/voice-agent/components/VoiceDebugPanel.js +4 -8
  35. package/dist/voice-agent/relay/VoiceRelayBar.d.ts +7 -1
  36. package/dist/voice-agent/relay/VoiceRelayBar.js +90 -24
  37. package/dist/window-panels/windows/agents/LiveRunWindow.d.ts +3 -1
  38. package/dist/window-panels/windows/agents/LiveRunWindow.js +5 -2
  39. package/package.json +8 -8
@@ -27,7 +27,7 @@ export interface OpenAgentIdWindowOptions {
27
27
  agentId?: string | null;
28
28
  }
29
29
  export type OpenAgentAdminFindUsagesWindowOptions = OpenAgentIdWindowOptions;
30
- export type OpenAgentCreateAppWindowOptions = OpenAgentIdWindowOptions;
30
+ export type OpenAgentCreateAppWindowOptions = Record<string, never>;
31
31
  export type OpenAgentDataStorageWindowOptions = OpenAgentIdWindowOptions;
32
32
  export type OpenAgentFindUsagesWindowOptions = OpenAgentIdWindowOptions;
33
33
  export type OpenAgentInterfaceVariationsWindowOptions = OpenAgentIdWindowOptions;
@@ -198,6 +198,8 @@ export interface OpenLiveRunWindowOptions {
198
198
  runSetKey?: string | null;
199
199
  label?: string | null;
200
200
  pending?: boolean;
201
+ /** The launch failed before a stream existed: its reason, shown in the window. */
202
+ failure?: string | null;
201
203
  /** Stable id to reuse one window per subject. Omit for a fresh window. */
202
204
  instanceId?: string;
203
205
  width?: number | string;
@@ -222,7 +224,7 @@ export interface EditorPrimaryAction {
222
224
  label: string;
223
225
  variant?: "default" | "secondary" | "outline" | "destructive" | "ghost" | "link";
224
226
  }
225
- export interface OpenFullScreenMarkdownEditorOptions {
227
+ interface OpenFullScreenMarkdownEditorOptionsBase {
226
228
  instanceId?: string;
227
229
  content?: string;
228
230
  mode?: unknown;
@@ -236,14 +238,29 @@ export interface OpenFullScreenMarkdownEditorOptions {
236
238
  showSaveButton?: boolean;
237
239
  showCopyButton?: boolean;
238
240
  primaryActions?: EditorPrimaryAction[];
239
- onSave?: (content: string) => void | Promise<void>;
240
- onAction?: (action: string, content: string) => void | Promise<void>;
241
+ }
242
+ type OpenFullScreenMarkdownEditorHandlers = {
243
+ onSave: (content: string) => Promise<void>;
244
+ onAction?: never;
241
245
  onEvent?: (event: {
242
246
  type: "save";
243
247
  content: string;
244
248
  action?: string;
245
249
  }) => void | Promise<void>;
246
- }
250
+ } | {
251
+ onSave?: never;
252
+ onAction: (action: string, content: string) => Promise<void>;
253
+ onEvent?: (event: {
254
+ type: "save";
255
+ content: string;
256
+ action?: string;
257
+ }) => void | Promise<void>;
258
+ } | {
259
+ onSave?: undefined;
260
+ onAction?: undefined;
261
+ onEvent?: undefined;
262
+ };
263
+ export type OpenFullScreenMarkdownEditorOptions = OpenFullScreenMarkdownEditorOptionsBase & OpenFullScreenMarkdownEditorHandlers;
247
264
  export interface ChatFullScreenEditorHandle {
248
265
  instanceId: string;
249
266
  callbackGroupId: string | null;
@@ -361,3 +378,4 @@ export declare function useOpenTopicalMapWindow(): (opts: OpenTopicalMapWindowOp
361
378
  export declare function useOpenScratchpadPanel(): (opts?: OpenScratchpadPanelOptions) => ChatWindowHandle;
362
379
  export declare function useOpenWorkingDocumentPanel(): (opts: OpenWorkingDocumentPanelOptions) => ChatWindowHandle;
363
380
  export declare function useOpenWorkingDocumentWindow(): (opts: OpenWorkingDocumentWindowOptions) => ChatInstanceWindowHandle;
381
+ export {};
@@ -73,7 +73,9 @@ const surfaceSpecific = [
73
73
  valueType: "array",
74
74
  alwaysAvailable: false,
75
75
  typicalCharCount: 6e3,
76
- inlineUpTo: 8e3,
76
+ // Page budget 10,000 (shared with the 2,000 custom_fields baseline and the two 1,000 values above):
77
+ // the newest messages fit in 6,000; older text is a `transcript` lookup away.
78
+ inlineUpTo: 6e3,
77
79
  sortOrder: 295,
78
80
  group: "thread"
79
81
  },
@@ -586,6 +586,7 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
586
586
  required_output_keys: string[];
587
587
  shown_to: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
588
588
  source_mandate_id: string | null;
589
+ typed_input_complete: boolean;
589
590
  updated_at: string;
590
591
  updated_by: string | null;
591
592
  version: number;
@@ -631,6 +632,7 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
631
632
  required_output_keys?: string[];
632
633
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
633
634
  source_mandate_id?: string | null;
635
+ typed_input_complete?: boolean;
634
636
  updated_at?: string;
635
637
  updated_by?: string | null;
636
638
  version?: number;
@@ -676,6 +678,7 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
676
678
  required_output_keys?: string[];
677
679
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
678
680
  source_mandate_id?: string | null;
681
+ typed_input_complete?: boolean;
679
682
  updated_at?: string;
680
683
  updated_by?: string | null;
681
684
  version?: number;
@@ -2048,6 +2051,7 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
2048
2051
  required_output_keys: string[];
2049
2052
  shown_to: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
2050
2053
  source_mandate_id: string | null;
2054
+ typed_input_complete: boolean;
2051
2055
  updated_at: string;
2052
2056
  updated_by: string | null;
2053
2057
  version: number;
@@ -2093,6 +2097,7 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
2093
2097
  required_output_keys?: string[];
2094
2098
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
2095
2099
  source_mandate_id?: string | null;
2100
+ typed_input_complete?: boolean;
2096
2101
  updated_at?: string;
2097
2102
  updated_by?: string | null;
2098
2103
  version?: number;
@@ -2138,6 +2143,7 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
2138
2143
  required_output_keys?: string[];
2139
2144
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
2140
2145
  source_mandate_id?: string | null;
2146
+ typed_input_complete?: boolean;
2141
2147
  updated_at?: string;
2142
2148
  updated_by?: string | null;
2143
2149
  version?: number;
@@ -2718,6 +2724,7 @@ declare const provisionTable: (supabase: Client) => import("@supabase/supabase-j
2718
2724
  required_output_keys: string[];
2719
2725
  shown_to: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
2720
2726
  source_mandate_id: string | null;
2727
+ typed_input_complete: boolean;
2721
2728
  updated_at: string;
2722
2729
  updated_by: string | null;
2723
2730
  version: number;
@@ -2763,6 +2770,7 @@ declare const provisionTable: (supabase: Client) => import("@supabase/supabase-j
2763
2770
  required_output_keys?: string[];
2764
2771
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
2765
2772
  source_mandate_id?: string | null;
2773
+ typed_input_complete?: boolean;
2766
2774
  updated_at?: string;
2767
2775
  updated_by?: string | null;
2768
2776
  version?: number;
@@ -2808,6 +2816,7 @@ declare const provisionTable: (supabase: Client) => import("@supabase/supabase-j
2808
2816
  required_output_keys?: string[];
2809
2817
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
2810
2818
  source_mandate_id?: string | null;
2819
+ typed_input_complete?: boolean;
2811
2820
  updated_at?: string;
2812
2821
  updated_by?: string | null;
2813
2822
  version?: number;
@@ -4748,6 +4757,7 @@ declare const bindingTable: (supabase: Client) => import("@supabase/supabase-js"
4748
4757
  required_output_keys: string[];
4749
4758
  shown_to: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
4750
4759
  source_mandate_id: string | null;
4760
+ typed_input_complete: boolean;
4751
4761
  updated_at: string;
4752
4762
  updated_by: string | null;
4753
4763
  version: number;
@@ -4793,6 +4803,7 @@ declare const bindingTable: (supabase: Client) => import("@supabase/supabase-js"
4793
4803
  required_output_keys?: string[];
4794
4804
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
4795
4805
  source_mandate_id?: string | null;
4806
+ typed_input_complete?: boolean;
4796
4807
  updated_at?: string;
4797
4808
  updated_by?: string | null;
4798
4809
  version?: number;
@@ -4838,6 +4849,7 @@ declare const bindingTable: (supabase: Client) => import("@supabase/supabase-js"
4838
4849
  required_output_keys?: string[];
4839
4850
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
4840
4851
  source_mandate_id?: string | null;
4852
+ typed_input_complete?: boolean;
4841
4853
  updated_at?: string;
4842
4854
  updated_by?: string | null;
4843
4855
  version?: number;
@@ -6826,6 +6838,7 @@ declare const treatmentTable: (supabase: Client) => import("@supabase/supabase-j
6826
6838
  required_output_keys: string[];
6827
6839
  shown_to: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
6828
6840
  source_mandate_id: string | null;
6841
+ typed_input_complete: boolean;
6829
6842
  updated_at: string;
6830
6843
  updated_by: string | null;
6831
6844
  version: number;
@@ -6871,6 +6884,7 @@ declare const treatmentTable: (supabase: Client) => import("@supabase/supabase-j
6871
6884
  required_output_keys?: string[];
6872
6885
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
6873
6886
  source_mandate_id?: string | null;
6887
+ typed_input_complete?: boolean;
6874
6888
  updated_at?: string;
6875
6889
  updated_by?: string | null;
6876
6890
  version?: number;
@@ -6916,6 +6930,7 @@ declare const treatmentTable: (supabase: Client) => import("@supabase/supabase-j
6916
6930
  required_output_keys?: string[];
6917
6931
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
6918
6932
  source_mandate_id?: string | null;
6933
+ typed_input_complete?: boolean;
6919
6934
  updated_at?: string;
6920
6935
  updated_by?: string | null;
6921
6936
  version?: number;
@@ -4778,6 +4778,7 @@ declare const mandateContextMenuView: (supabase: Client) => import("@supabase/su
4778
4778
  required_output_keys: string[];
4779
4779
  shown_to: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
4780
4780
  source_mandate_id: string | null;
4781
+ typed_input_complete: boolean;
4781
4782
  updated_at: string;
4782
4783
  updated_by: string | null;
4783
4784
  version: number;
@@ -4823,6 +4824,7 @@ declare const mandateContextMenuView: (supabase: Client) => import("@supabase/su
4823
4824
  required_output_keys?: string[];
4824
4825
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
4825
4826
  source_mandate_id?: string | null;
4827
+ typed_input_complete?: boolean;
4826
4828
  updated_at?: string;
4827
4829
  updated_by?: string | null;
4828
4830
  version?: number;
@@ -4868,6 +4870,7 @@ declare const mandateContextMenuView: (supabase: Client) => import("@supabase/su
4868
4870
  required_output_keys?: string[];
4869
4871
  shown_to?: import("../../host/db-types.js").Database["platform"]["Enums"]["shown_to"] | null;
4870
4872
  source_mandate_id?: string | null;
4873
+ typed_input_complete?: boolean;
4871
4874
  updated_at?: string;
4872
4875
  updated_by?: string | null;
4873
4876
  version?: number;
@@ -1,4 +1,5 @@
1
- const pending = /* @__PURE__ */ new Map();
1
+ const PENDING_KEY = /* @__PURE__ */ Symbol.for("ai-matrx.rich-editor.in-place-caret-handoff");
2
+ const pending = globalThis[PENDING_KEY] ??= /* @__PURE__ */ new Map();
2
3
  function handInPlaceCaret(key, caret) {
3
4
  if (caret) pending.set(key, caret);
4
5
  else pending.delete(key);
@@ -74,14 +74,10 @@ function VoiceDebugPanel({
74
74
  })} [${e.level}] ${e.label}${e.detail ? ` \u2014 ${e.detail}` : ""}`
75
75
  )
76
76
  ];
77
- try {
78
- if (!await copyText(lines.join("\n"))) return;
79
- setCopied(true);
80
- setTimeout(() => setCopied(false), 1500);
81
- toast.success("Voice debug copied");
82
- } catch {
83
- toast.error("Copy failed");
84
- }
77
+ if (!await copyText(lines.join("\n"))) return;
78
+ setCopied(true);
79
+ setTimeout(() => setCopied(false), 1500);
80
+ toast.success("Voice debug copied");
85
81
  };
86
82
  return /* @__PURE__ */ jsxs("div", { className: "pointer-events-auto w-full overflow-hidden rounded-lg border border-border bg-zinc-950/95 text-zinc-100 shadow-lg backdrop-blur", children: [
87
83
  /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between gap-2 px-3 py-1.5", children: [
@@ -16,7 +16,13 @@ export interface VoiceRelayBarProps {
16
16
  /**
17
17
  * `bar` draws the standalone section chrome. `toolbar` embeds the same
18
18
  * controls in an existing toolbar without adding another layout row.
19
+ * `composer` is the Smart Agent Input's "Live audio": idle it is ONE icon
20
+ * button beside the mic (no word, no extra width); pressed, the same live
21
+ * controls as `toolbar` (Arman, 2026-10-07: one voice control per surface).
19
22
  */
20
- variant?: "bar" | "toolbar";
23
+ variant?: "bar" | "toolbar" | "composer";
24
+ /** Controlled on/off (the composer's + menu turns it on when the row is folded). */
25
+ enabled?: boolean;
26
+ onEnabledChange?: (enabled: boolean) => void;
21
27
  }
22
28
  export declare function VoiceRelayBar(props: VoiceRelayBarProps): import("react").JSX.Element;
@@ -1,6 +1,9 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { useAppSelector } from "../../store/hooks.js";
5
+ import { cn } from "@ai-matrx/design-system";
6
+ import { selectVoiceInstructions } from "../state/selectors.js";
4
7
  import { Mic, Square, AudioLines } from "lucide-react";
5
8
  import { Button } from "@ai-matrx/design-system/controls";
6
9
  import { useMandate } from "../../mandates/useMandate.js";
@@ -16,7 +19,10 @@ function ActiveVoiceRelay({
16
19
  conversationId,
17
20
  surfaceKey,
18
21
  sourceFeature,
19
- questionPacing
22
+ questionPacing,
23
+ onEnd,
24
+ autoStart,
25
+ variant
20
26
  }) {
21
27
  const relay = useVoiceRelaySession({
22
28
  communicatorAgentId,
@@ -27,19 +33,26 @@ function ActiveVoiceRelay({
27
33
  questionPacing
28
34
  });
29
35
  const live = relay.status !== "idle" && relay.status !== "error";
36
+ const instructionsReady = useAppSelector(
37
+ (state) => (selectVoiceInstructions(state, relay.instanceId) ?? "").trim().length > 0
38
+ );
39
+ const started = useRef(false);
40
+ useEffect(() => {
41
+ if (!autoStart || !instructionsReady || started.current) return;
42
+ started.current = true;
43
+ relay.toggle();
44
+ }, [autoStart, instructionsReady, relay]);
30
45
  return /* @__PURE__ */ jsxs(Fragment, { children: [
31
46
  /* @__PURE__ */ jsx(
32
47
  Button,
33
48
  {
34
49
  variant: live ? "danger" : "primary",
35
- onClick: relay.toggle,
36
- children: live ? /* @__PURE__ */ jsxs(Fragment, { children: [
37
- /* @__PURE__ */ jsx(Square, { className: "mr-1.5 h-3.5 w-3.5" }),
38
- " End voice"
39
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
40
- /* @__PURE__ */ jsx(Mic, { className: "mr-1.5 h-3.5 w-3.5" }),
41
- " Talk"
42
- ] })
50
+ icon: live ? /* @__PURE__ */ jsx(Square, {}) : /* @__PURE__ */ jsx(Mic, {}),
51
+ onClick: () => {
52
+ relay.toggle();
53
+ if (live) onEnd?.();
54
+ },
55
+ children: live ? "End voice" : "Talk"
43
56
  }
44
57
  ),
45
58
  live ? (
@@ -53,33 +66,86 @@ function ActiveVoiceRelay({
53
66
  }
54
67
  )
55
68
  ) : null,
56
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: relay.error ? relay.error.message : relay.brainBusy ? "thinking\u2026" : relay.status })
69
+ relay.error || relay.brainBusy || relay.status !== "idle" ? (
70
+ // In the composer's row it is ONE line: the full sentence on hover.
71
+ /* @__PURE__ */ jsx(
72
+ "span",
73
+ {
74
+ className: cn(
75
+ "text-xs",
76
+ relay.error ? "text-destructive" : "text-muted-foreground",
77
+ variant === "composer" && "min-w-0 max-w-[14rem] truncate"
78
+ ),
79
+ title: relay.error?.message,
80
+ children: relay.error ? variant === "composer" ? "Voice did not start" : relay.error.message : relay.brainBusy ? "thinking\u2026" : relay.status
81
+ }
82
+ )
83
+ ) : null
57
84
  ] });
58
85
  }
59
86
  function VoiceRelayBar(props) {
60
- const [enabled, setEnabled] = useState(false);
61
- const communicator = useMandate(VOICE_COMMUNICATOR_MANDATE_KEY);
87
+ const [ownEnabled, setOwnEnabled] = useState(false);
88
+ const enabled = props.enabled ?? ownEnabled;
89
+ const setEnabled = (next) => {
90
+ if (props.enabled === void 0) setOwnEnabled(next);
91
+ props.onEnabledChange?.(next);
92
+ };
93
+ if (!enabled && props.variant === "composer") {
94
+ return /* @__PURE__ */ jsx(
95
+ Button,
96
+ {
97
+ variant: "quiet",
98
+ icon: /* @__PURE__ */ jsx(AudioLines, {}),
99
+ "aria-label": "Live audio",
100
+ title: "Live audio \u2014 talk and hear the answer",
101
+ onClick: () => setEnabled(true)
102
+ }
103
+ );
104
+ }
62
105
  return /* @__PURE__ */ jsx(
63
106
  "div",
64
107
  {
65
- className: props.variant === "toolbar" ? "flex items-center gap-1" : "flex items-center gap-2 border-b border-border px-3 py-1.5",
66
- children: !enabled ? /* @__PURE__ */ jsx(Button, { icon: /* @__PURE__ */ jsx(AudioLines, {}), variant: "quiet", onClick: () => setEnabled(true), children: " Voice" }) : communicator.loading ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Connecting the voice layer\u2026" }) : communicator.error || !communicator.mandate ? (
67
- // An unresolvable mandate REFUSES loudly — no fallback persona, ever.
68
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-destructive", children: [
69
- "Voice is unavailable: ",
70
- communicator.error ?? "no Communicator bound",
71
- /* @__PURE__ */ jsx(ErrorAlchemyMenu, { error: communicator.error })
72
- ] })
73
- ) : /* @__PURE__ */ jsx(
74
- ActiveVoiceRelay,
108
+ className: props.variant === "toolbar" || props.variant === "composer" ? "flex items-center gap-1" : "flex items-center gap-2 border-b border-border px-3 py-1.5",
109
+ children: !enabled ? /* @__PURE__ */ jsx(Button, { icon: /* @__PURE__ */ jsx(AudioLines, {}), variant: "quiet", onClick: () => setEnabled(true), children: " Voice" }) : /* @__PURE__ */ jsx(
110
+ EnabledVoiceRelay,
75
111
  {
76
112
  ...props,
77
- communicatorAgentId: communicator.mandate.agentId
113
+ onEnd: props.variant === "composer" ? () => setEnabled(false) : void 0
78
114
  }
79
115
  )
80
116
  }
81
117
  );
82
118
  }
119
+ function EnabledVoiceRelay(props) {
120
+ const communicator = useMandate(VOICE_COMMUNICATOR_MANDATE_KEY);
121
+ if (communicator.loading) {
122
+ return /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: "Connecting the voice layer\u2026" });
123
+ }
124
+ if (communicator.error || !communicator.mandate) {
125
+ return /* @__PURE__ */ jsxs(
126
+ "span",
127
+ {
128
+ className: cn(
129
+ "flex min-w-0 items-center gap-1 text-xs text-destructive",
130
+ props.variant === "composer" && "max-w-[14rem]"
131
+ ),
132
+ title: `Voice is unavailable: ${communicator.error ?? "no Communicator bound"}`,
133
+ children: [
134
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: props.variant === "composer" ? "Voice is unavailable" : `Voice is unavailable: ${communicator.error ?? "no Communicator bound"}` }),
135
+ /* @__PURE__ */ jsx(ErrorAlchemyMenu, { error: communicator.error })
136
+ ]
137
+ }
138
+ );
139
+ }
140
+ return /* @__PURE__ */ jsx(
141
+ ActiveVoiceRelay,
142
+ {
143
+ ...props,
144
+ communicatorAgentId: communicator.mandate.agentId,
145
+ autoStart: props.variant === "composer"
146
+ }
147
+ );
148
+ }
83
149
  export {
84
150
  VoiceRelayBar
85
151
  };
@@ -35,6 +35,8 @@ export interface LiveRunWindowProps {
35
35
  label?: string | null;
36
36
  /** The run has been launched but no stream has connected yet. */
37
37
  pending?: boolean;
38
+ /** The launch failed before a stream existed: its reason, shown in the body. */
39
+ failure?: string | null;
38
40
  /**
39
41
  * Per-kind size override. Only pass these once you have WATCHED that kind
40
42
  * render and seen the default box be wrong — a kind whose output is three
@@ -49,4 +51,4 @@ export interface LiveRunWindowProps {
49
51
  workingMessage?: string | null;
50
52
  completeMessage?: string | null;
51
53
  }
52
- export default function LiveRunWindow({ windowInstanceId, onClose, conversationId, requestId, runSetKey, label, pending, width, height, progress, initialMinimized, workingMessage, completeMessage, }: LiveRunWindowProps): React.JSX.Element;
54
+ export default function LiveRunWindow({ windowInstanceId, onClose, conversationId, requestId, runSetKey, label, pending, failure, width, height, progress, initialMinimized, workingMessage, completeMessage, }: LiveRunWindowProps): React.JSX.Element;
@@ -24,6 +24,7 @@ function LiveRunWindow({
24
24
  runSetKey = null,
25
25
  label = null,
26
26
  pending = false,
27
+ failure = null,
27
28
  width = LIVE_RUN_WIDTH,
28
29
  height = LIVE_RUN_HEIGHT,
29
30
  progress = null,
@@ -41,10 +42,11 @@ function LiveRunWindow({
41
42
  const { statusText } = useLiveRunStatus(
42
43
  conversationId,
43
44
  statusRequestId,
44
- pending && !statusRequestId
45
+ pending && !statusRequestId && !failure
45
46
  );
46
47
  const hasOutput = Boolean(requestId || conversationId || runSetKey);
47
- const title = statusText ? `${label ?? "AI is working"} \u2014 ${statusText}` : label ?? "AI is working";
48
+ const phase = failure && !statusRequestId ? "Failed" : statusText;
49
+ const title = phase ? `${label ?? "AI is working"} \u2014 ${phase}` : label ?? "AI is working";
48
50
  return /* @__PURE__ */ jsx(
49
51
  WindowPanel,
50
52
  {
@@ -81,6 +83,7 @@ function LiveRunWindow({
81
83
  conversationId,
82
84
  requestId,
83
85
  pending: pending && !progress,
86
+ failure,
84
87
  variant: "bare",
85
88
  className: "h-full",
86
89
  bodyClassName: "max-h-none h-full overflow-y-auto"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/chat",
3
- "version": "0.3.6",
3
+ "version": "0.3.11",
4
4
  "description": "THE one AI Matrx person-to-agent chat system: the full chat (running agents, conversations, tool calls, streaming, context, surfaces, voice) as per-module subpaths @ai-matrx/chat/<domain>/<module> over a host contract (/host, /host/react) whose only required value is a db; plus the kernel compatibility entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) until P28.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -203,22 +203,22 @@
203
203
  "zod": "^4.6.5",
204
204
  "@ai-matrx/agents": "latest",
205
205
  "@ai-matrx/associations": "latest",
206
- "@ai-matrx/alchemy": "latest",
207
206
  "@ai-matrx/browser-audio": "latest",
207
+ "@ai-matrx/alchemy": "latest",
208
208
  "@ai-matrx/canvas": "latest",
209
+ "@ai-matrx/content-ir": "latest",
210
+ "@ai-matrx/data": "latest",
209
211
  "@ai-matrx/content-ir-react": "latest",
210
212
  "@ai-matrx/diff": "latest",
211
- "@ai-matrx/data": "latest",
212
- "@ai-matrx/icons": "latest",
213
213
  "@ai-matrx/design-system": "latest",
214
- "@ai-matrx/media": "latest",
215
- "@ai-matrx/kit": "latest",
214
+ "@ai-matrx/icons": "latest",
216
215
  "@ai-matrx/print": "latest",
217
216
  "@ai-matrx/realtime": "latest",
218
217
  "@ai-matrx/records": "latest",
219
218
  "@ai-matrx/records-ui": "latest",
220
- "@ai-matrx/tap-target": "latest",
221
- "@ai-matrx/content-ir": "latest"
219
+ "@ai-matrx/media": "latest",
220
+ "@ai-matrx/kit": "latest",
221
+ "@ai-matrx/tap-target": "latest"
222
222
  },
223
223
  "devDependencies": {
224
224
  "@arethetypeswrong/cli": "^0.18.5",