Examples
products-matcher
The same pattern as wellness-matcher, aimed at a broad marketplace catalog (flowers, cakes, electronics, jewelry, fashion, hampers, home) instead of a personal-care line. The output is a consumer-personality read, not a health lens, and it draws on Jaimini and a divisional chart that wellness-matcher does not touch.
Tool chain
Eleven tools, all called on every request: set_birth_profile, get_full_chart, get_planets, get_house_cusps, get_nakshatra_details, get_aspects_and_strength, get_boundary_warnings, get_shadbala, get_arudha_lagna, get_chara_karakas and get_d2_chart.
- get_arudha_lagna reads the projected public image, the closest KP/Jaimini reading to a consumer-facing persona. It drives the
Public imagechart signal. - get_chara_karakas returns the Jaimini chara karakas. The Atmakaraka (the planet at the highest degree within its sign) marks the soul's deepest craving, and drives the
Core drivesignal. - get_shadbala backs the
Strongest planetsignal, and tests whether a "strong planet" claim in the trait mapping is actually carried by strength or is mere placement. - get_d2_chart, the Hora divisional chart, reads wealth-acquisition capacity: each sign halved into a Sun hora (active earning, status spending) and a Moon hora (accumulation, value-mindedness). It drives the
Spending capacitysignal, and because the hora split is longitude-based rather than time-based, this one signal survives the birth-time fallback.
Inputs
name,birth_date,birth_time,birth_time_knownlocation_name, free text, resolved by the modelbiological_sex, optional
Birth-time fallback
birth_time_known: false the app defaults to noon and skips ascendant and cusp logic, leaning on planet placements plus Moon nakshatra. The D2-derived spending signal is unaffected, since it reads sign, not time.Call it
const result = await runLumin({
allowedTools: ALLOWED_TOOLS, // the 11 tools above
system: buildSystemPrompt(),
user: buildUserPrompt(input),
maxTokens: 16000,
effort: "xhigh",
signal: req.signal,
});
const parsed = ensureShape(
parseJsonBlock<MatchResponse>(result.text),
validateShape,
);Response shape
{
"resolved_location": {
"latitude": 6.9271, "longitude": 79.8612,
"utc_offset_minutes": 330, "note": "Colombo, Sri Lanka"
},
"personality": {
"label": "Warm and celebratory",
"traits": ["warm", "celebratory", "nurturing"],
"summary": "A Moon-Venus signature that leans toward gift-giving occasions...",
"signals": [
{ "label": "Public image", "value": "Cancer Arudha Lagna", "detail": "Reads as nurturing, home-oriented, approachable." },
{ "label": "Core drive", "value": "Venus Atmakaraka", "detail": "Highest-degree planet in sign; craves beauty, harmony, connection." },
{ "label": "Strongest planet", "value": "Moon", "detail": "Leading Shadbala rupas among the personality-carrying planets." },
{ "label": "Spending capacity", "value": "Moon hora", "detail": "Accumulation-minded, values-driven purchasing over status spending." }
]
},
"matches": [
{
"id": "km-scented-candle-set",
"reason": "Warm, home-oriented persona with a nurturing Arudha Lagna.",
"name": "Amber Rose Candle Trio",
"category": "home",
"price_lkr": 3600
}
]
}Screens
- A hero and a product-catalog-flavoured intake form
- A personality card listing the four chart signals beside the trait labels
- A 5-up product grid across nine categories
The interesting engineering detail
The trait mapping (planet to personality trait) lives entirely in the prompt, same as wellness-matcher's dosha mapping. The tools do not encode "warm" or "luxurious"; they return chart facts (an Arudha sign, an Atmakaraka, a Shadbala rupa count, a hora split), and the four chart signals are surfaced in the UI precisely so a buyer can audit the read instead of trusting a label. Fork this app for a new vertical by changing the mapping and the catalog; the tool chain does not change.
Where to next
- Commerce and personalization use cases for the send-time optimisation and segment-builder rows this same tool set can drive.
- wellness-matcher for the sibling pattern aimed at a personal-care catalog.