Skip to content

(MOT-4053) feat(provider-llamacpp): native embeddings surface - #513

Merged
rohitg00 merged 3 commits into
mainfrom
feat/provider-llamacpp-embed
Jul 16, 2026
Merged

(MOT-4053) feat(provider-llamacpp): native embeddings surface#513
rohitg00 merged 3 commits into
mainfrom
feat/provider-llamacpp-embed

Conversation

@rohitg00

@rohitg00 rohitg00 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Adds provider::llamacpp::embed: batch text embeddings from the configured llama-server, which exposes an OpenAI-compatible /v1/embeddings when started with --embeddings and an embedding-capable model. The endpoint derives from the configured chat api_url (sibling path), the credential is optional to match the chat path (local servers usually run without --api-key), and the one-vector-per-input contract is enforced with count and index validation. Behind router::embed's registry walk this gives the memory worker fully local semantic recall.

Live-verified on a rig: llama-server with a nomic-embed GGUF on a custom port; provider::llamacpp::embed directly and router::embed { provider: llamacpp } both returned correct 768-dim vectors, provider available in the registry. Wire schema golden committed; 67 tests green. The 3 integration tests that need an isolated engine fail identically on clean main on this host (environment) and are untouched.

Fixes MOT-4053

Summary by CodeRabbit

  • New Features

    • Added local batch text embeddings through the configured llama-server.
    • Supports one embedding vector per input while preserving input order.
    • Enables local semantic memory recall through the router without cloud calls.
    • Requires llama-server embeddings support and an embedding-capable GGUF model.
  • Documentation

    • Documented embeddings setup, behavior, and requirements.
  • Security

    • Restricted direct embedding calls so they can only be invoked through the router.

provider::llamacpp::embed serves batch embeddings from the configured
llama-server (--embeddings plus an embedding-capable model), deriving
the sibling /v1/embeddings from the chat api_url so nonstandard ports
and path prefixes keep working. Credential only when the server runs
with --api-key, matching the chat path. One-vector-per-input enforced
(count and index contract); upstream errors name the --embeddings
requirement. Registered internal like the other provider functions and
denied to agents; router::embed discovers it via the registry walk.

Live-verified: llama-server with a nomic-embed GGUF on a custom port,
direct provider call and router::embed provider=llamacpp both return
correct 768-dim vectors.
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview, Comment Jul 16, 2026 3:02pm
workers-tech-spec Ready Ready Preview, Comment Jul 16, 2026 3:02pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 44 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@rohitg00, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 12 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 537a4372-91b5-4bde-8f3d-f132edbf1aa7

📥 Commits

Reviewing files that changed from the base of the PR and between 90bc833 and c871ad0.

📒 Files selected for processing (3)
  • provider-llamacpp/src/embed.rs
  • provider-llamacpp/src/register.rs
  • provider-llamacpp/tests/golden/schemas/provider.llamacpp.embed.json
📝 Walkthrough

Walkthrough

Adds provider::llamacpp::embed for batch text embeddings through llama-server, including request validation, indexed response ordering, provider registration, internal permissions, catalog coverage, tests, and documentation.

Changes

Llama.cpp embeddings provider

Layer / File(s) Summary
Embedding contract and catalog
provider-llamacpp/src/embed.rs, provider-llamacpp/src/surface.rs, provider-llamacpp/src/lib.rs
Adds embedding request/response types, exports the module, and includes the function in the provider catalog.
Embedding request handling
provider-llamacpp/src/embed.rs
Derives the llama-server embeddings URL, resolves configuration and authentication, validates inputs and indexed responses, and returns embeddings in input order.
Provider registration and access
provider-llamacpp/src/register.rs, provider-llamacpp/iii-permissions.yaml, provider-llamacpp/tests/schemas.rs, provider-llamacpp/README.md
Registers the internal handler, blocks direct agent access, updates catalog-order tests, and documents local embeddings behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RouterEmbed as router::embed
  participant LlamaCppEmbed as provider::llamacpp::embed
  participant LlamaServer as llama-server
  RouterEmbed->>LlamaCppEmbed: Submit batch text
  LlamaCppEmbed->>LlamaCppEmbed: Resolve config and validate inputs
  LlamaCppEmbed->>LlamaServer: POST /v1/embeddings
  LlamaServer-->>LlamaCppEmbed: Return indexed vectors
  LlamaCppEmbed-->>RouterEmbed: Return vectors in input order
