@yeaft/webchat-agent 1.0.668 → 1.0.669
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +96 -94
- package/local-runtime/web/app.bundle.js.gz +0 -0
- package/local-runtime/web/index.html +2 -2
- package/local-runtime/web/style.bundle.css +1 -1
- package/local-runtime/web/style.bundle.css.gz +0 -0
- package/package.json +1 -1
- package/yeaft/sessions/scheduled-task-scheduler.js +7 -0
- package/yeaft/web-bridge.js +41 -4
|
Binary file
|
package/package.json
CHANGED
|
@@ -181,6 +181,13 @@ export class ScheduledTaskScheduler {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
observe(sessionId, event) {
|
|
184
|
+
// Stop can arrive before boot/classification creates any VP turn controller
|
|
185
|
+
// or terminal event. Retire those claims once their ingress has drained.
|
|
186
|
+
if (event.type === 'yeaft_aborted' && event.all) {
|
|
187
|
+
for (const [id, active] of this.runs) {
|
|
188
|
+
if (!sessionId || id === sessionId) active.interrupted = true;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
184
191
|
const active = this.runs.get(sessionId);
|
|
185
192
|
if (!active) return;
|
|
186
193
|
if (event.type === 'error') active.error = event.message || event.error?.message || String(event.error || 'Execution failed');
|
package/yeaft/web-bridge.js
CHANGED
|
@@ -510,6 +510,36 @@ const vpAborts = new Map();
|
|
|
510
510
|
*/
|
|
511
511
|
const sessionCopyEpochs = new Map();
|
|
512
512
|
const modelReentryActivity = new Map();
|
|
513
|
+
// Pending ingress has no VP AbortController yet. Keep per-request tokens so
|
|
514
|
+
// Stop fences existing boot/classification awaits, not later inputs in the
|
|
515
|
+
// same activity epoch (or inputs belonging to another Session).
|
|
516
|
+
const pendingSessionIngress = new Map();
|
|
517
|
+
|
|
518
|
+
function beginSessionIngress(sessionId) {
|
|
519
|
+
let pending = pendingSessionIngress.get(sessionId);
|
|
520
|
+
if (!pending) {
|
|
521
|
+
pending = new Set();
|
|
522
|
+
pendingSessionIngress.set(sessionId, pending);
|
|
523
|
+
}
|
|
524
|
+
const ingress = {
|
|
525
|
+
cancelled: false,
|
|
526
|
+
release() {
|
|
527
|
+
pending.delete(ingress);
|
|
528
|
+
if (pending.size === 0 && pendingSessionIngress.get(sessionId) === pending) {
|
|
529
|
+
pendingSessionIngress.delete(sessionId);
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
};
|
|
533
|
+
pending.add(ingress);
|
|
534
|
+
return ingress;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function cancelSessionIngress(sessionId = null) {
|
|
538
|
+
for (const [id, pending] of pendingSessionIngress) {
|
|
539
|
+
if (sessionId && id !== sessionId) continue;
|
|
540
|
+
for (const ingress of pending) ingress.cancelled = true;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
513
543
|
|
|
514
544
|
function hasSessionRuntimeWork(sessionId) {
|
|
515
545
|
const prefix = `${sessionId}::`;
|
|
@@ -2273,14 +2303,16 @@ function scheduleTaskResultReentry(event) {
|
|
|
2273
2303
|
|
|
2274
2304
|
async function routeEnvelopeToVpThread(sessionId, vpId, envelope) {
|
|
2275
2305
|
const releaseActivity = beginSessionActivity(sessionId);
|
|
2306
|
+
const ingress = beginSessionIngress(sessionId);
|
|
2276
2307
|
try {
|
|
2277
|
-
return await routeActiveEnvelopeToVpThread(sessionId, vpId, envelope);
|
|
2308
|
+
return await routeActiveEnvelopeToVpThread(sessionId, vpId, envelope, ingress);
|
|
2278
2309
|
} finally {
|
|
2310
|
+
ingress.release();
|
|
2279
2311
|
releaseActivity();
|
|
2280
2312
|
}
|
|
2281
2313
|
}
|
|
2282
2314
|
|
|
2283
|
-
async function routeActiveEnvelopeToVpThread(sessionId, vpId, envelope) {
|
|
2315
|
+
async function routeActiveEnvelopeToVpThread(sessionId, vpId, envelope, ingress) {
|
|
2284
2316
|
const routeStart = perfNowMs();
|
|
2285
2317
|
const { text, prompt, promptParts } = buildVpPromptPayload(vpId, envelope);
|
|
2286
2318
|
const runningThreads = getRunningThreads(sessionId, vpId);
|
|
@@ -2313,6 +2345,7 @@ async function routeActiveEnvelopeToVpThread(sessionId, vpId, envelope) {
|
|
|
2313
2345
|
// promise would leave it visible in history without ever starting a turn.
|
|
2314
2346
|
console.warn('[Yeaft] VP thread classification failed; starting a new thread:', err?.message || err);
|
|
2315
2347
|
}
|
|
2348
|
+
if (ingress.cancelled) return null;
|
|
2316
2349
|
const targetIsRunning = decision
|
|
2317
2350
|
? runningThreads.some((t) => t.threadId === decision.targetThreadId)
|
|
2318
2351
|
: false;
|
|
@@ -5214,22 +5247,25 @@ async function runYeaftSessionSend(msg) {
|
|
|
5214
5247
|
traceDuration('session_send.open_session', openSessionStart, { ok: !!sessionHandle });
|
|
5215
5248
|
|
|
5216
5249
|
const releaseActivity = beginSessionActivity(sessionId);
|
|
5250
|
+
const ingress = beginSessionIngress(sessionId);
|
|
5217
5251
|
try {
|
|
5218
5252
|
return await dispatchAcceptedSessionSend({
|
|
5219
|
-
msg, text, mentions, quote, sessionId, yeaftDir, perfTraceId, perfStart,
|
|
5253
|
+
msg, text, mentions, quote, sessionId, yeaftDir, perfTraceId, perfStart, ingress,
|
|
5220
5254
|
tracePerf, traceDuration, turnConfig, sessionHandle, sessionRoot, sessionMetaForRuntime,
|
|
5221
5255
|
});
|
|
5222
5256
|
} finally {
|
|
5257
|
+
ingress.release();
|
|
5223
5258
|
releaseActivity();
|
|
5224
5259
|
}
|
|
5225
5260
|
}
|
|
5226
5261
|
|
|
5227
5262
|
async function dispatchAcceptedSessionSend({
|
|
5228
|
-
msg, text, mentions, quote, sessionId, yeaftDir, perfTraceId, perfStart,
|
|
5263
|
+
msg, text, mentions, quote, sessionId, yeaftDir, perfTraceId, perfStart, ingress,
|
|
5229
5264
|
tracePerf, traceDuration, turnConfig, sessionHandle, sessionRoot, sessionMetaForRuntime,
|
|
5230
5265
|
}) {
|
|
5231
5266
|
const ensureSessionStart = perfNowMs();
|
|
5232
5267
|
await ensureSessionLoaded({ sessionMeta: sessionMetaForRuntime, perfTraceId });
|
|
5268
|
+
if (ingress.cancelled) return;
|
|
5233
5269
|
// Runtime boot may await I/O. Re-read the claim immediately before ingress
|
|
5234
5270
|
// so edits, disable, archive or deletion during boot cannot execute stale work.
|
|
5235
5271
|
msg[SCHEDULED_TASK_DISPATCH_GUARD]?.();
|
|
@@ -6742,6 +6778,7 @@ export function handleYeaftAbortThread(_msg = {}) {
|
|
|
6742
6778
|
export function handleYeaftAbortAll(msg = {}) {
|
|
6743
6779
|
const sessionId = typeof msg.sessionId === 'string' && msg.sessionId ? msg.sessionId : null;
|
|
6744
6780
|
const aborted = [];
|
|
6781
|
+
cancelSessionIngress(sessionId);
|
|
6745
6782
|
if (!sessionId && currentAbortCtrl && !currentAbortCtrl.signal.aborted) {
|
|
6746
6783
|
try { currentAbortCtrl.abort(); aborted.push('main'); } catch { /* best-effort */ }
|
|
6747
6784
|
}
|