Knowledge > Processes > Theological Lens Matching
Theological Lens Matching
How the system adapts to each church's theological tradition across both the voice agent and chatbot. The lens controls vocabulary, doctrinal rules, RAG filtering, and agent personality.
Theological Lens Taxonomy
17 theological lenses (IDs 1-17) plus 1 universal (ID 0), stored in sai_theological_lenses.
ID Lens Name
── ──────────────────────
0 Universal (shows in all traditions)
1 Evangelical / Restoration
2 Progressive
3 Missional
4 Reformed / Presbyterian
5 Wesleyan / Methodist
6 Lutheran
7 Catholic
8 Anabaptist
9 Pentecostal
10 Christocentric (DEFAULT — non-denominational)
11 Orthodox
12 Black Church
13 Anglican / Episcopal
14 Baptist
15 Charismatic
16 Dispensational
17 Liberation
Lens Resolution (Priority Order)
The system resolves a church's theological lens through a cascade of sources. The first match wins.
Chatbot Resolution (route.ts)
PRIORITY 1: CLIENT-SIDE OVERRIDE (demo mode)
IF lensOverride is a valid number (1-17)
AND lensNameOverride is a non-empty string (<=50 chars):
lensId = lensOverride
lensName = sanitized lensNameOverride
# Used in demo/preview when user selects a tradition
PRIORITY 2: EXPLICIT CHURCH SETTING (church_theological_lenses)
query church_theological_lenses
WHERE church_id = church.id
JOIN sai_theological_lenses for lens_name
LIMIT 1
IF found:
lensId = theological_lens_id
lensName = lens_name
PRIORITY 3: DENOMINATION AUTO-DETECT (DENOMINATION_TO_LENS mapping)
IF church.denomination is not null:
lensId = DENOMINATION_TO_LENS[church.denomination] ?? 10
query sai_theological_lenses for lens_name WHERE lens_id = lensId
PRIORITY 4: DEFAULT
lensId = 10 (Christocentric)
lensName = "Christocentric"
Voice Agent Resolution (core/rag.py)
FUNCTION get_lens_id(denomination: str | None) -> int:
IF denomination is None or empty:
RETURN 10 (Christocentric — DEFAULT_LENS_ID)
RETURN DENOMINATION_TO_LENS.get(denomination, 10)
Denomination-to-Lens Mapping
70+ denomination strings mapped to 17 lens IDs. This mapping is maintained in sync across three files:
churchwiseai-web/voice-agent-livekit/core/rag.py(DENOMINATION_TO_LENS)churchwiseai-web/src/lib/rag.ts(DENOMINATION_TO_LENS)- Legacy:
voice-agent/rag.js(reference only)
BAPTIST FAMILY → Lens 14 (Baptist)
Baptist, Southern Baptist, American Baptist, Free Will Baptist
CATHOLIC → Lens 7
Catholic, Roman Catholic
WESLEYAN/METHODIST FAMILY → Lens 5
Methodist, United Methodist, Free Methodist, AME
Church of the Nazarene, Nazarene, Wesleyan
REFORMED/PRESBYTERIAN → Lens 4
Presbyterian, PCA, PCUSA, Reformed
LUTHERAN → Lens 6
Lutheran, ELCA, LCMS, Missouri Synod
PENTECOSTAL → Lens 9
Pentecostal, Assembly of God, Assemblies of God
Church of God, Foursquare
ANGLICAN/EPISCOPAL → Lens 13
Episcopal, Anglican
ORTHODOX → Lens 11
Orthodox, Greek Orthodox, Eastern Orthodox, Russian Orthodox
ANABAPTIST → Lens 8
Mennonite, Amish, Anabaptist, Brethren
NON-DENOMINATIONAL → Lens 10 (Christocentric, DEFAULT)
Non-denominational, Nondenominational, Community Church, Bible Church
CHARISMATIC → Lens 15
Charismatic
EVANGELICAL / RESTORATION → Lens 1
Evangelical, Church of Christ, Disciples of Christ, Christian Church
BLACK CHURCH → Lens 12
AME Zion, CME, COGIC, National Baptist
DISPENSATIONAL → Lens 16
Dispensational
PROGRESSIVE → Lens 2
Progressive, UCC, United Church of Christ
MISSIONAL → Lens 3
Missional
LIBERATION → Lens 17
Liberation
What the Lens Controls
1. RAG Filtering
Both voice agent and chatbot filter search results by lens ID.
VOICE AGENT (fetch_session_rag in core/rag.py):
lens_id = get_lens_id(denomination)
search_unified_rag(embedding, lens_ids=[lens_id], match_count=5)
# Returns content tagged with this lens OR universal (lens_id=0)
CHATBOT (route.ts):
searchRAG({ queryEmbedding: embedding, lensIds: [lensId], matchCount: 8 })
# Supabase RPC search_unified_rag_content filters by p_theological_lens_ids
RESULT:
A Baptist church gets Baptist-tradition illustrations
A Catholic church gets Catholic-tradition content
Universal content (lens_id=0) appears for all traditions
2. Doctrinal Rules (theological_contradictions)
Per-lens rules that constrain what the AI must/must-not say.
QUERY: theological_contradictions WHERE lens_id = lensId
FIELDS PER RULE:
doctrine_category: e.g., "baptism", "eucharist", "ordination"
primary_position: "Believers' baptism by immersion only"
contrary_positions: ["infant baptism", "sprinkling"]
must_include_terms: ["credobaptism", "immersion"]
must_exclude_terms: ["christening", "infant sprinkling"]
explanation: context for the AI
INJECTED AS:
"IMPORTANT DOCTRINAL REQUIREMENTS:
BAPTISM:
- This church's position: Believers' baptism by immersion only
- MUST include: credobaptism, immersion
- MUST NEVER mention: christening, infant sprinkling
- DO NOT recommend: infant baptism, sprinkling
This means your answers should strictly follow the Baptist
theological positions listed above."
CHURCH-SPECIFIC OVERRIDES (organization_settings.doctrinal_overrides):
A church can override standard lens positions:
{ "baptism": { custom_practice: true,
explanation: "We practice both infant dedication and believer's baptism" }}
Appended as "CUSTOM CHURCH PRACTICES" section
3. Vocabulary (lens_knowledge → lens-vocabulary.ts)
Per-lens preferred and avoided vocabulary injected into the chatbot prompt.
EXAMPLES:
Baptist (lens 14):
PREFER: "baptism by immersion", "believer's baptism", "Sunday school"
AVOID: "christening", "infant baptism", "catechism"
Catholic (lens 7):
PREFER: "Holy Mass", "Eucharist", "parish", "sacrament", "priest"
AVOID: "worship service", "communion table", "pastor" (use "Father")
Orthodox (lens 11):
PREFER: "Divine Liturgy", "Theotokos", "Holy Tradition"
AVOID: "worship service", "Bible study" (use "catechesis")
Lutheran (lens 6):
PREFER: "the Lord's Supper", "Real Presence", "sacrament"
AVOID: "mere symbol", "just symbolic"
IMPLEMENTATION:
fetchLensVocabulary(lensId) → queries lens_knowledge table
buildChatVocabularyBlock(vocab, lensName) → formats for prompt injection
4. Agent Personality
The theological lens influences the chatbot's conversational style.
FORMAL TRADITIONS (Catholic, Orthodox, Anglican, Lutheran):
More formal language
Liturgical calendar awareness
Proper titles (Father, Reverend, Bishop)
Reference to sacraments, tradition, church fathers
INFORMAL TRADITIONS (Non-denominational, Community, Charismatic):
Conversational tone
Contemporary language
First-name basis
Focus on personal relationship with God
REFORMED TRADITIONS (Presbyterian, Reformed, Baptist):
Theological precision
Scripture-first approach
Doctrinal clarity
Respect for confessional standards
BLACK CHURCH TRADITION:
Rich call-and-response patterns
Social justice awareness
Community emphasis
Musical/worship tradition references
Cross-Channel Consistency
The lens resolution produces identical results across both channels because:
- Both use the same
DENOMINATION_TO_LENSmapping (kept in sync manually) - Both search the same
unified_rag_contenttable with the same lens filter - Both read the same
theological_contradictionsrules - Default is always Christocentric (lens 10) when denomination is unknown
The voice agent resolves lens once at session initialization (fetch_session_rag) and caches it for the call. The chatbot resolves lens on every request (stateless API).