Export persona.DiscoverAgentsMD and add agent.Config.AgentsMD so project
and global AGENTS.md rules actually reach the model. Previously
buildInitialMessages always called AssembleSystemPrompt with an empty
string, so no AGENTS.md content was ever injected despite the discovery
logic already existing.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- agent/loop.go: Record assistant message with ToolCalls before tool results,
and set ToolCallID on tool-result messages so follow-up requests have complete
context (prevents models from losing track of already-attempted tools).
- llm/providers/llamacpp/client.go: Buffer fragmented tool call deltas during
streaming, assemble them into complete calls when finish_reason arrives.
Add ToolCalls, ToolCallID, Name fields to request building.
- llm/providers/openai/client.go: Send ToolCalls, ToolCallID, Name when
building chat requests so messages are wire-format correct.
- llm/types.go: Add ToolCalls field to Message struct for serialization
back into conversation history.
- agent/integration_test.go: Move integration test skip from TestMain to a
per-test skipUnlessIntegration() so it doesn't hide other package tests.
- sandbox & tools: Add edge-case tests (relative traversal, array paths,
non-path strings, zero-value guards, sentinel errors).
Backend.Upsert never received the fragment's Content, so ChromaDB (and
any backend) stored the vector but silently dropped the actual text —
saved memories had nothing to retrieve later. Backend.Search now also
takes the raw query text, and a failed/missing embedding no longer
hard-fails Add/Search: it degrades to a nil vector so a lexical-capable
backend can still index/find the content (Chroma has no such fallback
and now says so explicitly instead of misbehaving).
Adds pkg/rag/backends/sqlitevec: a zero-dependency backend (pure-Go
SQLite, no external service) that does cosine similarity when a real
embedding vector is available and falls back to FTS5/BM25 full-text
search otherwise. Adds pkg/rag/embeddings.OpenAICompatible, covering
both a local llama.cpp server (`--embeddings` enabled) and real OpenAI
(or any OpenAI-shaped /embeddings endpoint) through the same client.
Also fixes token usage tracking for llama.cpp streaming: the client
never requested `stream_options.include_usage` nor parsed a usage-only
SSE event, and even when present, the agent loop's RunStream dropped
any chunk with no Delta/ReasoningDelta — silently discarding the only
chunk that carries usage.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>