Detectors

Detectors can be replaced without changing the policy.

Every detector runs behind the same HTTP Detector API. A rail binds to a detector by class, not by name. The injection rail picks the injection-class detector with the highest grade on the installed tier. When a model is replaced by a better one, the policy, the ledger and the evidence pack stay the same.

29detectors
13classes
20on the CPU tier
9on the GPU tiers (vLLM)
1HTTP contract (Detector API 0.7)
How one is chosen

Selection goes by class, grade, language and tier.

A rail declares the detector class it needs and a minimum quality grade (A, B or C). The registry picks the highest-graded detector on the installed tier that implements the class, meets the grade and supports the detected language. When none does, the rail’s fail posture applies; activation reports the gap and the health page shows it.

Catalogue →
Hardware tiers

Four hardware tiers, one policy model

The tier decides only which detectors are installed. The Starter tier runs without a GPU; the GPU tiers add guard LLMs over vLLM. Switching a detector on in the console compares its memory estimate with the container’s limit; a change that does not fit is not applied.

Tiers →
Models

Model weights arrive signed or are downloaded on request.

Every model file is recorded in the catalogue with its sha256 and size. On a closed network the models come inside the bundle or as a tar, and every file is re-hashed. A download starts only when the host explicitly allows it and an administrator picks a model in the panel, from allow-listed hosts only.

Deployment →
Map

Three layers, four hardware tiers

Rules and built-in detectors run in-process. The CPU models are in every install. The GPU guards are added over vLLM. Pick a hardware tier to see which detectors it activates. Tap a node to read its name, class and runtime.

Detector map · three layers · nodes by class · tier chips
layer 1Rules · built-inin-process, no model6 / 6 active
Injection
Rules · 3
Code
Files
layer 2CPU modelsONNX · PyTorch · llama.cpp13 / 14 active
Injection · 2
Personal data · 5
Toxicity · 2
Groundedness · 2
Jailbreak
Content safety
Topic
layer 3GPU guardsvLLM, OpenAI-compatible endpoints4 / 9 active
Content safety · 4
Policy judge
Agent trajectory · 2
Image
Groundedness
Recommended1 × 48 GB (or 2 × 24)23 / 29 detectors active
Hover or tap a node: its name, class, tier and runtime appear here.
activenot on tieron demandThe catalogue as shipped; a rail binds to a detector by class, never by name.
Turkish

Separate evaluation sets for Turkish

Turkish evaluation sets of more than 11,000 rows cover injection, benign banking text, PII, health data and groundedness. A bake-off report for the CPU tier is published. The over-refusal rate on benign samples is a CI gate (GR-INJ-03). A detector that blocks benign Turkish text counts as a regression. TCKN and IBAN values are validated with checksums. İ/ı folding preserves length, so redaction spans do not shift.

Models

Model weights arrive signed or are downloaded on request.

The router fetches the model only from allow-listed hosts, in parts, and verifies each part. Nothing else is downloaded. The model licences (Apache-2.0, MIT, Gemma, Llama 4 Community, NVIDIA Open Model) ship as text inside the kit.

Catalogue

The catalogue by tier

The Starter tier runs without a GPU. It uses ONNX int8 models, llama.cpp and built-in detectors that need no model. The GPU tiers add guard LLMs over vLLM. The organisation’s own vLLM endpoints are configured from the console. Thulpar does not need to run vLLM itself.

Injection · 3Personal data · 5Toxicity · 2Groundedness · 3Jailbreak · 1Content safety · 5Rules · 3Topic · 1Code · 1Files · 1Policy judge · 1Agent trajectory · 2Image · 1

Starter · CPU · 8 vCPU / 16 GB RAM, no GPU

