Skip to content

Developer notes

question ─► limits, injection check, order intent
─► embedding of the question (AI service)
─► similarity search in PHP over ?:kv_aisa_sketches / ?:kv_aisa_chunks
─► live product data (fn_get_products + fn_gather_additional_products_data)
─► prompt: rules + store instructions + numbered sources + last 6 messages
─► chat completion (AI service)
─► checks: [[NO_ANSWER]] / [[OFF_TOPIC]] markers, product tags, price check
─► answer + product cards, stored conversation, knowledge gap
  • Embeddings are unit-normalised and stored as base64 float32 (?:kv_aisa_chunks.vec), so cosine similarity is a dot product.
  • A 64-dimension seeded random projection of every vector is stored in the narrow table ?:kv_aisa_sketches. Up to 4,000 chunks in scope every vector is compared exactly; above that, the sketches are scanned in keyset pages of 5,000 rows and the best max(300, chunks / 120) are compared exactly.
  • Product chunks contain name, categories, vendor, code, features, variation features, options, descriptions and (optional) review texts, never price or stock.
  • Chunks are about 900 characters along paragraph and sentence boundaries with a 120-character overlap; every chunk starts with its source line (for example Product: Name).

Measured with PHP 8.3, MariaDB 11.4, 768-dimension vectors, 10 queries each (recall@6 = share of the top 6 of a full exact scan that the search returned):

Chunks in scope Mode Average search time Memory Recall@6
3,900 exact 0.19 s 51 MB 100%
20,400 pre-filter 0.17 s 6 MB 100%
50,400 pre-filter 0.44 s 6 MB 100%
100,400 pre-filter 0.97 s 11 MB 100%

The search time grows linearly with the number of chunks. Embedding and chat calls of the AI service add their own latency (with a local GPU model in our test: 0.2–3 s per answer).

Table Contents
kv_aisa_config Connection settings, encrypted API keys (fn_encrypt_text), cron key, run marks
kv_aisa_docs One row per source (type + id), text hash, model, chunk count, status
kv_aisa_chunks Chunk text and vector
kv_aisa_sketches Pre-filter vectors (narrow table)
kv_aisa_queue Sources waiting for the sync
kv_aisa_files Uploaded documents (extracted text only)
kv_aisa_faq FAQ entries
kv_aisa_conversations, kv_aisa_messages History, ratings, flags, tokens, cost
kv_aisa_gaps Unanswered questions grouped by normalised text
kv_aisa_usage Daily requests, tokens and cost per kind (chat, embed)
kv_aisa_rate Rate-limit windows (salted IP hashes)
kv_aisa_codes One-time order codes (HMAC, 10 minutes)
kv_aisa_vendors Per-vendor switch (Multi-Vendor)

dispatch_before_display (widget configuration), update_product_post, delete_product_post, update_page_post, delete_page (sync queue), delete_company (vendor data). The arguments are identical in 4.17.2 and 4.21.2. Storefront template hook: index:footer (post). E-mail template: kv_ai_shopping_assistant_code (Twig, valid in Twig 2 and 3).

  • Storefront kv_ai_shopping_assistant.chat|history|rate|orders|order_code|order_verify (POST, JSON) and .cron (GET with key).
  • Admin kv_ai_shopping_assistant.manage|connection|knowledge|faq_update|conversations|conversation|gaps|vendors, AJAX sync_step, test_connection, preview; console php admin.php --dispatch=kv_ai_shopping_assistant.cron [--reconcile=1].
  • Vendor panel: vendor, vendor_toggle, faq_update, faq_delete, file_upload, file_delete (ownership checked).

define('KV_AISA_MAIL_CAPTURE', '/path/mail.log'); in config.local.php of a development store renders the order code e-mail with the real template and appends it to that file instead of sending it.

Designed for it, not yet tested with the full page cache switched on. The index:footer output depends only on the settings and the page (vendor of the product shown), never on the visitor. The conversation token lives in localStorage; every request is an AJAX POST to the add-on’s controller.

Tygh\Addons\KvAiShoppingAssistant\License\Client (domain-bound). Gated: the storefront widget and all its requests, the HTTP cron and the knowledge base sync. Kept: admin pages and all data.

Ideas for later versions, not part of 1.0: an assistant for staff inside the admin panel (orders, products, reports), a knowledge base built from more than one storefront language, and voice input in the widget.

app/addons/kv_ai_shopping_assistant/
addon.xml init.php func.php
controllers/frontend/kv_ai_shopping_assistant.php storefront JSON + HTTP cron
controllers/backend/kv_ai_shopping_assistant.php admin and vendor pages, console cron
controllers/backend/kv_ai_shopping_assistant_license.php
schemas/menu/{menu,menu_vendor,actions}.post.php
schemas/permissions/{admin,vendor_multivendor}.post.php
Tygh/Addons/KvAiShoppingAssistant/
Ai.php AiException.php OpenAI-compatible client (OpenAI, Azure, others)
Assistant.php answer pipeline
Retriever.php Vector.php similarity search
Indexer.php Sources.php Text.php Pdf.php Files.php Faq.php
Catalog.php live product data
Orders.php order status lookup
Guard.php Usage.php Gaps.php Stats.php Vendors.php Housekeeping.php Storefront.php Config.php Db.php
License/ Upgrade/
design/backend/templates/addons/kv_ai_shopping_assistant/ admin pages, license card
var/themes_repository/responsive/templates/addons/kv_ai_shopping_assistant/hooks/index/footer.post.tpl
js/addons/kv_ai_shopping_assistant/{func.js,admin.js}