Ivan Savchenko
← All demos
CRM Copilot

AI inside a product needs the same permissions as the user

LLM features added to an existing multi-tenant SaaS app, done safely.

0
SQL written by the model
115
tests in 13 files
Zod
tool inputs and structured outputs are schema-validated
0/2
runs where the free Nemotron NL filter was right (schema-valid, but incomplete)
Interactive demo

Talk to the copilot

Try the presets or type your own command. Notice what it refuses to do.

A small browser version with a deterministic fake model — no API key, nothing leaves your device. The real project is in the repo.

What it solves

Most companies asking for “AI in our product” already have a product: a database, accounts and permissions. A chatbot pasted on top can know things it should not.

How it works

  1. The copilot calls only seven typed tools (four read, three propose-only write), each scoped in code to the signed-in user's workspace. It never writes SQL.
  2. It never writes on its own: it proposes a change, the user sees a before/after diff and approves it. On approval the server re-checks ownership, expiry (15 minutes by default) and that the record has not changed since.
  3. Tool inputs and structured outputs (emails, summaries, filters) are validated against a Zod schema. Per-workspace rate limits are enforced; tokens, estimated cost and latency are logged for every request.

The honest verdict

The AI gets the signed-in user's workspace and identity scope — not more (the demo has no roles yet). A malformed answer becomes a clean error, not a broken page; a well-formed but wrong one does not: a free model (Nemotron) returned a schema-valid but incomplete filter in both runs. Model comparison of 2026-10-12, one run per model (20 chat cases, 14 filter requests, 5 emails, 5 summaries): chat Haiku 18/20 (20/20 on a re-run after one rule was loosened), Opus 20/20, Qwen 19/20; filters Haiku 14/14, Opus 12/14 (both misses came from the gateway's strict JSON-schema mode, checked with one probe call each), Qwen 13/14. Emails are the weak spot: judged faithful 1 of 5 for Haiku, 4 of 5 for Opus, 3 of 5 for Qwen, with Opus judging all of them including its own output. Samples are small: a direction, not a measurement.

TypeScriptNext.jsNestJSPrisma
Next demoDocExtract →