Trove reads every document you give it and answers questions against the record — with citations, and with an explicit “not in the record” when the answer isn’t there. Point it at your own model and nothing leaves your network.
Drop files or paste a link to an archive — no per-project document cap.
Measured, not asserted
Benchmark: the public Synthea CCDA corpus (1,180 patient records, 688 MB), asked to identify every patient with a documented history of cancer. Scored against a ground-truth answer key derived directly from the SNOMED-coded problem lists. 48 records in that corpus mention “cancer” without carrying a cancer diagnosis; Trove excluded all 48.
How it works
Most document AI ranks chunks by similarity and reads the top few. That works until the question is “find all of them” — then anything the ranker missed is simply absent from the answer, and nothing in the output tells you it’s missing. Trove takes a different path.
Every format is parsed to text with its structure intact — sections, tables, headings, coded fields. A diagnosis on a problem list stays distinguishable from the same word appearing in a lab name.
Selecting the sections that can answer a question routinely cuts a corpus by two to three orders of magnitude, losslessly. On the clinical benchmark above, 688 MB became 256K tokens — small enough to read whole.
Under the context budget, every document goes to the model in full. Nothing is selected out, so nothing can be missed by selection. Ranking is a fallback for corpora that genuinely exceed the budget, not the default path.
Each claim carries the document it came from. When the record doesn’t support an answer, Trove says which part is missing instead of producing a confident guess.
Capabilities
Claims cite the document they came from. Open the source and read it yourself — verification takes seconds, not a re-review of the whole set.
Asked to find all matching records, Trove returns all of them and states the count. It does not sample, truncate, or trail off into “and others”.
Trove talks to any OpenAI-compatible endpoint. Run GLM-5.2, Qwen3, or DeepSeek on your own GPUs and no document ever leaves your infrastructure.
Load a whole matter, archive, or record set at once. Upload files directly or paste a link to a ZIP and Trove expands and ingests the contents.
Incomplete or redacted records are normal. Trove reasons from what remains and names what’s missing rather than filling the gap with something plausible.
Four endpoints. Upload, ingest, ask, list. Wire it into the systems your team already uses instead of asking them to adopt another console.
Developer API
Upload a document, ask a question. Authentication is a bearer token; everything speaks JSON.
# 1 — upload a document
curl -X POST https://trove.techmaven.us/v1/documents \
-H "Authorization: Bearer $TROVE_KEY" \
-F "file=@contract.pdf"
# or pull an entire archive from a link
curl -X POST https://trove.techmaven.us/v1/ingest-url \
-H "Authorization: Bearer $TROVE_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/records.zip"}'
# 2 — ask across everything you've loaded
curl -X POST https://trove.techmaven.us/v1/ask \
-H "Authorization: Bearer $TROVE_KEY" \
-H "Content-Type: application/json" \
-d '{"question":"Which contracts auto-renew?"}'
import requests
BASE = "https://trove.techmaven.us"
H = {"Authorization": f"Bearer {KEY}"}
# upload
with open("contract.pdf", "rb") as f:
doc = requests.post(f"{BASE}/v1/documents",
headers=H, files={"file": f}).json()
# ask
r = requests.post(f"{BASE}/v1/ask", headers=H, json={
"question": "Which contracts auto-renew?",
"document_ids": [doc["id"]],
}).json()
print(r["answer"])
for c in r["citations"]:
print(c["tag"], c["filename"])
const BASE = "https://trove.techmaven.us";
const H = { Authorization: `Bearer ${KEY}` };
// upload
const fd = new FormData();
fd.append("file", await fs.openAsBlob("contract.pdf"));
const doc = await (await fetch(`${BASE}/v1/documents`,
{ method: "POST", headers: H, body: fd })).json();
// ask
const res = await (await fetch(`${BASE}/v1/ask`, {
method: "POST",
headers: { ...H, "Content-Type": "application/json" },
body: JSON.stringify({ question: "Which contracts auto-renew?" }),
})).json();
console.log(res.answer);
{
"answer": "Three contracts auto-renew:\n\n
1. Northwind MSA — 12-month term,
auto-renews unless notice is given
60 days prior [d1]\n
2. Acme SaaS Order — renews annually
at list price [d3]\n
3. Belltower Lease — 5-year term with
one 3-year option [d7]\n\n
The Cortez agreement [d4] is silent on
renewal; the record does not say.",
"citations": [
{ "tag": "d1",
"document_id": "d_9f2c41ab7e30",
"filename": "northwind-msa.pdf" }
],
"model": "glm-5.2",
"documents_searched": 7,
"elapsed_ms": 4182
}
Deployment
Trove has one integration point with the model: an OpenAI-compatible base URL. Serve the weights yourself and documents never leave your network.
# serve any open-weight model on your own GPUs
vllm serve zai-org/GLM-5.2 --port 8000 --tensor-parallel-size 8
# point Trove at it — this is the entire integration
TROVE_LLM_BASE_URL=http://localhost:8000/v1 \
TROVE_LLM_MODEL=zai-org/GLM-5.2 \
uvicorn main:app --host 0.0.0.0 --port 8080
# SGLang, Ollama, TGI, LM Studio and KServe all expose the same
# interface — only the URL and model name change.
Leads the open field on agentic and coding evaluations. Scored 102/102 with zero false positives on the clinical benchmark above. The default recommendation.
Roughly 1% of frontier output pricing. The right choice when volume, not the last point of accuracy, is the binding constraint.
The most widely adopted open base. Pick it when you intend to fine-tune on your own corpus or run at the edge.
Drop files into the app, or paste a link to an archive.