Skip to content

Comments

feat(cli): add local embeddings setup to floop init#130

Merged
nvandessel merged 2 commits intofeature/yzma-integrationfrom
feature/yzma-phase-5-cli
Feb 20, 2026
Merged

feat(cli): add local embeddings setup to floop init#130
nvandessel merged 2 commits intofeature/yzma-integrationfrom
feature/yzma-phase-5-cli

Conversation

@nvandessel
Copy link
Owner

Summary

  • Add --embeddings / --no-embeddings flags to floop init for downloading and enabling local embedding dependencies
  • Create internal/setup/ package with DetectInstalled(), DownloadLibraries(), and DownloadEmbeddingModel() using yzma download APIs
  • Add auto-detection of installed embedding deps in ~/.floop/ on MCP server startup (no explicit config needed after first setup)
  • Interactive prompt in floop init for embeddings setup with skip-if-already-installed detection

Test plan

  • internal/setup/ unit tests: DetectInstalled with various file layouts, DefaultFloopDir, libraryFileName
  • Full test suite passes (go test ./... — 31 packages)
  • Build passes (go build ./...)

🤖 Generated with Claude Code

Adds embedding setup flow to `floop init`:
- Interactive prompt to download llama.cpp libs + nomic-embed-text model
- `--embeddings` / `--no-embeddings` flags for non-interactive use
- Auto-detects installed dependencies in ~/.floop/ on server startup
- Creates internal/setup package with DetectInstalled, DownloadLibraries,
  and DownloadEmbeddingModel functions
- Updates config.yaml with local provider settings after download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link

greptile-apps bot commented Feb 19, 2026

Greptile Summary

Adds local embedding setup to floop init with auto-detection and download capabilities. Creates new internal/setup/ package with detection for llama.cpp libraries and GGUF models in ~/.floop/. Interactive mode prompts users to enable embeddings with skip-if-installed logic. MCP server now auto-detects installed embeddings at startup as a fallback when no explicit config exists.

Key changes:

  • New --embeddings / --no-embeddings flags for CLI control
  • setup.DetectInstalled() checks ~/.floop/lib/ for platform-specific libllama and ~/.floop/models/ for .gguf files
  • setup.DownloadLibraries() and setup.DownloadEmbeddingModel() use yzma download APIs
  • MCP server fallback: explicit config → auto-detect ~/.floop/ → no embeddings
  • Config update writes LLM.Provider=local to ~/.floop/config.yaml after successful download

Issues found:

  • Embedding setup errors silently ignored when --embeddings explicitly provided (line 108-118 in cmd_init.go)
  • Custom string search implementation instead of strings.Contains() in tests

Confidence Score: 4/5

  • Safe to merge with one logic issue to address regarding error handling
  • Well-tested implementation with comprehensive unit tests and clear separation of concerns. The auto-detection fallback is well-designed. Main concern is that explicit --embeddings flag failures are downgraded to warnings rather than errors, which could confuse users who explicitly requested the feature. Dependencies add significant size but are already used by yzma.
  • Review error handling in cmd/floop/cmd_init.go:108-118 to fail fast when --embeddings is explicitly provided

Important Files Changed

Filename Overview
internal/setup/embeddings.go New package for embedding setup - well-structured with clear separation of concerns for detection and download
cmd/floop/cmd_init.go Adds embeddings flags and interactive prompts, with minor issue in error-swallowing logic
internal/mcp/server.go Clean auto-detection fallback for embeddings - follows explicit config > auto-detect priority pattern
go.mod Large dependency footprint from hashicorp/go-getter (AWS, GCS, S3) for downloads

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[floop init] --> B{Interactive or Flags?}
    B -->|Interactive| C[runInteractiveInit]
    B -->|Flags| D[Parse flags]
    
    C --> E{Embeddings installed?}
    E -->|Yes| F[Skip embeddings prompt]
    E -->|No| G[Prompt user for embeddings]
    
    D --> H{--embeddings flag?}
    H -->|Yes| I[doEmbeddings = true]
    H -->|No| J[doEmbeddings = false]
    
    F --> K[Return doEmbeddings=false]
    G --> L{User choice}
    L -->|Yes| M[Return doEmbeddings=true]
    L -->|No| K
    
    I --> N[setupEmbeddings]
    M --> N
    
    N --> O{Already installed?}
    O -->|Yes| P[Return already_installed]
    O -->|No| Q[DownloadLibraries]
    
    Q --> R[DownloadEmbeddingModel]
    R --> S[Update config.yaml]
    S --> T[Set LLM.Provider=local]
    
    T --> U[MCP Server Startup]
    U --> V{Config has LLM.Provider=local?}
    V -->|Yes| W[Use config paths]
    V -->|No| X[DetectInstalled ~/.floop/]
    
    X --> Y{Libs + Model found?}
    Y -->|Yes| Z[Auto-enable embedder]
    Y -->|No| AA[Continue without embeddings]
    
    W --> Z
    Z --> AB[Embedder available for semantic search]
