Commit graph

3 commits

Author SHA1 Message Date
Victor Hugo Vargas
550ba526c4 feat(sse): emit compaction event after start, before sources/chunk
streaming.WriteCompaction packages a 'compaction' event with the
kept/older turn counts, summary tokens and provider-reported
window/used tokens so the client can hint 'context optimized' to the
user without parsing the stream body.

streamChat runs Compact before BuildMessages and writes the event
right after start, ensuring the client sees it before any chunk is
emitted. Add a runner test that exercises limitRAGContext to keep
the system prompt + RAG block under the configured window.
2026-07-18 00:08:22 -07:00
Victor Hugo Vargas
18e555e338 feat: persistent conversation storage (Phase 4)
Conversations survive page reloads and work for any frontend, not just
the widget. Server-side SQLite, conversation ID as bearer token, browser
identity via localStorage.

Backend
-------
- internal/portfolio/conversations.go: schema + CRUD. Conversations and
  messages tables in the same SQLite DB as the RAG index, with
  foreign-key cascade delete. Conv IDs are 16-byte random hex
  (128 bits of entropy).
- internal/portfolio/indexer.go: applies conversation schema + enables
  foreign_keys pragma in OpenStore.
- internal/server/handlers.go: POST /api/chat accepts an optional
  conversation_id, mints one if absent, persists user message before
  the LLM runs and assistant message (with sources) after the stream
  completes. New handlers: GetConversation, ListConversations,
  DeleteConversation.
- internal/server/server.go: routes for GET /api/conversations,
  GET/DELETE /api/conversations/{id}.
- internal/server/conversations_test.go: 6 tests (round-trip, continue,
  list, 404, delete, streaming).

Widget
------
- web/chat-widget.js: stores conv_id in localStorage["rony-chat-conv"],
  includes it in the chat request body, captures new IDs from the
  server's 'start' SSE event, and calls GET /api/conversations/{id} on
  load to restore history. On 404 it clears the stored ID and starts
  fresh.

Docs
----
- docs/architecture.md: §3.1 documents the conversation_id field and
  new REST endpoints; new §3.4 covers persistence lifecycle, schema,
  client responsibilities, and auth model. §5.6 updated; filetree
  reflects the new files.
- web/README.md: new 'Conversation persistence' section explains the
  browser-scoped behavior and how to opt out or persist across devices.
2026-07-17 00:56:35 -07:00
Victor Hugo Vargas
f33708534a feat: bootstrap rony-chat-bot Go module
Initial implementation of the bot:

- cmd/chat-bot: CLI entrypoint (serve, reindex, ask, version)
- internal/agent: LLM provider client + agent runner with RAG injection
- internal/config: YAML config loader (providers, RAG, persona, server)
- internal/i18n: response-language detection (EN/ES)
- internal/persona: persona system prompt assembly from YAML
- internal/portfolio: heading-based chunker + SQLite FTS5 indexer
- internal/server: chi router with /api/chat (SSE), /api/health, /api/info,
  /api/reindex, middleware (RequestID, Logging, CORS, RateLimit)
- internal/streaming: SSE protocol helpers (start, chunk, sources, done, error)
- web/: drop-in vanilla-JS chat widget (no build, no deps) + demo + README
- bench/: reproducible driver benchmark (modernc vs mattn SQLite)
- configs/portfolio-bot.yaml: llama.cpp default provider, SQLite RAG, canine persona
- docs/architecture.md / .es.md: aligned with SQLite FTS5 + llama.cpp decisions
- data/projects/README*.md: project data documentation
- README.md / .es.md: updated for current implementation

All tests pass (go test ./...). Bot is functional end-to-end with the
configured LLM provider.
2026-07-17 00:56:06 -07:00