Make every text artifact that goes into Shira's system prompt editable from
the EspoCRM admin UI, with code-level defaults kept as a safety floor.
* AssistantRule + CaseMemory: flip `tab: true` so admins can browse/edit from
the navbar. No longer invisible.
* New entity AssistantPrompt — one row per prompt section (tool_rules,
writing_style, legal_assistance, personality_case, personality_office,
other_rules_case, other_rules_office). Edits in the UI override the
in-code defaults; an inactive or missing row falls back to code.
Seeded on install with the current Python defaults via AfterInstall.
* New entity UserProfile — replaces /opt/data/profiles/{uid}.md. ACL is
own/all/no so each lawyer sees their own, admins see all. Injected into
the prompt's '=== ABOUT THIS USER ===' block.
* New entity AssistantSkill — replaces /opt/data/skills/. Tab-visible.
Context provider returns metadata only; full body fetched on demand.
* 3 new ContextProviders (AssistantPrompt, UserProfile, AssistantSkill)
injected into context by SmartAssistantService::chat at the same point
AssistantRule has been injecting since 2026-05-27.
* 3 new Controller classes (one-liner extends Record) — without these
EspoCRM returns 404 on the REST endpoint even when scopes/entityDefs
are correct. Same pattern as the AssistantRule fix in 2.9.2.
* New custom view smart-assistant:views/fields/prompt-editor — monospace
font, dir=auto for mixed RTL/LTR, taller textarea. Used by all three
long-text content fields.
* New admin panel 'ניהול שירה' that groups all five surfaces (prompts,
rules, skills, user profiles, case memory) under one Admin section.
* Hebrew labels for all new scopes added to fa_IR/Global.json.
Paired with shira-hermes (separate commit): prompt_builder.py refactored
to read each section from context['assistantPrompts'] with code defaults
as fallback; save_memory tool now goes through SmartAssistant/action/executeTool
so CaseMemory actually gets populated instead of dropping 'm Notes.
Migration script scripts/migrate_legacy_memory_notes.py in shira-hermes
moves existing 'm Notes into CaseMemory rows (one-shot, idempotent).
Refs Task Master none — schema additions, no destructive changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The floating chat called Espo.Ajax.postRequest with timeout:180000, which is
shorter than the agentic loop's worst-case latency. On 2026-05-13 a prod
request to generate a direct-access report sat 227s in the first ai-gateway
iteration (large skill+context payload), so the browser fired the .catch()
handler at 180s and rendered "שגיאה בתקשורת" — even though the backend
completed the work 47s later (report attached to case 42).
Changes:
- floating-chat.js: timeout 180000 → 600000 (matches the PHP curl timeout
already set to 600s in SmartAssistantService.php:521).
- After 60s the spinner label swaps to a "still working" hint so the user
knows long requests are normal, not stuck.
- i18n: new SlowHint label in en_US + fa_IR (the project uses fa_IR as the
Hebrew slot).
Refs Task Master #3
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Long operations like generate_initial_report were completing successfully
but the frontend showed "communication error" due to AJAX timeout. Increased
CURL timeout to 180s and frontend AJAX timeout to 180s (3 minutes).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move "needs attention" tab to the right (first in RTL), make it active
by default, and move "open cases" to the left (last).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add delete_meeting, delete_call, delete_note tools for Shira.
Add expand/collapse toggle button to the floating chat window.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inset crop to avoid icon's rounded corners, pure blue background fills entire square.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Square avatar image (no circle mask) — CSS border-radius handles clipping
- Badge moved outside .sa-fab to separate wrapper, not clipped by overflow:hidden
- object-fit: cover ensures image fills entire circle
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Avatar image pre-cropped as circle with transparency
- Removed overflow:hidden from FAB so badge is not clipped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Shira executes all actions inline (create task, meeting, note) without approval buttons
- Actions work from both case and office mode (auto-resolves case from drill-down)
- Tasks/meetings can be created without a case parent
- Chat input is now multi-line textarea with auto-grow (Shift+Enter for new line)
- Markdown tables render as proper HTML tables with LRM marks for BiDi safety
- Robot icon replaced with Shira's avatar in FAB, chat header, and message bubbles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Shira speaks in feminine form (חושבת instead of חושב)
- Neutral verb forms for buttons (הוספת/חיפוש instead of הוסף/חפש)
- Updated fallback texts to reference שירה by name
- Description updated: AI Gateway integration replaces n8n
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When Shira creates a task, meeting, or other entity, the current
detail view panels now refresh automatically via model.trigger('update-all').
For tasks and meetings, also refreshes the activities/tasks side panels.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SmartRequest and SmartAction note views were missing data() method,
so {{post}} in the template resolved to empty string. Added proper
data() with escapeString formatting, consistent with SmartResponse.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
self was resolving to window.self instead of the View instance
inside the forEach callback, causing self.escapeString to fail.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace jQuery text escaping with EspoCRM's built-in View.escapeString()
to maintain consistency with the rest of the codebase.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Espo.Utils.escapeString does not exist in EspoCRM 8.x, causing
TypeError crash when clicking dashlet cards. Use jQuery .text().html()
for XSS-safe HTML escaping instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cards "תיקים פתוחים" and "דיונים השבוע" showed counts but clicking
revealed "אין פריטים להצגה" because card counts came from direct DB
queries while detail filtered from alerts with stricter criteria.
Added getOpenCaseItems() and getUpcomingHearingItems() to AlertCalculator,
included them in summary API response, and wired dashlet to use them.
Also: renamed extension to SmartAssistant, title to "שירה — עוזרת אישית".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move JS from client/custom/src/modules/{mod}/ to client/custom/modules/{mod}/src/
Move TPL to client/custom/modules/{mod}/res/templates/
Update all define(), createView(), and metadata references from
custom:modules/{mod}/... to modules/{mod}/...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>