Spaces:
Sleeping
Sleeping
Commit ·
1fec525
1
Parent(s): 3bcc2b8
fixed ui bug
Browse files- ui/index.html +17 -14
ui/index.html
CHANGED
|
@@ -358,6 +358,11 @@
|
|
| 358 |
================================================================ -->
|
| 359 |
<script>
|
| 360 |
function orgos() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
return {
|
| 362 |
// ---- Config ----
|
| 363 |
envUrl: window.location.origin,
|
|
@@ -411,9 +416,6 @@
|
|
| 411 |
// ---- Log ----
|
| 412 |
actionLog: [],
|
| 413 |
|
| 414 |
-
// ---- SSE handle ----
|
| 415 |
-
_sse: null,
|
| 416 |
-
_chart: null,
|
| 417 |
scoreUpdated: false,
|
| 418 |
|
| 419 |
// ----------------------------------------------------------------
|
|
@@ -421,7 +423,7 @@
|
|
| 421 |
// ----------------------------------------------------------------
|
| 422 |
async init() {
|
| 423 |
await this.checkHealth();
|
| 424 |
-
|
| 425 |
// Poll health every 10s
|
| 426 |
setInterval(() => this.checkHealth(), 10_000);
|
| 427 |
},
|
|
@@ -470,23 +472,23 @@
|
|
| 470 |
if (this.isRunning) return;
|
| 471 |
this.isRunning = true;
|
| 472 |
const url = `${this.envUrl}/ui/run-agent?workflow_id=${this.selectedWorkflow}`;
|
| 473 |
-
|
| 474 |
-
|
| 475 |
try {
|
| 476 |
const evt = JSON.parse(e.data);
|
| 477 |
this._handleSSEEvent(evt);
|
| 478 |
} catch {}
|
| 479 |
};
|
| 480 |
-
|
| 481 |
this.isRunning = false;
|
| 482 |
-
|
| 483 |
this._pushLog({ type: 'error', step: this.stepCount, message: 'SSE connection error.' });
|
| 484 |
};
|
| 485 |
},
|
| 486 |
|
| 487 |
stopAgent() {
|
| 488 |
this.isRunning = false;
|
| 489 |
-
if (
|
| 490 |
},
|
| 491 |
|
| 492 |
_handleSSEEvent(evt) {
|
|
@@ -523,13 +525,14 @@
|
|
| 523 |
});
|
| 524 |
if (evt.done) { this.isRunning = false; }
|
| 525 |
} else if (evt.type === 'done') {
|
| 526 |
-
this.isRunning = false;
|
| 527 |
this._pushLog({
|
| 528 |
type: 'info', step: evt.steps,
|
| 529 |
message: `Episode done. Final score: ${(evt.final_score||0).toFixed(4)} | Workflow complete: ${evt.completed}`,
|
| 530 |
});
|
|
|
|
| 531 |
} else if (evt.type === 'error') {
|
| 532 |
this._pushLog({ type: 'error', step: evt.step || this.stepCount, message: evt.message });
|
|
|
|
| 533 |
}
|
| 534 |
},
|
| 535 |
|
|
@@ -637,11 +640,11 @@
|
|
| 637 |
},
|
| 638 |
|
| 639 |
_updateChart() {
|
| 640 |
-
if (!
|
| 641 |
const labels = this.rewardHistory.map((_, i) => i + 1);
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
|
| 645 |
},
|
| 646 |
};
|
| 647 |
}
|
|
|
|
| 358 |
================================================================ -->
|
| 359 |
<script>
|
| 360 |
function orgos() {
|
| 361 |
+
// Non-reactive handles — kept outside Alpine's Proxy to avoid
|
| 362 |
+
// deep-traversal stack overflows on complex objects (Chart.js, EventSource).
|
| 363 |
+
let _chartInst = null;
|
| 364 |
+
let _sseInst = null;
|
| 365 |
+
|
| 366 |
return {
|
| 367 |
// ---- Config ----
|
| 368 |
envUrl: window.location.origin,
|
|
|
|
| 416 |
// ---- Log ----
|
| 417 |
actionLog: [],
|
| 418 |
|
|
|
|
|
|
|
|
|
|
| 419 |
scoreUpdated: false,
|
| 420 |
|
| 421 |
// ----------------------------------------------------------------
|
|
|
|
| 423 |
// ----------------------------------------------------------------
|
| 424 |
async init() {
|
| 425 |
await this.checkHealth();
|
| 426 |
+
_chartInst = this._initChart();
|
| 427 |
// Poll health every 10s
|
| 428 |
setInterval(() => this.checkHealth(), 10_000);
|
| 429 |
},
|
|
|
|
| 472 |
if (this.isRunning) return;
|
| 473 |
this.isRunning = true;
|
| 474 |
const url = `${this.envUrl}/ui/run-agent?workflow_id=${this.selectedWorkflow}`;
|
| 475 |
+
_sseInst = new EventSource(url);
|
| 476 |
+
_sseInst.onmessage = (e) => {
|
| 477 |
try {
|
| 478 |
const evt = JSON.parse(e.data);
|
| 479 |
this._handleSSEEvent(evt);
|
| 480 |
} catch {}
|
| 481 |
};
|
| 482 |
+
_sseInst.onerror = () => {
|
| 483 |
this.isRunning = false;
|
| 484 |
+
if (_sseInst) { _sseInst.close(); _sseInst = null; }
|
| 485 |
this._pushLog({ type: 'error', step: this.stepCount, message: 'SSE connection error.' });
|
| 486 |
};
|
| 487 |
},
|
| 488 |
|
| 489 |
stopAgent() {
|
| 490 |
this.isRunning = false;
|
| 491 |
+
if (_sseInst) { _sseInst.close(); _sseInst = null; }
|
| 492 |
},
|
| 493 |
|
| 494 |
_handleSSEEvent(evt) {
|
|
|
|
| 525 |
});
|
| 526 |
if (evt.done) { this.isRunning = false; }
|
| 527 |
} else if (evt.type === 'done') {
|
|
|
|
| 528 |
this._pushLog({
|
| 529 |
type: 'info', step: evt.steps,
|
| 530 |
message: `Episode done. Final score: ${(evt.final_score||0).toFixed(4)} | Workflow complete: ${evt.completed}`,
|
| 531 |
});
|
| 532 |
+
this.stopAgent(); // close EventSource — prevents auto-reconnect
|
| 533 |
} else if (evt.type === 'error') {
|
| 534 |
this._pushLog({ type: 'error', step: evt.step || this.stepCount, message: evt.message });
|
| 535 |
+
this.stopAgent(); // close EventSource on error too — prevents reconnect loop
|
| 536 |
}
|
| 537 |
},
|
| 538 |
|
|
|
|
| 640 |
},
|
| 641 |
|
| 642 |
_updateChart() {
|
| 643 |
+
if (!_chartInst) return;
|
| 644 |
const labels = this.rewardHistory.map((_, i) => i + 1);
|
| 645 |
+
_chartInst.data.labels = labels;
|
| 646 |
+
_chartInst.data.datasets[0].data = this.rewardHistory;
|
| 647 |
+
_chartInst.update('none');
|
| 648 |
},
|
| 649 |
};
|
| 650 |
}
|