@qvac/harness
v0.2.8
Published
An AI harness implementing generate(context) via @qvac/sdk. Knows nothing about workbench, hyperdb, or chunks — just inference in, events out.
Readme
@qvac/harness
The QV.AC inference engine: generate(context) over the QVAC SDK — completions,
embeddings, transcription, image and music generation — plus the tool runtime
skills execute in (Python via Pyodide, web search/fetch, MCP, filesystem). It
knows nothing about the app, hyperdb or sync: inference in, events out.
It runs as a supervised child process (or Bare thread on mobile) that a host spawns and talks to over hrpc — crash isolation for free, death is the exit itself. See bare-supervisor for the supervision contract.
The published package
The published package ships the prebuilt engine and its runtime content, not the library source:
dist/harness.bundle— the stowed sidecar (all platforms in one bundle)dist/prebuilds-manifest.json— every native prebuild dir the bundle defers, keyed by bundle-relative path; the host assembles those beside the bundle from its ownnode_modules- the hash-pinned Python
wheels/the tool runtime consumes (skills come from@qvac/skills, a content-addressed bundle this package materializes at runtime)
The @qvac inference addons and pyodide resolve from the host's real
node_modules at runtime (dlopen'd backends need real paths), so the host
installs those alongside.
The host-side library surface — spawnHarness/harnessChild, the transport,
model catalogs, skill helpers and DOCX extractor — ships as compiled JavaScript
and declarations in dist-lib/. The package exports resolve to that surface;
the TypeScript source stays in the repository.
Spawning
The generated dist/harness.cjs is the host entry: it spawns the bundle as a
bare-sidecar process and hands back the stow ipc plus the exit promise.
const harness = require('@qvac/harness/dist/harness.cjs')
const { ipc, sidecar, exit } = await harness.start(args)The argv slots the bundle reads (skills dir, sdk storage, model config, wheels
dir, ...) are the ones worker/harness-sidecar.mjs documents in this repo. The
in-house hosts don't call this directly — they use the repo's library surface
(harnessChild under bare-supervisor), which owns that argv contract.
DOCX extraction
Hosts can supply the bundled Python extractor to their document pipeline:
Set QVAC_PYODIDE_CACHE_DIR to a writable directory before calling the API,
including from source and compiled-package consumers. The worker seeds this
cache from shipped wheels; without it, Pyodide can try downloading packages.
import { extractDocxText, closeDocxWorker } from '@qvac/harness/docx'
const text = await extractDocxText(bytes, 'notes.docx', { signal })
// At host shutdown, after outstanding extractions have settled:
await closeDocxWorker()The extractor preserves paragraph and table order, accepts up to 20 MiB, and
requires the shipped Python wheels. With the cache configured, extraction uses
those wheels offline. Bundled hosts also set QVAC_PYODIDE_WORKER_ENTRY and
QVAC_PYTHON_WHEELS_DIR to their staged worker and wheels paths.
Source checkouts prepare wheels with bun run vendor:wheels.
Development
bun install
bun run lint # prettier + lunte + tsc
bun run test # brittle, node and bare lanes
bun run build:schema # regenerates spec/ (wire-compat rewind once v* tags exist)
bun run build:bundle # stows dist/harness.bundle (--minify for the shipped form)The schema baseline rewinds spec/ against this repo's v* release tags and
skips loudly while none exist. Dependency overrides pin the resolutions the
engine is validated against — keep them aligned with direct specs, npm refuses
a mismatch on publish.
License
See LICENSE.
