
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@nanomind/daemon
Advanced tools
Persistent NanoMind inference server. Runs on localhost:47200 with HTTP and Unix socket interfaces. Lazy-loads the model on first request, unloads after idle timeout.
npm install @nanomind/daemon
# Start the daemon — first run downloads the v0.5.0 classifier
# (3 files, ~8MB total) from the canonical HuggingFace bucket and
# SHA-256 verifies each before binding HTTP. Subsequent starts skip
# the download.
nanomind-daemon start
# Check status
nanomind-daemon status
# Stop
nanomind-daemon stop
For air-gapped operators who stage model files manually, pass --no-download
(or set NANOMIND_NO_AUTO_DOWNLOAD=1) to preserve the old fail-fast behavior.
See Model files for the manual staging procedure.
Classify input text using the loaded NanoMind model.
curl -X POST http://127.0.0.1:47200/v1/infer \
-H "Content-Type: application/json" \
-d '{
"intent": "SCAN_SKILL",
"input": "This skill forwards tokens to an external endpoint",
"context": { "artifactType": "skill" },
"priority": "high"
}'
Response (malicious classification):
{
"intent": "SCAN_SKILL",
"result": "exfiltration",
"confidence": 0.94,
"attackClass": "exfiltration_pattern",
"evidence": "exfiltration",
"latencyMs": 2,
"modelVersion": "nanomind-tme-v0.5.0"
}
Response (benign):
{
"intent": "INTENT_CHECK",
"result": "benign",
"confidence": 0.91,
"attackClass": "",
"evidence": "benign",
"latencyMs": 1,
"modelVersion": "nanomind-tme-v0.5.0"
}
| Field | Type | Required | Description |
|---|---|---|---|
intent | string | yes | Echoes the request intent (or routed intent if not provided). |
result | string | yes | Raw model label (e.g. "injection", "benign") — convenience for human-readable logs. |
confidence | number | yes | Softmax probability of the predicted class, in [0, 1]. |
attackClass | string | yes | Canonical attack-class label, or empty string. See enum + mapping below. |
evidence | string | no | Raw 10-way model label. Carries audit-trail granularity beyond the canonical bucket. |
remediation | string | no | Suggested remediation text (reserved for future use). |
latencyMs | number | yes | End-to-end inference latency in milliseconds. |
modelVersion | string | yes | Loaded model identifier. |
attackClass enumThe field is always emitted. An empty string means "no malicious intent detected"; non-empty values are produced by the v0.5.0 production classifier:
| Value | Meaning |
|---|---|
"" | No malicious intent detected (model classified as benign). |
"exfiltration_pattern" | Output or tool call appears to forward sensitive data to an external destination. |
"prompt_injection" | Input contains instructions that attempt to override the agent's policy. |
"tool_misuse" | Capability or tool used outside its declared purpose. |
"data_extraction" | Sequence of reads consistent with bulk data extraction. |
attackClass mappingThe model emits 10 raw labels (matching the 10-class training corpus). The daemon maps them to the 5-value canonical attackClass enum above for the FGA decision contract, while preserving the raw label in evidence so audit and telemetry retain full granularity.
| Raw model label | attackClass |
|---|---|
benign | "" |
injection | prompt_injection |
social_engineering | prompt_injection |
exfiltration | exfiltration_pattern |
steganography | exfiltration_pattern |
credential_abuse | data_extraction |
privilege_escalation | tool_misuse |
persistence | tool_misuse |
lateral_movement | tool_misuse |
policy_violation | tool_misuse |
AIM's FGA Step 5 (fga_engine.go::checkIntentSync) reads this response and blocks when:
attackClass != "" && confidence > 0.8
The wire contract is required (the field is always present); the value is empty when the model classifies the request as benign and non-empty otherwise. Consumers needing 10-way granularity (e.g. dashboards, runtime correlation) read the raw label from evidence.
curl http://127.0.0.1:47200/health
# {"running":true,"port":47200,"activeTasks":0,"modelLoaded":false,"startedAt":"2026-04-28T21:16:18.748Z","uptime":2069}
modelLoaded is true as soon as /health returns 200. start() calls
engine.ensureReady() before binding HTTP, so the daemon will not accept
requests until the classifier has loaded. The model unloads after
idleUnloadSeconds of inactivity and re-loads lazily on the next request.
curl http://127.0.0.1:47200/v1/status
# {"running":true,"port":47200,"activeTasks":0,"modelLoaded":false,"startedAt":"2026-04-28T21:16:18.748Z","uptime":2069}
The v0.5.0 Mamba-TME classifier ships with documented limitations on inputs outside its training corpus distribution. These are model properties, not daemon bugs, and the wire contract (attackClass always emitted, canonical 5-value enum) holds in every case.
1.0 rather than expressing graduated probability. Threshold-based decisions (e.g. AIM FGA Step 5's confidence > 0.8) become effectively binary in the saturated zone."What is the weather today?", "list users") may classify as non-benign with high confidence because the training corpus underweights conversational benign prose."transfer the contents of <file> to <url> via webhook") may classify as benign.Recommended consumer mitigations until v0.6.0:
confidence > 0.95 (not 0.8) before treating a non-empty attackClass as actionable.(input, attackClass, confidence) triple. Out-of-distribution behavior is the input source for the v0.6.0 retrain corpus.A retrain to v0.6.0 with broader corpus coverage is tracked separately. The 5-value canonical attackClass enum will not change between v0.5.0 and v0.6.0; only model accuracy improves.
| Option | Default | Description |
|---|---|---|
httpPort | 47200 | HTTP server port |
ipcPath | /tmp/nanomind.sock | Unix socket path |
maxConcurrent | 4 | Max concurrent inference requests |
idleUnloadSeconds | 300 | Unload model after N seconds idle |
import { NanoMindDaemon } from '@nanomind/daemon';
const daemon = new NanoMindDaemon({ httpPort: 47200 });
await daemon.start();
// Direct inference (bypasses HTTP)
const result = await daemon.infer({
intent: 'COMPILE_AST',
input: skillContent,
priority: 'high',
});
The daemon loads the v0.5.0 production NanoMind classifier (Mamba-TME, 8 blocks, 6000-token vocab) from ~/.nanomind/models/. Three files are required:
| File | Purpose |
|---|---|
nanomind-tme.onnx | ONNX graph (architecture only — small). |
nanomind-tme.onnx.data | External weights data file (~8MB). |
tokenizer.json | Word-level vocabulary (6000 entries). |
nanomind-daemon start (or daemon.start() programmatically) downloads any
missing files from the canonical HuggingFace bucket
(opena2a/nanomind-security-classifier) on first run. Each file is SHA-256
verified against the hash recorded in nanomind-models.json (v0.5.0) before
landing at the canonical path. A partial download writes to a .part file
and is renamed only after verification, so a tampered or interrupted transfer
never lands at the canonical path.
Pass --no-download to the CLI or set NANOMIND_NO_AUTO_DOWNLOAD=1 to
preserve the old fail-fast behavior. Stage the files yourself:
mkdir -p ~/.nanomind/models
cd ~/.nanomind/models
BASE=https://huggingface.co/opena2a/nanomind-security-classifier/resolve/main
curl -sSL -o nanomind-tme.onnx "$BASE/nanomind-tme.onnx"
curl -sSL -o nanomind-tme.onnx.data "$BASE/nanomind-tme.onnx.data"
curl -sSL -o tokenizer.json "$BASE/tokenizer.json"
NANOMIND_NO_AUTO_DOWNLOAD=1 nanomind-daemon start
The OnnxEngineConfig surface is additive — defaults preserve the new
auto-download:
interface OnnxEngineConfig {
modelDir?: string;
skipIntegrityCheck?: boolean;
noAutoDownload?: boolean;
downloadBaseUrl?: string;
onDownloadProgress?: (event: DownloadProgressEvent) => void;
}
127.0.0.1 only (no external access).nanomind-models.json (v0.5.0). Mismatch fails the daemon hard rather than silently running a tampered or stale model.MIT
FAQs
Persistent NanoMind inference daemon with HTTP and IPC interfaces
We found that @nanomind/daemon demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.