@ai-matrx/chat 0.3.5 → 0.3.9

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 (38) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/agents/components/chat/ChatNewClient.d.ts +6 -1
  3. package/dist/agents/components/chat/ChatNewClient.js +10 -3
  4. package/dist/agents/components/chat/begin-fresh-chat.d.ts +2 -0
  5. package/dist/agents/components/chat/begin-fresh-chat.js +18 -1
  6. package/dist/agents/components/inputs/smart-input/InputActionButtons.d.ts +4 -0
  7. package/dist/agents/components/inputs/smart-input/InputActionButtons.js +16 -9
  8. package/dist/agents/components/inputs/smart-input/RunControlsMenu.d.ts +2 -0
  9. package/dist/agents/components/inputs/smart-input/RunControlsMenu.js +2 -0
  10. package/dist/agents/components/inputs/smart-input/SmartAgentInputStacked.js +1 -1
  11. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPeek.js +1 -1
  12. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +4 -6
  13. package/dist/agents/components/inputs/smart-input/composer/ComposerOutput.js +9 -4
  14. package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.d.ts +3 -1
  15. package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +2 -2
  16. package/dist/agents/components/inputs/smart-input/composer/composer-types.d.ts +5 -0
  17. package/dist/agents/components/inputs/variable-input-variations/AgentVariableCards.js +1 -1
  18. package/dist/agents/components/shared/AgentOptionsMenu.js +2 -2
  19. package/dist/agents/components/shared/AgentPeekDuplicateButton.d.ts +6 -3
  20. package/dist/agents/components/shared/AgentPeekDuplicateButton.js +8 -7
  21. package/dist/agents/redux/agent-definition/slice.d.ts +16 -1
  22. package/dist/agents/redux/agent-definition/slice.js +20 -0
  23. package/dist/agents/redux/execution-system/message-crud/edit-message.thunk.js +3 -6
  24. package/dist/agents/redux/execution-system/message-crud/fork-and-resubmit-from-message.thunk.js +1 -1
  25. package/dist/agents/types/agent-definition.types.d.ts +29 -1
  26. package/dist/compute/targets.d.ts +2 -6
  27. package/dist/context/sources/scopes.d.ts +3 -3
  28. package/dist/host/ui-slots.js +1 -1
  29. package/dist/host/window-openers.d.ts +21 -5
  30. package/dist/surfaces/lib/ui-surfaces-agent-writes.d.ts +61 -0
  31. package/dist/surfaces/lib/ui-surfaces-agent-writes.js +305 -0
  32. package/dist/surfaces/lib/ui-surfaces-scope.d.ts +40 -0
  33. package/dist/surfaces/lib/ui-surfaces-scope.js +116 -0
  34. package/dist/tool-call-visualization/effects/toolStateEffects.d.ts +1 -1
  35. package/dist/tool-call-visualization/registry/registry.js +0 -2
  36. package/dist/voice-agent/relay/VoiceRelayBar.d.ts +7 -1
  37. package/dist/voice-agent/relay/VoiceRelayBar.js +90 -24
  38. package/package.json +5 -5
@@ -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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/chat",
3
- "version": "0.3.5",
3
+ "version": "0.3.9",
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",
@@ -204,21 +204,21 @@
204
204
  "@ai-matrx/agents": "latest",
205
205
  "@ai-matrx/alchemy": "latest",
206
206
  "@ai-matrx/associations": "latest",
207
- "@ai-matrx/browser-audio": "latest",
208
207
  "@ai-matrx/canvas": "latest",
209
- "@ai-matrx/content-ir": "latest",
208
+ "@ai-matrx/browser-audio": "latest",
210
209
  "@ai-matrx/content-ir-react": "latest",
210
+ "@ai-matrx/content-ir": "latest",
211
211
  "@ai-matrx/data": "latest",
212
212
  "@ai-matrx/design-system": "latest",
213
213
  "@ai-matrx/diff": "latest",
214
214
  "@ai-matrx/icons": "latest",
215
215
  "@ai-matrx/kit": "latest",
216
216
  "@ai-matrx/media": "latest",
217
- "@ai-matrx/print": "latest",
218
217
  "@ai-matrx/realtime": "latest",
219
218
  "@ai-matrx/records": "latest",
220
219
  "@ai-matrx/records-ui": "latest",
221
- "@ai-matrx/tap-target": "latest"
220
+ "@ai-matrx/tap-target": "latest",
221
+ "@ai-matrx/print": "latest"
222
222
  },
223
223
  "devDependencies": {
224
224
  "@arethetypeswrong/cli": "^0.18.5",