feat(nexus): mount phase 14 providers + drain voice queue in assistant
main.tsx adds VoiceProvider and CommandPaletteProvider to the provider stack, placed above BrowserRouter so both the route tree and the document-level Cmd+K listener see a stable context. PersonalAssistant gains a single-shot effect that, on mount, drains VoiceContext.queue via drainQueue() and feeds each transcript through the existing handleSend pipeline. This implements spec section 5.5 (voice captured on non-Assistant routes streams through on arrival). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2a950dedd0
commit
9b772aa1bd
2 changed files with 45 additions and 23 deletions
|
|
@ -14,6 +14,8 @@ import { SidebarProvider } from "./context/SidebarContext";
|
|||
import { DialogProvider } from "./context/DialogContext";
|
||||
import { ToastProvider } from "./context/ToastContext";
|
||||
import { ThemeProvider } from "./context/ThemeContext";
|
||||
import { VoiceProvider } from "./context/VoiceContext";
|
||||
import { CommandPaletteProvider } from "./context/CommandPaletteContext";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { initPluginBridge } from "./plugins/bridge-init";
|
||||
import { PluginLauncherProvider } from "./plugins/launchers";
|
||||
|
|
@ -41,29 +43,33 @@ createRoot(document.getElementById("root")!).render(
|
|||
<StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider>
|
||||
<BrowserRouter>
|
||||
<CompanyProvider>
|
||||
<ToastProvider>
|
||||
<LiveUpdatesProvider>
|
||||
<TooltipProvider>
|
||||
<BreadcrumbProvider>
|
||||
<SidebarProvider>
|
||||
<PanelProvider>
|
||||
<ChatPanelProvider>
|
||||
<PluginLauncherProvider>
|
||||
<DialogProvider>
|
||||
<App />
|
||||
</DialogProvider>
|
||||
</PluginLauncherProvider>
|
||||
</ChatPanelProvider>
|
||||
</PanelProvider>
|
||||
</SidebarProvider>
|
||||
</BreadcrumbProvider>
|
||||
</TooltipProvider>
|
||||
</LiveUpdatesProvider>
|
||||
</ToastProvider>
|
||||
</CompanyProvider>
|
||||
</BrowserRouter>
|
||||
<VoiceProvider>
|
||||
<CommandPaletteProvider>
|
||||
<BrowserRouter>
|
||||
<CompanyProvider>
|
||||
<ToastProvider>
|
||||
<LiveUpdatesProvider>
|
||||
<TooltipProvider>
|
||||
<BreadcrumbProvider>
|
||||
<SidebarProvider>
|
||||
<PanelProvider>
|
||||
<ChatPanelProvider>
|
||||
<PluginLauncherProvider>
|
||||
<DialogProvider>
|
||||
<App />
|
||||
</DialogProvider>
|
||||
</PluginLauncherProvider>
|
||||
</ChatPanelProvider>
|
||||
</PanelProvider>
|
||||
</SidebarProvider>
|
||||
</BreadcrumbProvider>
|
||||
</TooltipProvider>
|
||||
</LiveUpdatesProvider>
|
||||
</ToastProvider>
|
||||
</CompanyProvider>
|
||||
</BrowserRouter>
|
||||
</CommandPaletteProvider>
|
||||
</VoiceProvider>
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
</StrictMode>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ export function PersonalAssistant() {
|
|||
const queryClient = useQueryClient();
|
||||
const { pushToast } = useToast();
|
||||
const { activeConversationId, setActiveConversationId } = useChatPanel();
|
||||
const voice = useVoice();
|
||||
|
||||
const companyId = selectedCompany?.id ?? null;
|
||||
const companyPrefix = useMemo(
|
||||
|
|
@ -195,6 +196,21 @@ export function PersonalAssistant() {
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [promote.state.kind]);
|
||||
|
||||
// Phase 14 — drain any voice transcripts captured from non-Assistant
|
||||
// routes into the chat pipeline. Runs once per mount; if the queue is
|
||||
// empty the effect is a no-op.
|
||||
const voiceDrainedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (voiceDrainedRef.current) return;
|
||||
if (!companyId) return;
|
||||
if (voice.queue.length === 0) return;
|
||||
voiceDrainedRef.current = true;
|
||||
const drained = voice.drainQueue();
|
||||
for (const text of drained) {
|
||||
handleSend(text);
|
||||
}
|
||||
}, [companyId, voice, handleSend]);
|
||||
|
||||
const handlePromote = useCallback(() => {
|
||||
if (!selectedConvId || !canPromote) return;
|
||||
promote.startPrompting();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue