@epicbagel/saas-kit 1.21.0 → 1.23.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/chunk-HETZNLKT.cjs +148 -0
- package/dist/chunk-PL2462GA.js +148 -0
- package/dist/primitives/chat.cjs +1204 -23
- package/dist/primitives/chat.js +1206 -25
- package/dist/primitives/voice-session-controls.cjs +2 -2
- package/dist/primitives/voice-session-controls.d.cts +9 -1
- package/dist/primitives/voice-session-controls.d.ts +9 -1
- package/dist/primitives/voice-session-controls.js +1 -1
- package/dist/primitives/workflow-assistant.cjs +35 -69
- package/dist/primitives/workflow-assistant.d.cts +12 -13
- package/dist/primitives/workflow-assistant.d.ts +12 -13
- package/dist/primitives/workflow-assistant.js +32 -66
- package/package.json +1 -1
- package/dist/chunk-4YJ6DGPL.cjs +0 -1215
- package/dist/chunk-C23Q4FRM.js +0 -1215
- package/dist/chunk-KF4X37DP.js +0 -140
- package/dist/chunk-YMI3X2YL.cjs +0 -140
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkHETZNLKTcjs = require('../chunk-HETZNLKT.cjs');
|
|
6
6
|
require('../chunk-NKWHDI4C.cjs');
|
|
7
7
|
require('../chunk-JDEXZGIY.cjs');
|
|
8
8
|
require('../chunk-KWLSBTB2.cjs');
|
|
9
9
|
require('../chunk-2BSFYU22.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
exports.VoiceSessionControls =
|
|
12
|
+
exports.VoiceSessionControls = _chunkHETZNLKTcjs.VoiceSessionControls;
|
|
@@ -22,10 +22,18 @@ interface VoiceSessionControlsProps {
|
|
|
22
22
|
/** Optional external audio store, so level changes only re-render these controls. */
|
|
23
23
|
audioLevels?: VoiceAudioLevelsSource;
|
|
24
24
|
labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry" | "endShort" | "muteShort" | "unmuteShort" | "transcriptPlaceholder", string>>;
|
|
25
|
+
/**
|
|
26
|
+
* Called when someone is about to start (the start control is hovered,
|
|
27
|
+
* pressed or focused), before the click lands. Hosts load their voice
|
|
28
|
+
* transport here so starting doesn't wait for it. It must never touch the
|
|
29
|
+
* microphone: capture belongs to `onStart`, so warming never prompts for
|
|
30
|
+
* permission. It can fire several times; make it idempotent.
|
|
31
|
+
*/
|
|
32
|
+
onWarm?: () => void;
|
|
25
33
|
size?: "icon" | "hero";
|
|
26
34
|
className?: string;
|
|
27
35
|
}
|
|
28
36
|
/** Transport-independent voice controls. The conversation stays visible while speaking. */
|
|
29
|
-
declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, volumeBands, audioLevels, labels, onWarm, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
|
|
30
38
|
|
|
31
39
|
export { type VoiceAudioLevelsSource, VoiceSessionControls, type VoiceSessionControlsProps, type VoiceSessionState };
|
|
@@ -22,10 +22,18 @@ interface VoiceSessionControlsProps {
|
|
|
22
22
|
/** Optional external audio store, so level changes only re-render these controls. */
|
|
23
23
|
audioLevels?: VoiceAudioLevelsSource;
|
|
24
24
|
labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry" | "endShort" | "muteShort" | "unmuteShort" | "transcriptPlaceholder", string>>;
|
|
25
|
+
/**
|
|
26
|
+
* Called when someone is about to start (the start control is hovered,
|
|
27
|
+
* pressed or focused), before the click lands. Hosts load their voice
|
|
28
|
+
* transport here so starting doesn't wait for it. It must never touch the
|
|
29
|
+
* microphone: capture belongs to `onStart`, so warming never prompts for
|
|
30
|
+
* permission. It can fire several times; make it idempotent.
|
|
31
|
+
*/
|
|
32
|
+
onWarm?: () => void;
|
|
25
33
|
size?: "icon" | "hero";
|
|
26
34
|
className?: string;
|
|
27
35
|
}
|
|
28
36
|
/** Transport-independent voice controls. The conversation stays visible while speaking. */
|
|
29
|
-
declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, volumeBands, audioLevels, labels, onWarm, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
|
|
30
38
|
|
|
31
39
|
export { type VoiceAudioLevelsSource, VoiceSessionControls, type VoiceSessionControlsProps, type VoiceSessionState };
|
|
@@ -2,32 +2,7 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
var _chunk4YJ6DGPLcjs = require('../chunk-4YJ6DGPL.cjs');
|
|
7
|
-
require('../chunk-2BTDBZYN.cjs');
|
|
8
|
-
require('../chunk-PH2TV7XI.cjs');
|
|
9
|
-
require('../chunk-YMI3X2YL.cjs');
|
|
10
|
-
require('../chunk-M4V7OJNF.cjs');
|
|
11
|
-
require('../chunk-B765DSRG.cjs');
|
|
12
|
-
require('../chunk-23IETCLV.cjs');
|
|
13
|
-
require('../chunk-DMPSKGFM.cjs');
|
|
14
|
-
require('../chunk-NWDPH2Z7.cjs');
|
|
15
|
-
require('../chunk-Z2H4LJVG.cjs');
|
|
16
|
-
require('../chunk-7LDJAXRX.cjs');
|
|
17
|
-
require('../chunk-2HV2KKOE.cjs');
|
|
18
|
-
require('../chunk-ZLEM2SAU.cjs');
|
|
19
|
-
require('../chunk-KENBU3NV.cjs');
|
|
20
|
-
require('../chunk-ELPV44S6.cjs');
|
|
21
|
-
require('../chunk-2BHI5ZWJ.cjs');
|
|
22
|
-
require('../chunk-ZAITUDYD.cjs');
|
|
23
|
-
require('../chunk-U2NES7VR.cjs');
|
|
24
|
-
require('../chunk-V4YWTRLD.cjs');
|
|
25
|
-
require('../chunk-373W6VAD.cjs');
|
|
26
|
-
require('../chunk-W5HPHEE7.cjs');
|
|
27
|
-
require('../chunk-FYRQFEU4.cjs');
|
|
28
|
-
require('../chunk-2KFZQJH5.cjs');
|
|
29
|
-
require('../chunk-PQUSJEXL.cjs');
|
|
30
|
-
require('../chunk-WABCLRBR.cjs');
|
|
5
|
+
var _chunkHETZNLKTcjs = require('../chunk-HETZNLKT.cjs');
|
|
31
6
|
require('../chunk-NKWHDI4C.cjs');
|
|
32
7
|
|
|
33
8
|
|
|
@@ -36,10 +11,6 @@ var _chunkJDEXZGIYcjs = require('../chunk-JDEXZGIY.cjs');
|
|
|
36
11
|
|
|
37
12
|
var _chunkKWLSBTB2cjs = require('../chunk-KWLSBTB2.cjs');
|
|
38
13
|
require('../chunk-2BSFYU22.cjs');
|
|
39
|
-
require('../chunk-4LXN6GLZ.cjs');
|
|
40
|
-
require('../chunk-7Q4EFCUI.cjs');
|
|
41
|
-
require('../chunk-R35FT53G.cjs');
|
|
42
|
-
require('../chunk-H2UFRLLN.cjs');
|
|
43
14
|
|
|
44
15
|
// src/primitives/workflow-assistant.tsx
|
|
45
16
|
var _react = require('react');
|
|
@@ -62,15 +33,11 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
|
|
|
62
33
|
title = "Voice review",
|
|
63
34
|
context,
|
|
64
35
|
description,
|
|
65
|
-
|
|
66
|
-
value,
|
|
67
|
-
onChange,
|
|
68
|
-
onSend,
|
|
36
|
+
summaries,
|
|
69
37
|
voiceSession,
|
|
70
38
|
pending,
|
|
71
39
|
disabled,
|
|
72
40
|
error,
|
|
73
|
-
placeholder = "Describe an action\u2026",
|
|
74
41
|
besideCornerAction = false,
|
|
75
42
|
labels,
|
|
76
43
|
className
|
|
@@ -89,9 +56,10 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
|
|
|
89
56
|
moveFocus.current = true;
|
|
90
57
|
onOpenChange(next);
|
|
91
58
|
};
|
|
92
|
-
const startDisabled = pending || disabled ||
|
|
93
|
-
const active = voiceSession
|
|
94
|
-
const status = voiceSession
|
|
59
|
+
const startDisabled = pending || disabled || voiceSession.disabled;
|
|
60
|
+
const active = voiceSession.state !== "disconnected" && voiceSession.state !== "error";
|
|
61
|
+
const status = voiceSession.muted && voiceSession.state === "listening" ? _nullishCoalesce(_optionalChain([voiceSession, 'access', _3 => _3.labels, 'optionalAccess', _4 => _4.muted]), () => ( "Microphone muted")) : _nullishCoalesce(_optionalChain([voiceSession, 'access', _5 => _5.labels, 'optionalAccess', _6 => _6[voiceSession.state]]), () => ( SESSION_LABELS[voiceSession.state]));
|
|
62
|
+
const unavailable = voiceSession.state === "error" && voiceSession.disabled;
|
|
95
63
|
if (!open) return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
96
64
|
"aside",
|
|
97
65
|
{
|
|
@@ -107,17 +75,17 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
|
|
|
107
75
|
type: "button",
|
|
108
76
|
shape: "pill",
|
|
109
77
|
className: "min-h-12 min-w-12 max-w-full gap-2 shadow-lg",
|
|
110
|
-
disabled: startDisabled && !active,
|
|
111
|
-
"aria-label": active ? title : _nullishCoalesce(_optionalChain([labels, 'optionalAccess',
|
|
78
|
+
disabled: startDisabled && !active && !unavailable,
|
|
79
|
+
"aria-label": active ? title : unavailable ? "Voice review unavailable" : _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _7 => _7.start]), () => ( "Start voice review")),
|
|
112
80
|
"aria-expanded": false,
|
|
113
81
|
"aria-describedby": active ? statusId : void 0,
|
|
114
82
|
onClick: () => {
|
|
115
83
|
toggle(true);
|
|
116
|
-
if (!active && !startDisabled)
|
|
84
|
+
if (!active && !startDisabled) voiceSession.onStart();
|
|
117
85
|
},
|
|
118
86
|
children: [
|
|
119
87
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AudioLines, { "aria-hidden": "true", className: "shrink-0" }),
|
|
120
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : title })
|
|
88
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : unavailable ? "Voice unavailable" : title })
|
|
121
89
|
]
|
|
122
90
|
}
|
|
123
91
|
),
|
|
@@ -130,10 +98,10 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
|
|
|
130
98
|
size: "icon",
|
|
131
99
|
className: "min-h-12 min-w-12 bg-background shadow-lg",
|
|
132
100
|
onClick: () => {
|
|
133
|
-
_optionalChain([launcher, 'access',
|
|
101
|
+
_optionalChain([launcher, 'access', _8 => _8.current, 'optionalAccess', _9 => _9.focus, 'call', _10 => _10()]);
|
|
134
102
|
voiceSession.onEnd();
|
|
135
103
|
},
|
|
136
|
-
"aria-label": _nullishCoalesce(_nullishCoalesce(_optionalChain([labels, 'optionalAccess',
|
|
104
|
+
"aria-label": _nullishCoalesce(_nullishCoalesce(_optionalChain([labels, 'optionalAccess', _11 => _11.end]), () => ( _optionalChain([voiceSession, 'access', _12 => _12.labels, 'optionalAccess', _13 => _13.end]))), () => ( "End voice chat")),
|
|
137
105
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Square, { "aria-hidden": "true" })
|
|
138
106
|
}
|
|
139
107
|
)
|
|
@@ -163,38 +131,36 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
|
|
|
163
131
|
type: "button",
|
|
164
132
|
variant: "ghost",
|
|
165
133
|
size: "icon",
|
|
166
|
-
"aria-label": expanded ? _nullishCoalesce(_optionalChain([labels, 'optionalAccess',
|
|
134
|
+
"aria-label": expanded ? _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _14 => _14.collapse]), () => ( "Reduce panel")) : _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _15 => _15.expand]), () => ( "Expand panel")),
|
|
167
135
|
onClick: () => onExpandedChange(!expanded),
|
|
168
136
|
children: expanded ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Minimize2, { "aria-hidden": "true" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Maximize2, { "aria-hidden": "true" })
|
|
169
137
|
}
|
|
170
138
|
),
|
|
171
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", variant: "ghost", size: "icon", "aria-label": _nullishCoalesce(_optionalChain([labels, 'optionalAccess',
|
|
139
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", variant: "ghost", size: "icon", "aria-label": _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _16 => _16.minimize]), () => ( "Minimize voice review")), onClick: () => toggle(false), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { "aria-hidden": "true" }) })
|
|
172
140
|
] }),
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
_chunk4YJ6DGPLcjs.ChatThread,
|
|
176
|
-
{
|
|
177
|
-
messages,
|
|
178
|
-
pending,
|
|
179
|
-
maxHeight: expanded ? "60dvh" : "32dvh",
|
|
180
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex-1 px-3", messages.length > 0 || pending ? "min-h-24" : "min-h-0")
|
|
181
|
-
}
|
|
182
|
-
),
|
|
183
|
-
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
|
|
184
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0 p-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
185
|
-
_chunk4YJ6DGPLcjs.ChatInput,
|
|
141
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0", "data-slot": "workflow-assistant-voice", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
142
|
+
_chunkHETZNLKTcjs.VoiceSessionControls,
|
|
186
143
|
{
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
voiceSession
|
|
144
|
+
...voiceSession,
|
|
145
|
+
disabled: Boolean(startDisabled),
|
|
146
|
+
size: "hero",
|
|
147
|
+
onEnd: () => {
|
|
148
|
+
_optionalChain([heading, 'access', _17 => _17.current, 'optionalAccess', _18 => _18.focus, 'call', _19 => _19()]);
|
|
149
|
+
voiceSession.onEnd();
|
|
150
|
+
},
|
|
151
|
+
className: _chunkKWLSBTB2cjs.cn.call(void 0, !active && "justify-center px-4 py-6 text-center")
|
|
196
152
|
}
|
|
197
|
-
) })
|
|
153
|
+
) }),
|
|
154
|
+
description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0 px-4 py-3 text-sm text-muted-foreground", children: description }),
|
|
155
|
+
error && (voiceSession.state !== "error" || error !== voiceSession.error) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
|
|
156
|
+
pending && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "status", className: "shrink-0 px-4 py-2 text-sm text-muted-foreground", children: "Applying your instructions\u2026" }),
|
|
157
|
+
summaries.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { "aria-label": "Action summaries", className: "min-h-20 flex-1 overflow-y-auto border-t px-4 py-3", children: [
|
|
158
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-3 text-xs font-medium text-muted-foreground", children: "Action summaries" }),
|
|
159
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "space-y-3", "aria-live": "polite", "aria-relevant": "additions", children: [...summaries].reverse().map((summary) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { className: "space-y-1 border-b pb-3 last:border-0 last:pb-0", children: [
|
|
160
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: summary.context }),
|
|
161
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-pre-wrap break-words text-sm", children: summary.body })
|
|
162
|
+
] }, summary.id)) })
|
|
163
|
+
] })
|
|
198
164
|
]
|
|
199
165
|
}
|
|
200
166
|
);
|
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { ChatMessage } from './chat.cjs';
|
|
4
3
|
import { VoiceSessionControlsProps } from './voice-session-controls.cjs';
|
|
5
4
|
import 'react/jsx-runtime';
|
|
6
|
-
import './markdown.cjs';
|
|
7
|
-
import 'react-markdown';
|
|
8
|
-
import './rich-text.cjs';
|
|
9
5
|
|
|
6
|
+
interface WorkflowSummary {
|
|
7
|
+
id: string;
|
|
8
|
+
/** Scope at the time of the action, which may differ from the current list. */
|
|
9
|
+
context: string;
|
|
10
|
+
body: string;
|
|
11
|
+
}
|
|
10
12
|
interface WorkflowAssistantProps {
|
|
11
13
|
open: boolean;
|
|
12
14
|
onOpenChange: (open: boolean) => void;
|
|
13
15
|
expanded?: boolean;
|
|
14
16
|
onExpandedChange?: (expanded: boolean) => void;
|
|
15
17
|
title?: string;
|
|
16
|
-
/** Current host-owned scope. Keep it visible while the
|
|
18
|
+
/** Current host-owned scope. Keep it visible while the summaries scroll. */
|
|
17
19
|
context: string;
|
|
18
20
|
description?: ReactNode;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
onChange: (value: string) => void;
|
|
22
|
-
onSend: (value: string) => void;
|
|
21
|
+
/** Saved action receipts and clarification questions, newest last. Read-only. */
|
|
22
|
+
summaries: WorkflowSummary[];
|
|
23
23
|
/** Minimizing preserves this host-owned session; only End calls onEnd. */
|
|
24
|
-
voiceSession
|
|
24
|
+
voiceSession: VoiceSessionControlsProps;
|
|
25
25
|
pending?: boolean;
|
|
26
26
|
disabled?: boolean;
|
|
27
27
|
error?: string | null;
|
|
28
|
-
placeholder?: string;
|
|
29
28
|
/** Leave room for an existing corner action such as New. */
|
|
30
29
|
besideCornerAction?: boolean;
|
|
31
30
|
labels?: {
|
|
@@ -37,8 +36,8 @@ interface WorkflowAssistantProps {
|
|
|
37
36
|
};
|
|
38
37
|
className?: string;
|
|
39
38
|
}
|
|
40
|
-
/**
|
|
39
|
+
/** Voice-only workflow controls: the underlying list stays usable.
|
|
41
40
|
* The host owns scope, authorization, persistence and the voice connection. */
|
|
42
41
|
declare const WorkflowAssistant: React.ForwardRefExoticComponent<WorkflowAssistantProps & React.RefAttributes<HTMLElement>>;
|
|
43
42
|
|
|
44
|
-
export { WorkflowAssistant, type WorkflowAssistantProps };
|
|
43
|
+
export { WorkflowAssistant, type WorkflowAssistantProps, type WorkflowSummary };
|
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { ChatMessage } from './chat.js';
|
|
4
3
|
import { VoiceSessionControlsProps } from './voice-session-controls.js';
|
|
5
4
|
import 'react/jsx-runtime';
|
|
6
|
-
import './markdown.js';
|
|
7
|
-
import 'react-markdown';
|
|
8
|
-
import './rich-text.js';
|
|
9
5
|
|
|
6
|
+
interface WorkflowSummary {
|
|
7
|
+
id: string;
|
|
8
|
+
/** Scope at the time of the action, which may differ from the current list. */
|
|
9
|
+
context: string;
|
|
10
|
+
body: string;
|
|
11
|
+
}
|
|
10
12
|
interface WorkflowAssistantProps {
|
|
11
13
|
open: boolean;
|
|
12
14
|
onOpenChange: (open: boolean) => void;
|
|
13
15
|
expanded?: boolean;
|
|
14
16
|
onExpandedChange?: (expanded: boolean) => void;
|
|
15
17
|
title?: string;
|
|
16
|
-
/** Current host-owned scope. Keep it visible while the
|
|
18
|
+
/** Current host-owned scope. Keep it visible while the summaries scroll. */
|
|
17
19
|
context: string;
|
|
18
20
|
description?: ReactNode;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
onChange: (value: string) => void;
|
|
22
|
-
onSend: (value: string) => void;
|
|
21
|
+
/** Saved action receipts and clarification questions, newest last. Read-only. */
|
|
22
|
+
summaries: WorkflowSummary[];
|
|
23
23
|
/** Minimizing preserves this host-owned session; only End calls onEnd. */
|
|
24
|
-
voiceSession
|
|
24
|
+
voiceSession: VoiceSessionControlsProps;
|
|
25
25
|
pending?: boolean;
|
|
26
26
|
disabled?: boolean;
|
|
27
27
|
error?: string | null;
|
|
28
|
-
placeholder?: string;
|
|
29
28
|
/** Leave room for an existing corner action such as New. */
|
|
30
29
|
besideCornerAction?: boolean;
|
|
31
30
|
labels?: {
|
|
@@ -37,8 +36,8 @@ interface WorkflowAssistantProps {
|
|
|
37
36
|
};
|
|
38
37
|
className?: string;
|
|
39
38
|
}
|
|
40
|
-
/**
|
|
39
|
+
/** Voice-only workflow controls: the underlying list stays usable.
|
|
41
40
|
* The host owns scope, authorization, persistence and the voice connection. */
|
|
42
41
|
declare const WorkflowAssistant: React.ForwardRefExoticComponent<WorkflowAssistantProps & React.RefAttributes<HTMLElement>>;
|
|
43
42
|
|
|
44
|
-
export { WorkflowAssistant, type WorkflowAssistantProps };
|
|
43
|
+
export { WorkflowAssistant, type WorkflowAssistantProps, type WorkflowSummary };
|
|
@@ -1,33 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
"use client";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "../chunk-C23Q4FRM.js";
|
|
7
|
-
import "../chunk-Z45YKVAM.js";
|
|
8
|
-
import "../chunk-ZGTPNSR7.js";
|
|
9
|
-
import "../chunk-KF4X37DP.js";
|
|
10
|
-
import "../chunk-IJG2B3Y2.js";
|
|
11
|
-
import "../chunk-IW4ZIXXG.js";
|
|
12
|
-
import "../chunk-OUZSIA5G.js";
|
|
13
|
-
import "../chunk-36LNA4WM.js";
|
|
14
|
-
import "../chunk-H4XH2PPU.js";
|
|
15
|
-
import "../chunk-GA5SX7FE.js";
|
|
16
|
-
import "../chunk-QTPPNK6F.js";
|
|
17
|
-
import "../chunk-6FC65AZQ.js";
|
|
18
|
-
import "../chunk-WHDHUYS6.js";
|
|
19
|
-
import "../chunk-VY5U4VGV.js";
|
|
20
|
-
import "../chunk-INNGGLMZ.js";
|
|
21
|
-
import "../chunk-4HWCNRK4.js";
|
|
22
|
-
import "../chunk-V4LE2HWP.js";
|
|
23
|
-
import "../chunk-ZRLUUZHK.js";
|
|
24
|
-
import "../chunk-F366BHWH.js";
|
|
25
|
-
import "../chunk-EIY5LLSP.js";
|
|
26
|
-
import "../chunk-NBUWGRQO.js";
|
|
27
|
-
import "../chunk-CYDICVH2.js";
|
|
28
|
-
import "../chunk-42RTTHND.js";
|
|
29
|
-
import "../chunk-QMA3WVB7.js";
|
|
30
|
-
import "../chunk-3OWGL4Q2.js";
|
|
4
|
+
VoiceSessionControls
|
|
5
|
+
} from "../chunk-PL2462GA.js";
|
|
31
6
|
import "../chunk-5OF6D3GH.js";
|
|
32
7
|
import {
|
|
33
8
|
Button
|
|
@@ -36,10 +11,6 @@ import {
|
|
|
36
11
|
cn
|
|
37
12
|
} from "../chunk-G6SRSWXB.js";
|
|
38
13
|
import "../chunk-GJ7S3L6R.js";
|
|
39
|
-
import "../chunk-ZWZAAGQF.js";
|
|
40
|
-
import "../chunk-RPSRCB5O.js";
|
|
41
|
-
import "../chunk-PIU5SSUV.js";
|
|
42
|
-
import "../chunk-CS7DM3NV.js";
|
|
43
14
|
|
|
44
15
|
// src/primitives/workflow-assistant.tsx
|
|
45
16
|
import { forwardRef, useEffect, useId, useRef } from "react";
|
|
@@ -62,15 +33,11 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
|
|
|
62
33
|
title = "Voice review",
|
|
63
34
|
context,
|
|
64
35
|
description,
|
|
65
|
-
|
|
66
|
-
value,
|
|
67
|
-
onChange,
|
|
68
|
-
onSend,
|
|
36
|
+
summaries,
|
|
69
37
|
voiceSession,
|
|
70
38
|
pending,
|
|
71
39
|
disabled,
|
|
72
40
|
error,
|
|
73
|
-
placeholder = "Describe an action\u2026",
|
|
74
41
|
besideCornerAction = false,
|
|
75
42
|
labels,
|
|
76
43
|
className
|
|
@@ -89,9 +56,10 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
|
|
|
89
56
|
moveFocus.current = true;
|
|
90
57
|
onOpenChange(next);
|
|
91
58
|
};
|
|
92
|
-
const startDisabled = pending || disabled || voiceSession
|
|
93
|
-
const active = voiceSession
|
|
94
|
-
const status = voiceSession
|
|
59
|
+
const startDisabled = pending || disabled || voiceSession.disabled;
|
|
60
|
+
const active = voiceSession.state !== "disconnected" && voiceSession.state !== "error";
|
|
61
|
+
const status = voiceSession.muted && voiceSession.state === "listening" ? voiceSession.labels?.muted ?? "Microphone muted" : voiceSession.labels?.[voiceSession.state] ?? SESSION_LABELS[voiceSession.state];
|
|
62
|
+
const unavailable = voiceSession.state === "error" && voiceSession.disabled;
|
|
95
63
|
if (!open) return /* @__PURE__ */ jsxs(
|
|
96
64
|
"aside",
|
|
97
65
|
{
|
|
@@ -107,17 +75,17 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
|
|
|
107
75
|
type: "button",
|
|
108
76
|
shape: "pill",
|
|
109
77
|
className: "min-h-12 min-w-12 max-w-full gap-2 shadow-lg",
|
|
110
|
-
disabled: startDisabled && !active,
|
|
111
|
-
"aria-label": active ? title : labels?.start ?? "Start voice review",
|
|
78
|
+
disabled: startDisabled && !active && !unavailable,
|
|
79
|
+
"aria-label": active ? title : unavailable ? "Voice review unavailable" : labels?.start ?? "Start voice review",
|
|
112
80
|
"aria-expanded": false,
|
|
113
81
|
"aria-describedby": active ? statusId : void 0,
|
|
114
82
|
onClick: () => {
|
|
115
83
|
toggle(true);
|
|
116
|
-
if (!active && !startDisabled) voiceSession
|
|
84
|
+
if (!active && !startDisabled) voiceSession.onStart();
|
|
117
85
|
},
|
|
118
86
|
children: [
|
|
119
87
|
/* @__PURE__ */ jsx(AudioLines, { "aria-hidden": "true", className: "shrink-0" }),
|
|
120
|
-
/* @__PURE__ */ jsx("span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : title })
|
|
88
|
+
/* @__PURE__ */ jsx("span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : unavailable ? "Voice unavailable" : title })
|
|
121
89
|
]
|
|
122
90
|
}
|
|
123
91
|
),
|
|
@@ -170,31 +138,29 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
|
|
|
170
138
|
),
|
|
171
139
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": labels?.minimize ?? "Minimize voice review", onClick: () => toggle(false), children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
|
|
172
140
|
] }),
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
ChatThread,
|
|
141
|
+
/* @__PURE__ */ jsx("div", { className: "shrink-0", "data-slot": "workflow-assistant-voice", children: /* @__PURE__ */ jsx(
|
|
142
|
+
VoiceSessionControls,
|
|
176
143
|
{
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
ChatInput,
|
|
186
|
-
{
|
|
187
|
-
value,
|
|
188
|
-
onChange,
|
|
189
|
-
onSend,
|
|
190
|
-
disabled,
|
|
191
|
-
pending,
|
|
192
|
-
placeholder,
|
|
193
|
-
size: "sm",
|
|
194
|
-
voice: false,
|
|
195
|
-
voiceSession
|
|
144
|
+
...voiceSession,
|
|
145
|
+
disabled: Boolean(startDisabled),
|
|
146
|
+
size: "hero",
|
|
147
|
+
onEnd: () => {
|
|
148
|
+
heading.current?.focus();
|
|
149
|
+
voiceSession.onEnd();
|
|
150
|
+
},
|
|
151
|
+
className: cn(!active && "justify-center px-4 py-6 text-center")
|
|
196
152
|
}
|
|
197
|
-
) })
|
|
153
|
+
) }),
|
|
154
|
+
description && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-4 py-3 text-sm text-muted-foreground", children: description }),
|
|
155
|
+
error && (voiceSession.state !== "error" || error !== voiceSession.error) && /* @__PURE__ */ jsx("p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
|
|
156
|
+
pending && /* @__PURE__ */ jsx("p", { role: "status", className: "shrink-0 px-4 py-2 text-sm text-muted-foreground", children: "Applying your instructions\u2026" }),
|
|
157
|
+
summaries.length > 0 && /* @__PURE__ */ jsxs("section", { "aria-label": "Action summaries", className: "min-h-20 flex-1 overflow-y-auto border-t px-4 py-3", children: [
|
|
158
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-3 text-xs font-medium text-muted-foreground", children: "Action summaries" }),
|
|
159
|
+
/* @__PURE__ */ jsx("ol", { className: "space-y-3", "aria-live": "polite", "aria-relevant": "additions", children: [...summaries].reverse().map((summary) => /* @__PURE__ */ jsxs("li", { className: "space-y-1 border-b pb-3 last:border-0 last:pb-0", children: [
|
|
160
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: summary.context }),
|
|
161
|
+
/* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap break-words text-sm", children: summary.body })
|
|
162
|
+
] }, summary.id)) })
|
|
163
|
+
] })
|
|
198
164
|
]
|
|
199
165
|
}
|
|
200
166
|
);
|
package/package.json
CHANGED