Skip to content
docs
UseBuildChangelog
Open Lumin

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 image chart 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 drive signal.
  • get_shadbala backs the Strongest planet signal, 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 capacity signal, 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_known
  • location_name, free text, resolved by the model
  • biological_sex, optional

Birth-time fallback

With 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

typescript
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

json
{
  "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