teqo/src/components/campaign/shell/ai/CampaignAIHeaderButton.tsx
Francisco Ignácio Fontoura Solla f9cd1df7b2 feat: AI chat 'Sollinha' — campaign data assistant (v1 read-only)
- Streaming AI endpoint at /campanha/api/ai-chat with DeepSeek V4 Flash
- 8 tools: calculate, getMunicipalityVotes, getTopDeputies, getDobradinhas,
  getMunicipalityOverview, getLeaderships, getOrganizations, searchEntities
- In-memory rate limiter (50 msgs / 15 min per user)
- Desktop: resizable right sidebar via react-resizable-panels
- Mobile: full-screen Drawer opened by FAB (2/3 size of quick-actions FAB)
- Markdown rendering with react-markdown + remark-gfm (tables, bold, lists)
- Session-bound context (clean slate each open)
- Auth via existing campaign-token cookie, tools respect user RBAC
- Architecture doc: docs/plans/ai-chat-sollinha.md
- E2E tests: campaignAiChat.e2e.spec.ts (mocked endpoint)
2026-08-04 06:17:31 -03:00

26 lines
682 B
TypeScript

'use client'
import { Bot } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import { useAISidebar } from '@/components/campaign/shell/ai/CampaignAISidebarContext'
export const CampaignAIHeaderButton = ({ className }: { className?: string }) => {
const ctx = useAISidebar()
return (
<Button
type="button"
variant="ghost"
size="icon"
className={cn('size-11 hidden shrink-0 md:inline-flex', className)}
aria-label="Sollinha — Assistente virtual"
title="Sollinha — Assistente virtual"
onClick={() => ctx?.toggle()}
>
<Bot className="size-5" />
</Button>
)
}