20 detectors
detectorclassbaseruntimelanguagesgraderailslicence
rules-injection
Direct override, role play, encoding escapes; length-preserving Turkish folding
InjectionThulpar rule set (regex, TR/EN)no model, in-processtr, enCinjection.direct, injection.indirectThulpar
horizon-pi-guard-base InjectionmmBERTONNX Runtime, int830 languages incl. trAinjection.direct, injection.indirectApache-2.0
piguard InjectionDeBERTa-v3-basePyTorch, CPUenBinjection.indirectMIT
pii-tr
The tier’s PII detector: a GLiNER identifier that fails its checksum is dropped
Personal dataneonredact-tr-gliner ∪ Presidiounion: the validated identifier winstr, enApii.detect, pii.redactApache-2.0 / MIT
pii-presidio
TCKN, IBAN, card (Luhn), plate, e-mail, IP, TR phone
Personal dataMicrosoft Presidiopattern and checksum recognizers (light); spaCy/Stanza NER optionaltr, enBpii.detect, pii.redactMIT
neonredact-tr-gliner Personal dataGLiNER mDeBERTaPyTorch, CPUtrApii.detect, pii.redactApache-2.0
neonredact-tr Personal dataDistilBERT-TRONNX Runtime, int8trBpii.detect, pii.redactApache-2.0
pii-health
KVKK Art. 6 health data: disease, medication, anatomy, procedure, symptom, status
Personal datahealth-lexicon ∪ OpenMed NER (TinyMed-65M ×3)TR/EN lexicon on every text; NER on text that reads as Englishtr, enBpii.healthApache-2.0
detoxify-multilingual ToxicityXLM-RoBERTaPyTorch, CPUen fr es it pt tr ruBtoxicityApache-2.0
turkcell-offensive-tr ToxicityBERT-TRPyTorch, CPUtrAtoxicityMIT
lettucedetect-v2-mmbert
The built-in groundedness rail’s detector; a Turkish QA template
GroundednessmmBERTPyTorch, CPUtr, en, de, fr, es, it, pl, zhBgroundednessApache-2.0
turk-lettucedetecton-demand download GroundednessEuroBERT 210MPyTorch, CPUtr, enBgroundednessMIT
haloguard-0.8b JailbreakQwen3.5llama.cpp Q8_046 languagesBjailbreakApache-2.0
qwen3guard-0.6b Content safetyQwen3Guardllama.cpp Q8_0119 languagesBcontent.input, content.outputApache-2.0
language-idbuilt-in RulesLingua 2.2no model, in-process42 candidatesAlanguageApache-2.0
topic-embed Topicmultilingual-e5-smallONNX fp32, cosine similarity*Btopic, topic.outputMIT
injection-argsbuilt-in
SQLi, command, path traversal, RFI, XSS; 137 CRS rules under RE2
Ruleslibinjection + an OWASP CRS 4 subsetno model, in-process*Ctool.args.injectionBSD-3 / Apache-2.0
codeshieldbuilt-in CodeMeta PurpleLlama CodeShield + semgrep-coreregex rules, Semgrep in a separate process, no network14 languagesCcode, code.tool_resultMIT / LGPL-2.1
file-analyzerbuilt-in Filespypdf, pypdfium2, defusedxml, olefile, Pillow, tesseract, zxing-cppone isolated child process per file, memory and time limits*Bfile.analyze, file.type, file.active_content, file.hidden_text, file.metadata_pii, file.qropen source
rules-yarabuilt-in Rulesyara-python 4.5 / libyaracompiled-rule cache, scan deadline and byte caps*CyaraApache-2.0 / BSD-3

Standard · 1 × 24 GB GPU

3 detectors
detectorclassbaseruntimelanguagesgraderailslicence
qwen3guard-gen-4b Content safetyQwen3GuardvLLM, OpenAI-compatible119 languagesAcontent.input, content.output, jailbreakApache-2.0
dynaguard-1.7b Policy judgeQwen3vLLM, OpenAI-compatibleen, trBself_check.input, self_check.output, topicApache-2.0
agentdog-1.5-2b Agent trajectoryQwen2.5vLLM, OpenAI-compatibleenBtool.trajectoryApache-2.0

