{% extends "base.html" %} {% block title %}Vaults & Documents - Talkpipe Vault{% endblock %} {% block content %} {% if confirm_vault_path %}
{{ confirm_vault_path }} holds {{ confirm_entry_count }} item{{ 's' if confirm_entry_count != 1 }} that {{ 'are' if confirm_entry_count != 1 else 'is' }} not vault data. A vault is the folder that stores the search index — not the documents you want to search. Creating a vault here will write index files alongside your existing files, and deleting the vault later would delete this entire folder.
To make these documents searchable, put the vault in a new, empty folder instead and index this folder into it.
Pick the documents to index and the vault to index them into. Documents are embedded with {{ models.embedding_source }}/{{ models.embedding_model }} (change this under Settings).
{% if retrieval_filter and retrieval_filter.available and vault_path %}
A ChatterLang script that filters or transforms the results
retrieved from the open vault — {{ vault_path }}
— before they reach the Ask answer. It applies to this vault
only; your other vaults are unaffected. The script is stored in this
vault's folder and travels with it; whether it runs is decided here,
on this machine.
Each retrieved result flows through your script one at a time; emit it to keep it, drop it to filter it, modify it to transform it. Every result is a dictionary shaped like:
{"doc_id": "…", "score": 0.87,
"document": {"content": "…", "source": "…", "title": "…"}}
In lambdaFilter/lambda expressions the
result is item, as everywhere in TalkPipe —
item['document'], item['score'],
item['doc_id']. (Because the result is a
dictionary, TalkPipe also exposes its top-level keys as bare
names, so document and score work
too.) Starter recipes:
| lambdaFilter[expression="'some term' not in item['document'].get('content', '').lower()"]
drop results whose content mentions a term
| lambdaFilter[expression="'/archive/' not in item['document'].get('source', '')"]
drop results from a folder, by source path
| lambdaFilter[expression="item['score'] > 0.2"]
drop low-scoring results (only useful when your
embedding backend reports similarity scores)
For the common case — is this text inside that
field? — isIn and isNotIn
say the same thing without an expression. Name the field with a
dotted path (document.content,
document.source) and the text to look for:
| isNotIn[field="document.content", value="some term"]
drop results whose content mentions a term
(the first recipe above, without the expression)
| isIn[field="document.source", value="/notes/"]
keep only results whose source path
contains a folder
isIn/isNotIn match exactly, so they are
case-sensitive, and the named field has to exist on every result
— a result missing it makes the script fail, which means
unfiltered results (or, with Strict checked, a failed
question). Reach for lambdaFilter when the field may
be absent (.get('source', '')), when the match
should ignore case (.lower()), or when the test is
anything more than containment.
Any registered ChatterLang segment works — including LLM
transforms — but the script must be a single pipeline of
segments: no INPUT FROM source, loops, or forks.
When active, the filter runs on Ask retrieval for this vault
(keyword and semantic streams are filtered independently, then
merged) and can be applied on the search pages with their
“Apply custom transform” checkbox.
No vaults opened yet — indexing documents creates your first one.
{% endif %}