The first artifact from a Salesforce org took weeks of admin setup. Kriyo paints it in the first call.
Kriyo is an AI-UI for Salesforce: a chat where every conversation is the interface. A natural-language prompt runs an NL → SOQL → dashboard pipeline against a live org and streams the result as generative UI — metrics, charts, and tables painted onto the canvas as JSONL patches, not described back in prose.
Provenance: this problem was relayed to me first-hand by an industry insider at a ~15-year-old Salesforce data-management ISV serving institutional clients. I did not run a survey; where their reported experience appears below, it is labeled as reported. Kriyo is my proposed solution to it.
01 · Research — the world & who’s stuck
A 15-year-old ISV, institutional clients, and a product so deep it ships with a YouTube series
The incumbent sells a data-management layer on top of Salesforce — a wrapper over the org’s own objects that streamlines jobs Salesforce technically supports but makes cumbersome: document merge against Contact and Account records, mass personalized email, bulk edit, dedupe. Its users are institutional organizations — nonprofits running campaigns over hundreds of thousands of Contacts — and the tooling predates the AI era by a decade.
The product is powerful and correspondingly deep. Operating it takes an explainer YouTube series, and in practice a Salesforce admin or solutions engineer in the loop for even small changes: a new report type, a new field mapping, a new team’s view. Salesforce lets you drill down feasibly; drilling up — a custom cross-object cut of your own org data — means someone builds Reports & Dashboards for you.
Archetype · illustrative
Pre-sales AE
Archetype · illustrative
Strategy / RevOps
Archetype · illustrative
Compliance analyst
Archetypes are illustrative composites of the team roles the insider described (pre-sales, strategy/product, compliance) — not interviewed individuals. No quotes here are verbatim.
02 · Problem framing
The first touch point is the whole problem: weeks of setup before a prospect sees one artifact
Before a prospect sees anything real, someone has to stand the product up in their org: connected-app auth, permission sets, field-level security, object mappings — work that lands on a Salesforce admin and was reported to take one to two weeks. Only then does the first usable artifact exist. Salespeople can’t show value on the first call, so evaluation stalls exactly where intent is highest.
The same tax recurs after the sale. Strategy, product, and compliance each need their own view of the org, and each view is another configuration project. The insider described the company converting users slowly and churning them quickly — while leaning on institutional clients for top line and trying to backfill with volumes of smaller ones. Churn has many causes I can’t claim to own; the first-touch-point delay is the one this product is aimed at.
Setup duration and churn pressure: as reported by the insider about their company; directional, not measured by me.
03 · Solution
Chat-as-interface: every conversation is a live, bookmarkable dashboard over the org
Kriyo inverts the interaction. Instead of chat describing data, the chat renders it: a prompt like “show me open pipeline by stage” is classified for intent, grounded in the org’s actual schema, compiled to SOQL, executed, and streamed back as a working dashboard — generative UI, not generated prose.
The rendering is deterministic by construction. The model can’t emit arbitrary HTML; it composes only components registered in a Zod-typed catalog (createCatalog — Card, Grid, Metric, Chart, Table, …) and binds them to data through JSON Pointer paths (/stats/amountSum, /charts/byStageName_Amount_sum). The catalog is the guardrail; the same registry renders every dashboard, so output quality doesn’t drift with the model’s mood.
Because each conversation persists its dashboard snapshot, every chat is a per-team interface: pre-sales bookmarks their pipeline view, compliance bookmarks theirs — customized by typing intent, not by filing an admin ticket. Filters and actions (apply_filter, export_report) are part of the catalog, so the artifacts stay interactive, not static charts. You can watch three of these conversations replay end-to-end in the live demo.
04 · MVP — live on this page
Not a screenshot: the production renderer, running here, on a canned org snapshot
The dashboard below is mounted by this page using the same DataProvider → Renderer stack and componentRegistry as the chat route. Its /stats and /charts bindings were computed by the production DataAnalyzer over the snapshot — the only difference from a live session is that the Salesforce round-trip is canned.
Open Pipeline by Stage
Pipeline value by stage
Expected close value by month
Matching records
SOQL result set, stitched and bound at /data/records
| Opportunity | Stage | Amount | Close date |
|---|---|---|---|
| Acme Nonprofit — Renewal | Negotiation | $185,000.00 | 7/24/2026 |
| Northwind Foundation — Expansion | Proposal | $120,000.00 | 8/5/2026 |
| Bluewater Trust — New Business | Qualification | $96,000.00 | 8/18/2026 |
| Helios Charities — Platform | Negotiation | $240,000.00 | 6/30/2026 |
| Cedar Grove Org — Pilot | Prospecting | $42,000.00 | 9/11/2026 |
| Lakeside Institute — Renewal | Proposal | $150,000.00 | 7/9/2026 |
| Summit Alliance — New Business | Qualification | $78,000.00 | 9/2/2026 |
| Harbor Point Fund — Expansion | Prospecting | $55,000.00 | 6/15/2026 |
componentRegistry and <Renderer /> — the UITree and data bindings are identical to what the Gemini generator streams as JSONL patches. Data is a canned demo-org snapshot; no Salesforce call leaves this page.In the repo today
Full org pipeline
describeGlobal / describeSObject, Gemini SOQL generation, multi-step QueryPlans with result stitching.In the repo today
Streaming generative UI
The end-to-end MVP — pipeline, streaming UI, chat routes — was built over one weekend, roughly six months before this page (repo inception Jan 16, 2026).
05 · Architecture
Every query runs inside the caller's own Salesforce permissions
A Salesforce org is not an open database. Each person who logs in sees a different slice of it, shaped by their profile, permission sets, sharing rules, and field-level security. So the pipeline builds every query against what the current user can actually reach. When they lack access to an object or field the dashboard needs, the answer is not a blank chart. It is a card that names the missing object, field, and permission, so they know exactly what to ask their admin for.
Prompt-level · Designed
Gemini only sees what you can
describe() results. Objects and fields they can’t reach never enter the prompt, so the model can’t ask for data the user isn’t allowed to see.Pre-flight · Partial
Catch it before the org does
soql-parser-js check (built) and a capability gate (planned) stop broken or unauthorized queries before they touch the org. When one fails, it fails with a reason we can show the user.Org-level · Implemented
Salesforce has the last word
FLS_VIOLATION is where the loop stops, not where it tries harder.When a query fails, the system reads why before deciding what to do. Every Salesforce error gets matched against a nine-class taxonomy in lib/salesforce/error-taxonomy.ts. A misspelled field and a governor-limit timeout are different problems, so they get different fixes: regenerate with the right field names, shrink the query, back off, or stop. Each class carries its own correction note into the next prompt, and the whole loop is capped at three tries against the org.
Here is exactly what retries, why, and how far:
| Error class | Trigger signature | Recovery action | Budget |
|---|---|---|---|
| NO_SUCH_FIELD / NO_SUCH_COLUMN | INVALID_FIELD, “No such column 'X'” | Regenerate with field-correction instruction: bind only to API names present in the schema context | ≤ 3 executions total |
| INVALID_RELATIONSHIP | “Didn’t understand relationship” | Regenerate with relationship guidance (__r suffix for custom, standard names for built-in) | ≤ 3 executions total |
| MALFORMED_QUERY | MALFORMED_QUERY, unbalanced syntax | Regenerate with SOQL syntax rules (quoting, date literals, no SQL JOIN/UNION) | ≤ 3 executions total |
| INVALID_TYPE | “sObject type not supported / not queryable” | Regenerate with exact object API name from schema context | ≤ 3 executions total |
| QUERY_TOO_COMPLICATED | Too many subqueries / SELECT fields | Regenerate with reduced complexity: fewer fields, simpler WHERE, explicit LIMIT | ≤ 3 executions total |
| GOVERNOR_LIMIT | QUERY_TIMEOUT, “too many query rows” | Regenerate with shrunk scope (LIMIT ≤ 50, narrower filters) — respects org limits instead of hammering them | ≤ 3 executions total |
| FLS_VIOLATION | INSUFFICIENT_ACCESS_OR_READONLY | Strip inaccessible fields once; Designed: surface an access-missing card — security denials are terminal, never brute-forced | 1 corrective pass, no loop |
| AI provider 429 | Gemini rate limit | Linear backoff, 4s × attempt, before regeneration | ≤ 3 generation calls |
| UNKNOWN | Anything unclassified | One generic semantic-review regeneration | ≤ 3 executions total |
CreatedDate with a LIMIT of 200. Either the user gets a dashboard or they get a reason. The org never gets pounded with retries.Scaling this to real enterprise load leans on patterns that predate AI: cache-aside for metadata, token-bucket rate limiting tied to the org’s API budget, circuit breakers and bulkheads per tenant, and retrieval to keep generation grounded.
Implemented
Cache-aside schema cache
describeGlobal bootstraps a relationship-linked schema graph once per instance, with a 24h TTL and explicit invalidation. The plan adds a shared L2 cache (Redis/Postgres) across instances, refreshed on Metadata-change events rather than waiting for the TTL to expire.Implemented
Retrieval keeps SOQL grounded
Designed
One session per person
Designed
One tenant can't starve another
Implemented
Narrow surfaces on purpose
Designed
Observability
The labels mean what they say. Implemented is in the repo now: the error taxonomy, tiered retries, parser pre-flight, schema cache, and few-shot store. Designed is the hardening plan, built on ordinary system-design practice: OAuth 2.0, cache-aside, token bucket, circuit breaker, bulkhead, and RAG-style retrieval.
06 · Metrics + GTM — proposed
What this is designed to move, and how it would reach users
No outcomes are claimed here — this is the instrumentation plan. Baselines are the reported status quo; targets are what the design is built to hit.
| Metric | Baseline (reported) | Target | Instrument |
|---|---|---|---|
| Time to first artifact | 1–2 weeks of admin setup (as reported) | Within the first call, on a demo org | Prompt → rendered-dashboard latency; pipeline step events |
| Activation | Deploy-then-evaluate; stalls pre-value | First saved dashboard in first session | Snapshot persistence events per conversation |
| Per-team self-serve views | Each team view = an admin config project | New view via prompt; zero admin tickets | Bookmarked conversations per team per week |
| Retention signal | Churn pressure (as reported, directional) | Weekly returning conversations per org | Repeat sessions on saved dashboards |
Proposed wedge
Land in the sales call
Proposed expansion
Grow per team
Proposed distribution
AppExchange path
GTM is a hypothesis attached to a proposed solution — a wedge argued from the reported problem, not a motion that has been run. The call-1 experience itself is reproducible right now in the demo.