Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
node_modules/
models/
.env
CONFIG.env
*.env
Expand Down
4 changes: 4 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ loadEnv:

rest: true

# Captures the Scope object so resources can call scope.models.embed().
# See lib/modelCapture.js.
extensionModule: 'lib/modelCapture.js'

graphqlSchema:
files: 'schemas/*.graphql'

Expand Down
21 changes: 0 additions & 21 deletions lib/config.js

This file was deleted.

22 changes: 11 additions & 11 deletions lib/embeddings.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { init, embed as llamaEmbed } from 'harper-fabric-embeddings'
import { resolve } from 'path'
import { fileURLToPath } from 'url'

const __dirname = fileURLToPath(new URL('.', import.meta.url))
const modelPath = resolve(__dirname, '../models/bge-small-en-v1.5-q4_k_m.gguf')

// Model is pre-downloaded by the predev/prestart npm hook (scripts/download-model.js)
const initPromise = init({ modelPath })
// Thin wrapper around `scope.models.embed()` (harper#510). The host's
// configured backend (Ollama on Fabric GPU hosts, or any backend configured
// via the `models:` block in harperdb-config.yaml / env vars) handles the
// actual inference. Returns a plain Array<number> for compatibility with
// Harper's HNSW vector index storage.

export async function embed(text) {
await initPromise
return llamaEmbed(text)
const scope = globalThis.harperScope;
if (!scope) {
throw new Error('Harper scope not yet captured — modelCapture plugin must run before first embed call');
}
const [vector] = await scope.models.embed(text);
return Array.from(vector);
}
11 changes: 11 additions & 0 deletions lib/modelCapture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Plugin entry — captures the Scope object so `resources/*.js` can call
// `scope.models.embed()` against the host's configured embedding backend.
//
// Harper's `scope` is passed to plugins via `handleApplication(scope)` but
// isn't exposed as a global to Resource classes. This tiny plugin stashes the
// Scope on `globalThis.harperScope` at app boot, then `lib/embeddings.js`
// reads it from there.

export function handleApplication(scope) {
globalThis.harperScope = scope;
}
Loading