New: VisionPsy-Nano, a 460M vision model that outperforms models twice its size.
QVAC Logo

Configuration

Use qvac.config.* to configure QVAC's overall behavior.

Overview

QVAC configuration is loaded once during initialization and remains immutable for the lifetime of the SDK instance. The schema and options below are shared across clients; how the config reaches the worker is client-specific — see JS/TS SDK — Configuration and Python SDK — Configuration.

Providing a configuration is optional; when omitted, the SDK uses the default settings.

Example

Values marked with <placeholders> should be replaced with your actual values.

Configuration schema
{
  "plugins": ["<builtin_plugin_1>", "<custom_plugin_2>"],
  "loggerConsoleOutput": true,
  "loggerLevel": "info",
  "swarmRelays": ["<hyperbee_key_1>", "<hyperbee_key_2>"],
  "cacheDirectory": "</absolute/path/to/.qvac/models>",
  "httpDownloadConcurrency": 3,
  "httpConnectionTimeoutMs": 10000,
  "requireHttpChecksum": false,
  "requireSecureTransport": false,
  "registryDownloadMaxRetries": 3,
  "registryStreamTimeoutMs": 60000,
  "rpcInitTimeoutMs": 30000,
  "deviceDefaults": [
    {
      "name": "Samsung Galaxy force CPU",
      "match": { "platform": "android", "deviceBrand": "samsung" },
      "defaults": { "llm": { "device": "cpu" } }
    }
  ],
  "bareRuntimeVersion": "<x.y.z>",
  "serve": {
    "cors": {
      "origins": ["https://app.example.com"]
    },
    "models": {
      "<model_alias>": {
        "model": "<SDK_MODEL_CONSTANT>",
        "default": true,
        "preload": true,
        "config": {}
      }
    }
  }
}

Options

The following table lists all supported configuration options for qvac.config.*:

OptionDescriptionTypeRequiredDefault
pluginsPlugin specifiers to bundle (built-in and/or custom).string[]NoAll built-in plugins
loggerConsoleOutputEnable or disable console output for SDK loggers.booleanNotrue
loggerLevelGlobal log level for all SDK loggers."error" | "warn" | "info" | "debug"No"info"
swarmRelaysHyperswarm relay public keys (hex strings) for improved P2P connectivity (blind relays).string[]No
cacheDirectoryAbsolute path to the directory where models and other cached assets are stored.stringNo~/.qvac/models
httpDownloadConcurrencyMaximum number of concurrent HTTP downloads for sharded models.numberNo3
httpConnectionTimeoutMsTimeout in milliseconds for HTTP connection establishment (applies to HEAD and GET requests).numberNo10000
requireHttpChecksumReject a Hugging Face download that exposes no usable SHA-256 (instead of downloading it unverified). Hugging Face downloads are always verified when a hash is available regardless of this flag.booleanNofalse
requireSecureTransportReject plaintext http:// and HTTPS→HTTP downgrade redirects for every HTTP source (loopback exempt). When off, this is enforced only for Hugging Face sources; bring-your-own HTTP is left as-is.booleanNofalse
registryDownloadMaxRetriesMaximum retry attempts for registry (P2P) downloads on timeout.numberNo3
registryStreamTimeoutMsTimeout in milliseconds for stalled registry (P2P) download streams. Raise on slow or high-latency connections where the default triggers spurious retries.numberNo60000
rpcInitTimeoutMsTimeout in milliseconds for the worker RPC handshake performed when the SDK initializes. Raise on slow storage or embedded hardware where the first worker start legitimately exceeds the default. Overridden by the QVAC_RPC_INIT_TIMEOUT_MS environment variable.numberNo30000
deviceDefaultsOverride loaded model config for specific devices. First matching pattern wins. Use it to optimize for different hardware.DevicePattern[]No
bareRuntimeVersionBare runtime version used for native addon ABI verification during bundling (qvac bundle sdk / qvac verify bundle). When omitted, the bundler auto-detects it from node_modules (bare-runtime, then bare).stringNoAuto-detected
serveConfiguration for the HTTP server.ServeConfigNo

DevicePattern

FieldDescriptionTypeRequired
nameHuman-readable label for this pattern (used in logs).stringYes
matchWhich device(s) to target. All specified fields must match.DeviceMatchYes
defaultsModel config overrides to apply when matched.DeviceConfigDefaultsYes

DeviceMatch

FieldDescriptionTypeRequired
platformTarget platform."android" | "ios"Yes
deviceBrandCase-insensitive exact brand (e.g., "samsung", "google").stringNo
deviceModelPrefixCase-sensitive prefix match on the device model (e.g., "Pixel 10" matches "Pixel 10 Pro").stringNo
deviceModelContainsSubstring match on the device model (e.g., "Galaxy" matches "Samsung Galaxy S25").stringNo

DeviceConfigDefaults

Maps each model-type key to a model config object. For example (inside DevicePattern.defaults):

{
  "llm": { "device": "cpu", "ctx_size": 1024 },
  "embeddings": { "device": "cpu", "flashAttention": "off" }
}

