Commit Graph

10 Commits

Author SHA1 Message Date
juanatsap be5fdd03c4 feat: chat avatars + dark theme fix + text overflow fix
Avatars:
- Robot icon (green circle) before each agent message
- Person icon (dark circle) before each user message
- New .chat-bubble wrapper with flex layout for avatar + message

Dark theme fixes:
- Panel background: #1e1e1e (not pure black)
- Agent bubbles: #2d2d2d with light text (not dark/invisible)
- Input area: #2d2d2d (not black)
- Header stays green (--accent-green) in both themes
- Chips, suggestions consistent with panel background

Text overflow:
- overflow-wrap + word-break on messages
- min-width: 0 prevents flex overflow
- User bubble properly right-aligned with avatar
2026-04-08 17:31:07 +01:00
juanatsap c44e9e8c67 feat: CV navigation links in chat responses (GPS for the CV)
Agent instruction now requires markdown links to CV anchors:
- Companies: [Olympic Broadcasting](#exp-olympic-broadcasting)
- Projects: [Immich Photo Manager](#proj-immich-photo-manager)
- Sections: [Skills](#skills), [Experience](#experience)

formatResponse converts [text](#anchor) → clickable green links
that close the chat panel, smooth-scroll to the target, and
pulse a green highlight for 2 seconds.

All existing CV anchor IDs used: exp-{companyID}, proj-{projectID},
course-{courseID}, plus section IDs (experience, projects, skills, etc.)
2026-04-08 17:11:22 +01:00
juanatsap 160be31b31 feat: auto-fallback Gemini→Ollama + model warmup on chat open
Dual-provider architecture:
- Both Gemini and Ollama initialize at startup (if configured)
- Primary (Gemini) tried first for every request
- On any error (429, 503, timeout), automatically falls back to Ollama
- No manual switching needed — completely transparent to the user
- Log shows: "Primary failed (gemini: ...), falling back to ollama: ..."

Warmup:
- POST /api/chat/warmup called silently when chat panel opens
- Pre-loads Ollama model in background (10-15s) while user reads welcome
- By the time user types, model is ready for instant response
- Warms up fallback provider specifically (Gemini doesn't need it)

Timeout:
- Agent context increased to 60s (Ollama first response can be slow)
- Each request creates a fresh session (stateless for fallback compat)
2026-04-08 14:57:38 +01:00
juanatsap 8205a22972 feat: Ollama adapter + chat rate limiter (30 req/hour)
Ollama adapter (internal/chat/ollama.go):
- Implements model.LLM interface for ADK Go
- Talks to Ollama's OpenAI-compatible API (/v1/chat/completions)
- Full tool/function calling support (tested with Mistral Small 3.2)
- Converts ADK types to OpenAI format (messages, tools, tool_calls)
- Configurable via OLLAMA_HOST and OLLAMA_MODEL env vars

Multi-provider handler:
- MODEL_PROVIDER env: "gemini" (default) or "ollama"
- Gemini: requires GOOGLE_API_KEY (pay-as-you-go recommended)
- Ollama: connects to local or Tailscale-remote instance

Rate limiter:
- 30 requests/hour per IP on /api/chat endpoint
- Uses existing middleware.NewRateLimiter pattern

Tested: Ollama + Mistral Small 3.2 on M4 Pro 64GB — correct answers
2026-04-08 14:47:14 +01:00
juanatsap 4f558ac842 fix: replace Hyperscript with plain JS for chat interactions
The Hyperscript trigger/call commands couldn't reliably trigger HTMX
form submissions or call global JS functions. Moved all chat
interactions to plain JavaScript:

- toggleChatPanel(): open/close panel + icon swap
- sendChatQuestion(q): set input + htmx.trigger(form, 'submit')
- closeChatHelpAndAsk(q): close modal + open chat + send question
- htmx:afterRequest listener clears input after submit

Hyperscript kept only for site-wide patterns (closeOnBackdrop) that
work reliably.

Also: better error message for rate-limited API responses (429).
2026-04-08 14:11:11 +01:00
juanatsap 94976e1c19 feat: help modal, comprehensive intelligence, fix right-side position
Position fix:
- Remove _chat.css @import from main.css (was overriding with old
  left:2rem cached version). Chat CSS now loaded only via head-styles.
- Button confirmed at right:2rem, bottom:6rem (above back-to-top)

Help modal:
- New chat-help-modal.html using same <dialog> pattern as shortcuts
- 6 organized categories: Experience, Technologies, Projects,
  Education, Skills, How it works
- Bilingual EN/ES with example questions per category
- ? button in header opens modal via commandfor/show-modal
- Removed inline help card (modal replaces it)

Intelligence:
- Comprehensive query strategy for 8 question types
- Technology queries always use cross-section search
- Company queries use experience without filter for full listing
- Agent knows CV site is built with Go/HTMX (bonus context)
- Skills report proficiency levels when technology found
2026-04-08 13:15:07 +01:00
juanatsap 795ba88d6f fix: match CV design system, right-side positioning, smarter agent
CSS:
- Button moved to right: 2rem, above back-to-top (bottom: 6rem)
- Uses CV design tokens: --black-bar, --accent-blue, --paper-bg
- Fonts: Quicksand (header), Source Sans Pro (body)
- Tooltip on the left side (tooltip-left class)
- Dark theme uses CV-consistent grays

Intelligence:
- Agent instruction emphasizes exhaustive reporting of ALL matches
- Cross-section search results must not be truncated
- Mentions CV site itself is built with Go when relevant

Tests:
- Updated positioning assertions (right side, x > viewport/2)
- Added 5 intelligence tests: Go cross-section, company count,
  years of experience, React cross-section, Spanish response
- Resilient to API errors (waits for any message, not just user)
- 42 total test assertions
2026-04-08 13:04:47 +01:00
juanatsap 93e33f6496 fix: chat submission and session handling + 37 Playwright tests
- Fix chip auto-submit: use htmx.trigger() instead of native submit
  to bypass browser validation on required field
- Remove required from input (server validates already)
- Fix session_id duplication: use hx-swap-oob to replace single input
- Fix agent context: use background context with 30s timeout instead
  of HTTP request context (prevents premature cancellation)
- Remove redundant close button from header (toggle button handles it)
- Add 83-chat-mascot.test.mjs: 37 tests covering button, panel,
  help card, chips, typed questions, session, Spanish, positioning
2026-04-08 11:31:09 +01:00
juanatsap eddc424962 fix: cross-section search and CSS loading for chat widget
- agent.go: add section="search" that queries experience, projects,
  skills, and courses simultaneously — fixes missing results when
  a technology spans multiple CV sections (e.g. Java at Insa)
- head-styles.html: use modular CSS in development mode and load
  chat CSS separately — fixes unstyled page when bundle is stale
2026-04-08 00:44:16 +01:00
juanatsap f5276431ea feat: add AI chat widget powered by ADK Go 1.0
Visitors can ask questions about the CV via a floating chat panel.
The agent uses Gemini to answer questions about experience, projects,
skills, and education by querying the cached CV JSON data.

- internal/chat/agent.go: LLM agent with query_cv tool that searches
  CV data by section (experience, projects, skills, etc.) with keyword filtering
- internal/chat/handler.go: POST /api/chat endpoint with session management,
  graceful degradation when GOOGLE_API_KEY is not set
- chat-widget.html: HTMX-powered floating chat panel with Hyperscript toggle
- _chat.css: Responsive chat UI with dark theme support
- Wired into existing architecture via dependency injection (CVHandler,
  routes, main.go) — zero breaking changes, all existing tests pass
2026-04-08 00:20:48 +01:00