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>
This commit is contained in:
@@ -103,17 +103,68 @@ define('modules/knowledge-base/views/kb/index', ['view'], function (Dep) {
|
||||
|
||||
runAsk: function (message) {
|
||||
this.setLoading(true);
|
||||
this.startAskProgress();
|
||||
// Ask goes through the full agent loop (search + rerank + LLM),
|
||||
// which routinely takes 30-90s. The default jQuery Ajax timeout
|
||||
// is too short; override it here so the browser doesn't give up
|
||||
// before shira-hermes responds.
|
||||
Espo.Ajax.postRequest('KnowledgeBase/action/ask', {
|
||||
message: message,
|
||||
}).then(res => {
|
||||
}, {timeout: 240000}).then(res => {
|
||||
this.stopAskProgress();
|
||||
this.setLoading(false);
|
||||
this.renderAskAnswer(res.text || '');
|
||||
}).catch(err => {
|
||||
this.stopAskProgress();
|
||||
this.setLoading(false);
|
||||
this.showError(err);
|
||||
});
|
||||
},
|
||||
|
||||
startAskProgress: function () {
|
||||
// Show a live elapsed-time indicator so users know the request
|
||||
// is still running rather than stuck. Typical answers arrive in
|
||||
// 30-90s; we warn after 2 minutes.
|
||||
if (this.mode !== 'ask') return;
|
||||
const $results = this.$el.find('.kb-results');
|
||||
$results.html(
|
||||
'<div class="kb-ask-progress panel panel-info">' +
|
||||
' <div class="panel-body" style="direction:rtl;text-align:right;">' +
|
||||
' <i class="fas fa-circle-notch fa-spin" style="margin-left:8px;"></i>' +
|
||||
' <strong>שירה חושבת…</strong>' +
|
||||
' <div class="small text-muted" style="margin-top:6px;">' +
|
||||
' שירה מחפשת בבסיס הידע, מסכמת ומציגה ציטוטים מדויקים.' +
|
||||
' זה יכול לקחת בין 30 ל-90 שניות.' +
|
||||
' </div>' +
|
||||
' <div class="small" style="margin-top:10px;">' +
|
||||
' <span>זמן שעבר: </span>' +
|
||||
' <span class="kb-elapsed">0</span>' +
|
||||
' <span> שניות</span>' +
|
||||
' </div>' +
|
||||
' </div>' +
|
||||
'</div>'
|
||||
);
|
||||
const startedAt = Date.now();
|
||||
this._askTimer = setInterval(() => {
|
||||
const sec = Math.round((Date.now() - startedAt) / 1000);
|
||||
const $elapsed = this.$el.find('.kb-elapsed');
|
||||
if ($elapsed.length) $elapsed.text(sec);
|
||||
if (sec === 120) {
|
||||
this.$el.find('.kb-ask-progress .panel-body').append(
|
||||
'<div class="alert alert-warning" style="margin-top:10px;">' +
|
||||
'לוקח יותר זמן מהרגיל. עדיין ממתינים…</div>'
|
||||
);
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
stopAskProgress: function () {
|
||||
if (this._askTimer) {
|
||||
clearInterval(this._askTimer);
|
||||
this._askTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
renderSearchResults: function (hits) {
|
||||
const $results = this.$el.find('.kb-results');
|
||||
if (!hits.length) {
|
||||
@@ -260,7 +311,11 @@ define('modules/knowledge-base/views/kb/index', ['view'], function (Dep) {
|
||||
const $btn = this.$el.find('[data-action="submit"]');
|
||||
if (loading) {
|
||||
$btn.prop('disabled', true).text(this.translate('Loading', 'labels'));
|
||||
this.$el.find('.kb-results').html('<div class="text-muted">מחפש…</div>');
|
||||
// Only overwrite results with "מחפש…" for search. For ask,
|
||||
// startAskProgress() renders a richer progress panel.
|
||||
if (this.mode !== 'ask') {
|
||||
this.$el.find('.kb-results').html('<div class="text-muted">מחפש…</div>');
|
||||
}
|
||||
} else {
|
||||
$btn.prop('disabled', false).text(this.getSubmitLabel());
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "KnowledgeBase",
|
||||
"module": "KnowledgeBase",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"acceptableVersions": [
|
||||
">=8.0.0"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user