Loading

Last reviewed commit: 2c9f74d

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

- Fail with error when --embeddings is explicitly passed and setup fails
  (previously silently continued with success status)
- Include embeddings_error in JSON output for interactive mode failures
- Replace custom contains() with strings.Contains() in tests

Addresses review feedback from Greptile on PR #130.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nvandessel nvandessel merged commit c4a44e5 into feature/yzma-integration Feb 20, 2026
@nvandessel nvandessel deleted the feature/yzma-phase-5-cli branch February 20, 2026 02:56
nvandessel added a commit that referenced this pull request Feb 20, 2026
* feat(cli): add local embeddings setup to floop init

Adds embedding setup flow to `floop init`:
- Interactive prompt to download llama.cpp libs + nomic-embed-text model
- `--embeddings` / `--no-embeddings` flags for non-interactive use
- Auto-detects installed dependencies in ~/.floop/ on server startup
- Creates internal/setup package with DetectInstalled, DownloadLibraries,
  and DownloadEmbeddingModel functions
- Updates config.yaml with local provider settings after download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): improve embedding setup error handling and use stdlib

- Fail with error when --embeddings is explicitly passed and setup fails
  (previously silently continued with success status)
- Include embeddings_error in JSON output for interactive mode failures
- Replace custom contains() with strings.Contains() in tests

Addresses review feedback from Greptile on PR #130.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
nvandessel added a commit that referenced this pull request Feb 20, 2026
* feat(cli): add local embeddings setup to floop init

Adds embedding setup flow to `floop init`:
- Interactive prompt to download llama.cpp libs + nomic-embed-text model
- `--embeddings` / `--no-embeddings` flags for non-interactive use
- Auto-detects installed dependencies in ~/.floop/ on server startup
- Creates internal/setup package with DetectInstalled, DownloadLibraries,
  and DownloadEmbeddingModel functions
- Updates config.yaml with local provider settings after download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): improve embedding setup error handling and use stdlib

- Fail with error when --embeddings is explicitly passed and setup fails
  (previously silently continued with success status)
- Include embeddings_error in JSON output for interactive mode failures
- Replace custom contains() with strings.Contains() in tests

Addresses review feedback from Greptile on PR #130.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
nvandessel added a commit that referenced this pull request Feb 20, 2026
* feat: implement local LLM client with yzma (purego)

Replace llama-go CGo bindings with hybridgroup/yzma, which uses purego
to load llama.cpp shared libraries at runtime. No CGo, no build tags,
no C++ compiler needed — go build always works.

- Single local.go file (no stub), package-level sync.Once for lib init
- Per-call context creation in Embed() for simplicity
- Available() checks lib dir + model file via os.Stat
- Integration tests gated on FLOOP_TEST_LIB_PATH + FLOOP_TEST_MODEL_PATH

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address review feedback on yzma local client

- Increase token context padding from +16 to +64 for special tokens
- Check llama.Decode() error return instead of ignoring it
- Reset model/vocab/nEmbd handles and sync.Once in Close() so
  post-close usage fails cleanly or reloads safely

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve lint errors in local LLM client

- Fix gofmt alignment in LocalClient struct fields
- Check llama.Free and llama.ModelFree error returns (errcheck)
- Suppress gosec G115 for safe int->int32/uint32 conversions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: replace nolint comments with proper bounds checks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve gosec G115 lint errors

- Change GPULayers field type to int32 (matches llama API)
- Exclude gosec G115 (integer overflow) — no dataflow analysis,
  false positives on bounded values like len()
- Remove unnecessary math import and bounds check wrappers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use MergeCandidate threshold in integration test

