Dost Live
Dost (दोस्त — "friend") is KA26's AI layer. It started as a personal companion (capture a reminder, jot a note, talk) and has grown into the conversational entry point to the whole app: a Gemini function-calling agent that searches stores, finds service people, builds a cart, looks up your orders and prescriptions, posts community requests, and sets reminders — and renders every actionable result as a tappable card that deep-links to the exact record.
Internal naming: the route folder and DB tables are still
heli/Heli(Dost is the user-facing brand). Invisible to users.
1. Dost is an agent, not a chatbot
Behind DOST_AGENT_LOOP=true, Dost runs a Gemini function-calling loop (src/lib/dost-tools/agent-loop.ts, MAX_AGENT_STEPS=10, plus a self-review pass). It has 19 tools (src/lib/dost-tools/registry.ts):
| Group | Tools |
|---|---|
| Discover | search_stores, search_products, search_providers, search_requests, search_ads, find_saathi_ride |
| Personal data | get_orders, reorder_order, search_health, get_user_profile, get_purchase_history |
| Helper | youtube_search_url |
| Act | set_reminder, add_to_cart, manage_cart, shopping_list, place_order, create_ad, create_request |
Tools are general, never scenario-specific (there is no birthday_planner). Each wraps an existing KA26 capability. The agent gathers → decides → acts.
2. Two surfaces
| Surface | Endpoint | Behaviour |
|---|---|---|
Home capture box (mobile/app/(tabs)/heli.tsx) | POST /api/heli/capture | A Gemini intent classifier (routeIntent). Reminders/notes/events are saved as HeliThoughts. Actionable / ecosystem queries ("show my orders", "find a plumber", "2 BHK for rent") are routed to kind:"chat" → the agent chat. |
Chat screen (mobile/app/heli/chat.tsx) | POST /api/heli/chat-stream | SSE-streaming agent loop. Tool results stream back as DostActionCards. |
The classifier guard looksLikeEcosystemQuery (src/lib/heli-gemini.ts) plus an explicit prompt rule keep live-data queries on the agent path — never the memory-RAG question path, which would otherwise answer from stale saved memories.
3. Action cards (nothing actionable is plain text)
Every tool result that represents an entity renders as a card in mobile/src/components/DostActionCard.tsx, deep-linking to the specific record:
| Tool | Card | Deep-link |
|---|---|---|
search_stores | Stores | the shop |
search_products | Products | the item in its shop (/product/[id]) |
get_orders | Orders (status pill) | /order/[id] |
search_health | Prescriptions | /health-records |
search_providers | Providers | /provider/[code] |
search_ads / search_requests / find_saathi_ride | Ads / Requests / Rides | the listing / thread / ride |
add_to_cart / manage_cart / reorder_order | Live cart | the cart |
4. Persistent conversational carts v100
There is one active cart per (consumer, store) — enforced by a Postgres partial unique index (WHERE status='active', created via raw DDL because Prisma v6 can't express it). Dost appends and edits items by voice ("add two more", "remove the dal"), the cart persists across app restart, and checkout converts it to a StoreOrder. Models: DostCart + DostCartItem (snapshot price, @@unique(cartId, productId) merge). An abandoned-cart reminder fires once if items sit untouched for >12h. This unified what used to be two disconnected carts (Dost's server rows vs. the cart screen's phone-local storage).
5. Ecosystem reach v101
get_orders / reorder_order / search_health extend Dost past commerce into the user's own records. Order and prescription cards render with status and deep-links; the previously-inert ads/requests/Saathi cards became tappable.
6. Provider Profiles / Business Card v102
Every member can turn on a shareable occupation identity — the Share-my-Shop loop applied to people.
- Set up: occupation, services, service area, a one-line pitch, bio. Flipping
providerActiveon mints a public code (Consumer.qrCode). Editor atmobile/app/provider-profile.tsx. - Discover: Dost's
search_providersfinds opt-in members for "I need a plumber in Gadag" → a Provider card. Area-ranked; never returns the caller; contact is not on the card. - View Profile (
mobile/app/provider/[code].tsx): Call / WhatsApp Message / "Ask the community instead". Contact is revealed only here — "View Profile gatekeeps contact". - Share:
/u/[code]is a public web business card with rich OG metadata (name · occupation) so a WhatsApp share renders a preview and pulls non-users into the install funnel. - Stats:
ProfileViewEvent(deduped per visitor per day) +ProfileShareEventgive the member a "viewed N× · shared N×" signal.
Routes: GET/PATCH /api/consumer/provider-profile, GET /api/providers/[code] (public, contact-gated), POST /api/profile-share-event.
7. Reliability lessons (each found by live testing, not unit tests)
- Routing: ecosystem queries were being answered from saved memory and confabulating (invented a "vanilla cake" order). Fixed by routing live-data queries to the agent loop via the classifier guard + prompt rule.
- SSE chunk-boundary: verbose replies silently rendered as plain text — the streaming parser lost any
doneevent that split across two network chunks, exactly when the card data arrives. Fixed with a bufferingcreateSSEParser(mobile/src/lib/sse-parser.ts). - Card persistence: reopening a past session showed only text.
HeliChatTurn.toolCalls(JSONB) now snapshots the agent's tool calls so a restored session rehydrates the same cards.
8. Schema
HeliThought (unified capture; kind discriminator), HeliMemory (LLM-extracted facts, soft TTL), HeliChatTurn (+toolCalls JSONB), HeliSession (auto-titled), HeliAbuseFlag. Dost V2 added DostUserProfile / DostPersona / DostVoiceSample / DostEmotionalAnchor with a documented 5-point voice-data isolation contract. Provider Profiles added Consumer.occupation/providerHeadline/providerActive/providerSince + ProfileShareEvent / ProfileViewEvent.
9. Status
Consumer app v102 (1.0.82). Backend revision 00521. DOST_AGENT_LOOP=true on production. Verified end-to-end on device: order/prescription/ad/provider cards render and deep-link; "I need an electrician" → provider card → View Profile → Call.