Model types (allowed keys): llm | embeddings | whisper | parakeet | bci | nmt | tts | ocr

Important: for the exact config fields supported by each model type (key), see modelConfigloadModel() at @qvac/sdk API reference.

ServeConfig

FieldDescriptionTypeRequiredDefault
modelsMap of model aliases to model entries (see ModelEntry below). Required when running the server.Record<string, string | ModelEntry>Yes
publicBaseUrlExternally reachable origin (e.g., "https://api.example.com"). Required for image response_format=url. Must start with http:// or https://. The CLI flag --public-base-url overrides this value.stringNo
corsBrowser origins trusted to make cross-origin requests. See CorsOptions.CorsOptionsNo
openaiOptions for the openai extension, mounted with qvac serve --openai. See OpenAIOptions.OpenAIOptionsNo

CorsOptions

FieldDescriptionTypeRequiredDefault
originsExact HTTP(S) origins allowed by CORS, such as "https://app.example.com". Values cannot include credentials, a path, query, or fragment. Wildcard ("*") is not allowed. CLI --cors-origin values are added to this list.string[]No[]

Configure every browser origin explicitly:

{
  "serve": {
    "cors": {
      "origins": [
        "https://app.example.com",
        "http://localhost:3000"
      ]
    }
  }
}

Configuring one or more origins enables CORS. --docs also enables CORS for same-port localhost, 127.0.0.1, and [::1], plus the bound host when it is itself loopback. The legacy --cors flag is a compatibility validation switch: it does not enable CORS by itself and fails unless --cors-origin or serve.cors.origins supplies at least one explicit origin. --cors --docs still needs an explicit origin because the docs defaults do not satisfy that validation.

ModelEntry

The serve.models field is a map of model aliases to model entries. Keys are the model aliases — the names that HTTP clients use in the model field of their requests. Values can be either a string (SDK model constant name, e.g., "QWEN3_600M_INST_Q4") or a ModelEntry object:

Tip: you can generate or extend serve.models interactively with qvac configure instead of writing entries by hand.

FieldDescriptionTypeRequired
modelSDK model constant name.stringYes (unless using src + type)
srcExplicit model source (URL or path).stringYes (if no model)
typeModel type: llm | embeddings | whisper | parakeet | nmt | tts | ocr | whispercpp-audio-translation | diffusion.stringYes (if using src)
defaultUse as the default model for its endpoint category.booleanNo (false)
preloadLoad the model at server startup. When false, it loads lazily on the first request that names it (cold start).booleanNo (true for constant entries, false for explicit)
configModel config overrides (same as modelConfig in loadModel()).objectNo

Example:

{
  "serve": {
    "models": {
      "my-llm": {
        "model": "QWEN3_600M_INST_Q4",
        "default": true,
        "preload": true,
        "config": { "ctx_size": 8192 }
      },
      "my-embed": "GTE_LARGE_FP16"
    }
  }
}

LoadOptions (serve.load)

Controls how models are loaded on demand. Each field has a matching CLI flag on qvac serve.

FieldDescriptionTypeRequiredDefault
lazyWhen false, requests never trigger a load; an unloaded model returns 503 model_not_loaded. Only preloaded models serve. CLI: --no-lazy-load.booleanNotrue
concurrencyMax simultaneous loads across different aliases. 1 mirrors startup preload and bounds memory under lazy request-time loads. CLI: --load-concurrency.numberNo1
timeoutMsPer-load deadline in ms; on expiry the load is cancelled and the request gets 503 model_load_timeout. null = unbounded. CLI: --load-timeout.number | nullNonull
cancelOnDisconnectWhen true, a client disconnecting mid-load cancels the load — but only once no other request is still waiting on that same load. CLI: --no-cancel-load-on-disconnect.booleanNotrue

OpenAIOptions

Optional OpenAI-adapter settings. Currently only audio.speech is configurable:

FieldDescriptionTypeRequiredDefault
audio.speech.defaultVoiceVoice id used by /v1/audio/speech when the request omits voice. Set to null to make voice strictly required (otherwise the route returns 400 missing_voice).string | nullNo"alloy"
audio.speech.voicesMap from OpenAI voice strings to serve.models aliases (case-insensitive keys). Lets clients keep using OpenAI voice names while the server routes them to QVAC TTS aliases. See HTTP server — POST /v1/audio/speech.Record<string, string>No
audio.speech.maxInputCharsHard cap on the input length (characters) accepted by /v1/audio/speech. Set to null to disable. Matches OpenAI's documented limit and bounds memory usage since the route buffers the full WAV before responding.number | nullNo4096

Example:

{
  "serve": {
    "publicBaseUrl": "https://api.example.com",
    "openai": {
      "audio": {
        "speech": {
          "defaultVoice": "alloy",
          "voices": {
            "alloy": "tts-chatter-alloy",
            "echo": "tts-chatter-echo"
          },
          "maxInputChars": 4096
        }
      }
    }
  }
}

On this page

Ask anything about QVAC.