Three issues from the v0.2.0 user test:
1. Sides flipped relative to expectation
In our Hebrew/RTL CRM the user reads primary content (the answer or
the hit list) on the visual right and the supporting reference
(the PDF) on the visual left — that's how Hebrew layouts stage
"main + sidebar". v0.1.10's _buildSplitShell forced direction:ltr on
the splitter container (correct, for mouseX math) but laid the
children in the order [primary, handle, reference], which under LTR
put primary on the LEFT and PDF on the RIGHT. Fixed by renaming the
helper params to {primaryHtml, referenceHtml} and ordering the
children as [reference, handle, primary] — visual LEFT is now the
PDF, visual RIGHT is the answer/list. Default split moved from 42%
to 58% so the reference pane (now on the left) keeps the same
absolute width the PDF column had under v0.1.9's bootstrap rows.
2. No way to start a new query
afterRender replays _lastSearch / _lastAsk on every remount, which
means the prior result hangs around forever. Added a "חיפוש חדש" /
"שאלה חדשה" button next to the submit button. clearResults() cancels
any in-flight request (closes the EventSource for ask, drops
_activeSearch reference for search), removes the cached entry from
sessionStorage, empties the results pane, and refocuses the input.
3. Stale results from another session
Cached results now auto-expire after 30 minutes — _loadJson checks
completedAt against STALE_AFTER_MS and silently drops anything
older. So coming back tomorrow the KB tab opens clean instead of
showing yesterday's answer to whatever you asked then.
Refs Task Master #4, #6
KnowledgeBase extension for EspoCRM: UI on top of the shira-hermes KB of
Israeli National Insurance law, regulations, and circulars.
Three modes:
- חיפוש — Hybrid (pgvector + tsvector) + Voyage rerank-2.5, returns ranked
chunks with heading_path and citations.
- שאל את שירה — Full agent loop; Shira picks up search_insurance_kb as
needed and returns a summary with citations.
- עיון — Browse all active sources. Click a source:
- PDF source (ספר הליקויים, ספר המבחנים, circulars): renders the
original PDF inline via an iframe proxied through the
KnowledgeBasePdf EntryPoint, so the layout/columns/tables are
preserved and Ctrl+F works natively.
- TXT source (חוק הביטוח הלאומי scraped from Wikisource): falls back
to the hierarchical chunk list with RTL styling.
Architecture:
- Controller: KnowledgeBase.php — thin proxy to shira-hermes /kb/*.
- Service: KnowledgeBaseService.php — shared curl plumbing; derives the
shira-hermes base URL from the SmartAssistant integration record so
there is no second admin config.
- EntryPoint: KnowledgeBasePdf.php — streams the PDF inline, wraps the
body in a php://temp stream for setBody, applies a locked-down CSP.
- JS: views/kb/index.js branches on source.original_path; modes wired
through the SmartAssistant fa_IR i18n convention.
Auth model:
- Browser → EspoCRM: session cookie / X-Api-Key (EspoCRM's existing auth).
- EspoCRM → shira-hermes: X-Api-Key from the SmartAssistant integration
(never exposed to the browser).
- Portal users are blocked at both the Controller and the EntryPoint.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>