Commit graph

4 commits

Author SHA1 Message Date
Victor Hugo Vargas
7393812fba feat(agent): auto-compact long conversations in the runner
Runner.Compact folds the older portion of history into a single
system-role summary when the previous turn's input tokens cross
threshold_ratio × MaxContextWindow. When summarization fails, the
runner falls back to truncateToBudget so a flaky summarize call never
breaks the user's request.

EstimatePromptTokens / totalPromptTokens give a conservative count
(roughly 3 chars per token) used by both the compaction trigger and
BuildMessages' new limitRAGContext / fitHistory helpers to cap the
prompt inside the provider's reported window before the request goes
out. Covers the first-turn case where no usage has been reported yet.

Adds runner_compaction_test.go with table-driven coverage for the
disabled, below-threshold, short-history, unknown-window, fallback
and first-stream cases, plus a regression for the RAG-context trimmer.
2026-07-18 00:08:05 -07:00
Victor Hugo Vargas
4c5cad38f8 feat(config): add auto-compaction block and CLI wiring
Adds a configurable compaction section to portfolio-bot.yaml with
threshold_ratio, keep_recent_turns and an optional summary prompt.
Wires the new fields through config.Validate() and cmd/chat-bot/main.go
into agent.Runner.WithCompaction() so the runner can opt in to
auto-compaction at startup.
2026-07-18 00:07:41 -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