Recommended · 1 × 48 GB (or 2 × 24)

4 detectors
detectorclassbaseruntimelanguagesgraderailslicence
qwen3guard-gen-8b Content safetyQwen3GuardvLLM, fp8119 languagesAcontent.input, content.output, jailbreakApache-2.0
nemotron-cs-4b Content safetyNemotronvLLM, image inputen, trAcontent.output, image.content_safety, self_check.outputNVIDIA Open Model
agentdog-1.5-4b Agent trajectoryQwen2.5vLLM, OpenAI-compatibleenAtool.trajectoryApache-2.0
shieldgemma-2-4b ImageGemma 3vLLM, multimodal*Aimage.content_safetyGemma

Performance · 2 × 48 GB+, replicated

2 detectors
detectorclassbaseruntimelanguagesgraderailslicence
granite-guardian-4.1-8b GroundednessGranitevLLM, OpenAI-compatibleenAgroundedness, tool.trajectoryApache-2.0
llamaguard-4-12b Content safetyLlama 4vLLM, multimodal; opt-in*Acontent.input, content.output, image.content_safetyLlama 4 Community
Hardware tiers

Four hardware tiers, one policy model

Sector templates declare their minimum tier. On a smaller install, activation names the rails that would deny every check and suggests the template’s Starter variant.

CPU · 8 vCPU / 16 GB RAM, no GPU

Starter

status

Released; CPU bake-off measured

sync

Rules and YARA, the mmBERT injection classifier, PII (Presidio + Turkish GLiNER), toxicity, language id, tool-argument injection, CodeShield, the file analyzer, the health lexicon

async

Jailbreak and content-safety guards (llama.cpp) raise findings after the answer

who it is for

Pilots, shadow mode, environments without a GPU, edge installs

1 × 24 GB GPU

Standard

status

Built; GPU bake-off next

sync

Everything in Starter plus content safety 4B, a policy judge and agent trajectory over vLLM; jailbreak synchronous

async

Content safety on long outputs

who it is for

One application in production; the minimum tier of the sector templates

1 × 48 GB (or 2 × 24)

Recommended

status

Built; GPU bake-off next

sync

+ content safety 8B, custom policy and image moderation (Nemotron, ShieldGemma 2), agent trajectory 4B, Granite Guardian (groundedness)

async

Streaming moderation, MELON sampling

who it is for

Multi-application organisations; policy judge and images; the defence and public-sector templates

2 × 48 GB+, replicated

Performance

status

Built; GPU bake-off next

sync

All of the above with HA replicas, per-tenant detector pools, Llama Guard 4 (opt-in)

async

Explainable judge, re-execution sampling

who it is for

Bank scale, high availability, multi-tenant installations

Hardware presets
H200

An H200 that also serves the customer’s own LLMs: the guards on the same card with their own memory budget

DGX Spark

The guards on a DGX Spark: five models in 128 GB of unified memory, the arm64 bundle

Your own vLLM

Thulpar need not run vLLM: the customer’s own vLLM endpoints are the primary path, added from the console

Your own detector

Register your own model as a detector.

Any HTTP service that implements the Detector API can register. The info endpoint states its class, grade, languages and the rails it implements. The contents, chat and stream endpoints return spans. The organisation’s own fine-tuned classifier, a vendor model or an open guard model takes the same place in the rail graph. It writes to the same ledger.

GET /api/v1/info
{ "id": "acme-fraud-intent", "class": "policy_judge", "grade": "B",
  "languages": ["tr", "en"], "rails": ["self_check.input"],
  "capabilities": ["contents", "chat"] }

POST /api/v1/text/contents  →  DetectorResult[]  (spans, score, category)

See it in your own environment.

A one-hour technical demo: your scenario, your policy pack, on a closed-circuit install. Then the install kit and a trial licence for a pilot.