3 Commits

Author SHA1 Message Date
chaim 243ae2353f feat(kb): split-view PDF jump-to-page for both ask and search modes
Search and ask modes now render results as a two-column layout: a left
column with ranked hit cards (search) or Shira's answer + source picker
(ask), and a right column with an iframe showing the source PDF scrolled
to page_number. Clicking a hit (search) or source pill (ask) swaps the
iframe's src, so users can verify a quote against the original PDF
without leaving the KB tab.

- search: renderSearchResults lays out results as panel cards on the
  left (with kind + title + section + "עמ׳ N" label); the top hit is
  pre-selected and its PDF loads on the right. Clicking any card
  re-highlights it and swaps the preview. Law-kind hits (Wikisource
  text) gracefully fall back to a chunk-text panel with a Wikisource
  link so the right pane never 404s on a text source.
- ask: renderAskAnswer dedups /kb/ask's sources[] by source_id,
  collects all cited pages per source, and renders a picker row plus
  per-source page-jump buttons. First source's first page loads on
  initial render; buttons swap the iframe without re-running the query.

Depends on shira-hermes commits e534709 + 1ca1cc0 (chunker page_number
propagation + null-byte strip) — without them, every PDF collapses to
page 1 in the DB and the jump links are cosmetic.

Refs Task Master #1
2026-04-24 15:49:29 +00:00
chaim 34ad5cd023 feat(ask): progress panel + 240s ajax timeout
The ask mode goes through the full agent loop (hybrid search + rerank +
Claude). Typical runs land at 30-90s; long queries reach 90-120s. With
the previous UX the user saw only "Loading…" on the submit button and
"מחפש…" in the results area — indistinguishable from a stuck request.

- Render a dedicated progress panel on ask with a spinner, a description
  of what shira is doing, and a live elapsed-seconds counter.
- After 2 minutes, append a "taking longer than usual" warning so users
  know the request is still running.
- Override Espo.Ajax timeout to 240s; jQuery's default (undefined) or
  EspoCRM's request-level default would kill the browser request well
  before shira finishes on a cold cache.
- Version 0.1.7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:06:29 +00:00
chaim 8829a2e93a feat: KnowledgeBase extension v0.1.6 — inline PDF viewer in browse tab
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>
2026-04-24 11:57:23 +00:00