Loading

Possibly related PRs

Suggested reviewers: andersonleal

Poem

I’m a rabbit with vectors, hopping in line,
Each text finds a number, neatly aligned.
Through llama-server’s gate they flow,
In input order, back they go.
No cloud call—just local glow!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a native embeddings surface to provider-llamacpp.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/provider-llamacpp-embed

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
provider-llamacpp/src/embed.rs (2)

112-115: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Conditionally append the configuration hint based on status.

Unconditionally appending the hint (llama-server needs --embeddings and an embedding-capable model) to all non-success HTTP responses might mislead users when debugging unrelated issues, such as authentication errors (401/403) or payload size limits (413).

Consider appending this helpful hint only when the upstream server returns a 404 Not Found or 501 Not Implemented.

🛠️ Proposed fix
-        return Err(Error::Handler(format!(
-            "provider/upstream_status: {status}: {excerpt} \
-             (llama-server needs --embeddings and an embedding-capable model)"
-        )));
+        let hint = if status == reqwest::StatusCode::NOT_FOUND || status == reqwest::StatusCode::NOT_IMPLEMENTED {
+            " (llama-server needs --embeddings and an embedding-capable model)"
+        } else {
+            ""
+        };
+        return Err(Error::Handler(format!(
+            "provider/upstream_status: {status}: {excerpt}{hint}"
+        )));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@provider-llamacpp/src/embed.rs` around lines 112 - 115, Update the upstream
error construction in the embedding request handler so the llama-server
configuration hint is appended only for HTTP 404 Not Found or 501 Not
Implemented responses. Keep other non-success statuses, including authentication
and payload errors, limited to their status and response excerpt.

94-97: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid allocating a JSON AST for large arrays.

Using serde_json::json! moves req.input into an intermediate JSON AST representation (Vec<Value>). For large inputs (up to 512 texts), this introduces unnecessary allocations and performance overhead.

Consider defining an inline serializable struct to stream the data directly to the request body.

⚡ Proposed fix using a dedicated struct
+    #[derive(Serialize)]
+    struct UpstreamRequest {
+        model: String,
+        input: Vec<String>,
+    }
+
     let mut request = http
         .post(embed_url(&cfg.api_url))
         .timeout(std::time::Duration::from_secs(EMBED_TIMEOUT_SECS))
-        .json(&serde_json::json!({ "model": model, "input": req.input }));
+        .json(&UpstreamRequest {
+            model,
+            input: req.input,
+        });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@provider-llamacpp/src/embed.rs` around lines 94 - 97, Replace the
serde_json::json! payload in the request construction with a small inline
serializable struct containing model and input fields, so req.input is
serialized directly without building an intermediate Vec<Value>. Preserve the
existing embed_url, timeout, and request payload field names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@provider-llamacpp/src/embed.rs`:
- Around line 112-115: Update the upstream error construction in the embedding
request handler so the llama-server configuration hint is appended only for HTTP
404 Not Found or 501 Not Implemented responses. Keep other non-success statuses,
including authentication and payload errors, limited to their status and
response excerpt.
- Around line 94-97: Replace the serde_json::json! payload in the request
construction with a small inline serializable struct containing model and input
fields, so req.input is serialized directly without building an intermediate
Vec<Value>. Preserve the existing embed_url, timeout, and request payload field
names.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bc72d348-3ce2-4985-a617-384e72cfc6bf

📥 Commits

Reviewing files that changed from the base of the PR and between fb6a6d6 and 90bc833.

⛔ Files ignored due to path filters (1)
  • provider-llamacpp/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • provider-llamacpp/README.md
  • provider-llamacpp/iii-permissions.yaml
  • provider-llamacpp/src/embed.rs
  • provider-llamacpp/src/lib.rs
  • provider-llamacpp/src/register.rs
  • provider-llamacpp/src/surface.rs
  • provider-llamacpp/tests/schemas.rs

Embed was registered before on_router_ready while the catalog listed
it last, breaking the registration-order lockstep the schema test
documents (nothing asserted the actual order, so CI stayed green).
The registration now matches the catalog. The published request schema
also gains the 1..=512 input bounds the handler already enforces.
@rohitg00

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@rohitg00
rohitg00 merged commit 26f26d1 into main Jul 16, 2026
14 checks passed
@rohitg00
rohitg00 deleted the feat/provider-llamacpp-embed branch July 16, 2026 15:18
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