The IntentMatch threshold (>0.8) is too strict for small embedding
models like all-MiniLM-L6-v2. Use MergeCandidate (>0.7) which is
the actionable threshold for dedup and works across model sizes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restore similarity.go removed in code quality audit

The cherry-picked yzma commits depend on CosineSimilarity and normalize
functions that were in similarity.go before the deep code quality audit
(d5bb413) removed the file. Restore it for the local LLM client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(store): add embedding vector persistence via schema V3→V4 migration (#123)

Add EmbeddingStore interface and schema V4 migration for vector retrieval
support (yzma Phase 1). This enables storing embedding vectors alongside
behaviors for future semantic search.

Changes:
- Add BehaviorEmbedding struct and EmbeddingStore interface to store.go
- Schema V3→V4 migration: add embedding BLOB and embedding_model TEXT
  columns to behaviors table
- Implement StoreEmbedding, GetAllEmbeddings, GetBehaviorIDsWithoutEmbeddings
  on SQLiteGraphStore with binary encode/decode (little-endian float32)
- Add EmbeddingStore support to InMemoryGraphStore for testing
- Add EmbeddingStore delegation to MultiGraphStore (local/global merge)
- Add tests: migration, encode/decode round-trip, CRUD, NULL handling

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add brute-force vector search and context composition (#126)

* feat(store): add embedding vector persistence via schema V3→V4 migration

Add EmbeddingStore interface and schema V4 migration for vector retrieval
support (yzma Phase 1). This enables storing embedding vectors alongside
behaviors for future semantic search.

Changes:
- Add BehaviorEmbedding struct and EmbeddingStore interface to store.go
- Schema V3→V4 migration: add embedding BLOB and embedding_model TEXT
  columns to behaviors table
- Implement StoreEmbedding, GetAllEmbeddings, GetBehaviorIDsWithoutEmbeddings
  on SQLiteGraphStore with binary encode/decode (little-endian float32)
- Add EmbeddingStore support to InMemoryGraphStore for testing
- Add EmbeddingStore delegation to MultiGraphStore (local/global merge)
- Add tests: migration, encode/decode round-trip, CRUD, NULL handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add brute-force vector search and context query composition

Implements Phase 2 of the yzma vector retrieval feature with an isolated,
well-tested vectorsearch package:

- BruteForceSearch: finds topK most similar behaviors by cosine similarity
- cosineSimilarity: local copy to avoid import cycle with internal/llm
- ComposeContextQuery: builds embeddable text from ContextSnapshot fields

All edge cases covered: empty/nil inputs, topK clamping, ordering, and
ProjectTypeUnknown exclusion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add embedder service (#125)

* feat(store): add embedding vector persistence via schema V3→V4 migration

Add EmbeddingStore interface and schema V4 migration for vector retrieval
support (yzma Phase 1). This enables storing embedding vectors alongside
behaviors for future semantic search.

Changes:
- Add BehaviorEmbedding struct and EmbeddingStore interface to store.go
- Schema V3→V4 migration: add embedding BLOB and embedding_model TEXT
  columns to behaviors table
- Implement StoreEmbedding, GetAllEmbeddings, GetBehaviorIDsWithoutEmbeddings
  on SQLiteGraphStore with binary encode/decode (little-endian float32)
- Add EmbeddingStore support to InMemoryGraphStore for testing
- Add EmbeddingStore delegation to MultiGraphStore (local/global merge)
- Add tests: migration, encode/decode round-trip, CRUD, NULL handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add brute-force vector search and context query composition

Implements Phase 2 of the yzma vector retrieval feature with an isolated,
well-tested vectorsearch package:

- BruteForceSearch: finds topK most similar behaviors by cosine similarity
- cosineSimilarity: local copy to avoid import cycle with internal/llm
- ComposeContextQuery: builds embeddable text from ContextSnapshot fields

All edge cases covered: empty/nil inputs, topK clamping, ordering, and
ProjectTypeUnknown exclusion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add embedder service bridging LLM embeddings and store

Implements the Embedder type that orchestrates embedding generation and
persistence. Handles nomic-embed-text task prefixes (search_document for
behaviors, search_query for retrieval), provides BackfillMissing for
batch embedding of existing behaviors, and extractCanonical helper for
behavior content extraction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): wire vector embedding retrieval into pipeline (#127)

* feat(store): add embedding vector persistence via schema V3→V4 migration

Add EmbeddingStore interface and schema V4 migration for vector retrieval
support (yzma Phase 1). This enables storing embedding vectors alongside
behaviors for future semantic search.

Changes:
- Add BehaviorEmbedding struct and EmbeddingStore interface to store.go
- Schema V3→V4 migration: add embedding BLOB and embedding_model TEXT
  columns to behaviors table
- Implement StoreEmbedding, GetAllEmbeddings, GetBehaviorIDsWithoutEmbeddings
  on SQLiteGraphStore with binary encode/decode (little-endian float32)
- Add EmbeddingStore support to InMemoryGraphStore for testing
- Add EmbeddingStore delegation to MultiGraphStore (local/global merge)
- Add tests: migration, encode/decode round-trip, CRUD, NULL handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add brute-force vector search and context query composition

Implements Phase 2 of the yzma vector retrieval feature with an isolated,
well-tested vectorsearch package:

- BruteForceSearch: finds topK most similar behaviors by cosine similarity
- cosineSimilarity: local copy to avoid import cycle with internal/llm
- ComposeContextQuery: builds embeddable text from ContextSnapshot fields

All edge cases covered: empty/nil inputs, topK clamping, ordering, and
ProjectTypeUnknown exclusion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(vectorsearch): add embedder service bridging LLM embeddings and store

Implements the Embedder type that orchestrates embedding generation and
persistence. Handles nomic-embed-text task prefixes (search_document for
behaviors, search_query for retrieval), provides BackfillMissing for
batch embedding of existing behaviors, and extractCanonical helper for
behavior content extraction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): wire vector embedding retrieval into floop_active and floop_learn

Adds vector pre-filtering to handleFloopActive: when a local embedder is
available, behaviors are retrieved by semantic similarity to the current
context before entering the existing activation/spreading pipeline. Falls
back to full table scan when embedder is unavailable or vector search
returns no results.

Also embeds newly learned behaviors in the background after floop_learn,
and schedules a background backfill of unembedded behaviors on server
startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cli): add local embeddings setup to floop init (#130)

* feat(cli): add local embeddings setup to floop init

Adds embedding setup flow to `floop init`:
- Interactive prompt to download llama.cpp libs + nomic-embed-text model
- `--embeddings` / `--no-embeddings` flags for non-interactive use
- Auto-detects installed dependencies in ~/.floop/ on server startup
- Creates internal/setup package with DetectInstalled, DownloadLibraries,
  and DownloadEmbeddingModel functions
- Updates config.yaml with local provider settings after download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): improve embedding setup error handling and use stdlib

- Fail with error when --embeddings is explicitly passed and setup fails
  (previously silently continued with success status)
- Include embeddings_error in JSON output for interactive mode failures
- Replace custom contains() with strings.Contains() in tests

Addresses review feedback from Greptile on PR #130.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add local embeddings documentation (#131)

* docs: add local embeddings documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(docs): correct embedding dimension from 384 to 768

nomic-embed-text-v1.5 produces 768-dimensional embeddings.
The model spec was already correct but storage/performance
calculations incorrectly used 384. Fixes all 4 instances
across EMBEDDINGS.md and SCIENCE.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: extract vecmath package, fix vector fallback logic

Deduplicate CosineSimilarity/Normalize into internal/vecmath so both
llm and vectorsearch import from a single source. Fix handleFloopActive
to distinguish "vector retrieval succeeded with empty results" from
"not attempted / failed" by checking nodes == nil instead of len == 0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve golangci-lint issues (gofmt, unused type)

Fix trailing newline in search.go, struct field alignment in
embedder_test.go, and remove unused testNodeGetter interface.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: bump embedding migration to V5→V6, address review feedback

Renumber embedding migration from V4→V5 to V5→V6 since main's V4→V5
now holds the co_activations table (PR #137). Also fix int32 bounds
check for GPU layers config (clamp negative values to 0) and correct
schema comment from V4 to V6.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use ParseInt with bitSize 32 to satisfy CodeQL narrowing check

strconv.ParseInt(v, 10, 32) guarantees the value fits in int32,
eliminating the CodeQL integer-narrowing warning on the Atoi→int32 cast.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant