@a1hvdy/cc-openclaw 0.27.0 → 0.27.1
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/dist/src/engines/base-oneshot-session.js +2 -0
- package/dist/src/engines/persistent-custom-session.js +3 -0
- package/dist/src/engines/persistent-session.d.ts +2 -0
- package/dist/src/engines/persistent-session.js +12 -0
- package/dist/src/session/watchdogs.d.ts +3 -1
- package/dist/src/session/watchdogs.js +8 -6
- package/dist/src/types.d.ts +6 -0
- package/package.json +1 -1
|
@@ -102,6 +102,8 @@ export class BaseOneShotSession extends EventEmitter {
|
|
|
102
102
|
isReady: this._isReady,
|
|
103
103
|
startTime: this._startTime,
|
|
104
104
|
lastActivity: this._stats.lastActivity,
|
|
105
|
+
// v0.27.x — oneshot engine doesn't separate progress; mirror lastActivity.
|
|
106
|
+
lastProgressAt: this._stats.lastActivity,
|
|
105
107
|
contextPercent: 0,
|
|
106
108
|
retries: 0,
|
|
107
109
|
sessionId: this.sessionId,
|
|
@@ -797,6 +797,9 @@ export class PersistentCustomSession extends EventEmitter {
|
|
|
797
797
|
isReady: this._isReady,
|
|
798
798
|
startTime: this._startTime,
|
|
799
799
|
lastActivity: this._stats.lastActivity,
|
|
800
|
+
// v0.27.x — custom engine doesn't separate progress from activity; mirror
|
|
801
|
+
// lastActivity so the shared watchdog behaves exactly as before for it.
|
|
802
|
+
lastProgressAt: this._stats.lastActivity,
|
|
800
803
|
contextPercent: this.engineConfig.persistent
|
|
801
804
|
? Math.min(100, Math.round(((this._stats.tokensIn + this._stats.tokensOut) / ctxWindow) * 100))
|
|
802
805
|
: 0,
|
|
@@ -25,6 +25,8 @@ interface InternalStats {
|
|
|
25
25
|
costUsd: number;
|
|
26
26
|
startTime: string | null;
|
|
27
27
|
lastActivity: string | null;
|
|
28
|
+
/** v0.27.x — last PROGRESS event ts (excludes api_retry); watchdog keys off it. */
|
|
29
|
+
lastProgressAt: string | null;
|
|
28
30
|
history: Array<{
|
|
29
31
|
time: string;
|
|
30
32
|
type: string;
|
|
@@ -58,6 +58,7 @@ export class PersistentClaudeSession extends EventEmitter {
|
|
|
58
58
|
costUsd: 0,
|
|
59
59
|
startTime: null,
|
|
60
60
|
lastActivity: null,
|
|
61
|
+
lastProgressAt: null,
|
|
61
62
|
history: [],
|
|
62
63
|
retries: 0,
|
|
63
64
|
lastRetryError: undefined,
|
|
@@ -346,6 +347,16 @@ export class PersistentClaudeSession extends EventEmitter {
|
|
|
346
347
|
_handleEvent(event) {
|
|
347
348
|
const type = event.type;
|
|
348
349
|
this.stats.lastActivity = new Date().toISOString();
|
|
350
|
+
// v0.27.x — progress signal for the stalled-session watchdog. Every event
|
|
351
|
+
// EXCEPT `system/api_retry` counts as progress. api_retry fires during an
|
|
352
|
+
// API retry-storm WITHOUT producing output; counting it as activity (as
|
|
353
|
+
// lastActivity does) defeated the watchdog — it never saw 180s of
|
|
354
|
+
// no-progress, so a stalled/retrying model call hung to the 900s envelope
|
|
355
|
+
// (the gateway's `recovery=none lastProgressAge=353s`). Keying the watchdog
|
|
356
|
+
// off lastProgressAt fast-fails it at the threshold instead.
|
|
357
|
+
const isApiRetry = type === 'system' && event.subtype === 'api_retry';
|
|
358
|
+
if (!isApiRetry)
|
|
359
|
+
this.stats.lastProgressAt = this.stats.lastActivity;
|
|
349
360
|
// Track history (keep last 100)
|
|
350
361
|
this.stats.history.push({ time: this.stats.lastActivity, type, event });
|
|
351
362
|
if (this.stats.history.length > MAX_HISTORY_ITEMS)
|
|
@@ -769,6 +780,7 @@ export class PersistentClaudeSession extends EventEmitter {
|
|
|
769
780
|
isReady: this._isReady,
|
|
770
781
|
startTime: this.stats.startTime,
|
|
771
782
|
lastActivity: this.stats.lastActivity,
|
|
783
|
+
lastProgressAt: this.stats.lastProgressAt,
|
|
772
784
|
// v0.6.0: contextPercent now reflects ACTUAL per-turn context occupancy
|
|
773
785
|
// (input + cache-read tokens from the last `result` event), not lifetime
|
|
774
786
|
// cumulative tokens. Pre-fix it saturated at 100% by turn 3 of any
|
|
@@ -22,9 +22,11 @@
|
|
|
22
22
|
export interface WatchdogManagedSession {
|
|
23
23
|
session: {
|
|
24
24
|
isBusy: boolean;
|
|
25
|
-
/** Returns at least { lastActivity }.
|
|
25
|
+
/** Returns at least { lastActivity, lastProgressAt }. The watchdog prefers
|
|
26
|
+
* lastProgressAt (excludes api_retry pings); other stats fields ignored. */
|
|
26
27
|
getStats(): {
|
|
27
28
|
lastActivity?: string | null | undefined;
|
|
29
|
+
lastProgressAt?: string | null | undefined;
|
|
28
30
|
};
|
|
29
31
|
stop(): void;
|
|
30
32
|
};
|
|
@@ -46,18 +46,20 @@ export function watchStalledSessions(opts) {
|
|
|
46
46
|
if (!managed.session.isBusy)
|
|
47
47
|
continue;
|
|
48
48
|
const stats = managed.session.getStats();
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
// v0.27.x — prefer the PROGRESS timestamp (real output: text/tool/result),
|
|
50
|
+
// which excludes `system/api_retry` pings. Keying off lastActivity let a
|
|
51
|
+
// retry-storm reset the clock forever so the watchdog never fired. Fall back
|
|
52
|
+
// to lastActivity, then the SessionManager wall-clock.
|
|
53
|
+
const progressIso = stats.lastProgressAt ?? stats.lastActivity;
|
|
54
|
+
const lastEventMs = progressIso ? new Date(progressIso).getTime() : managed.lastActivity;
|
|
53
55
|
const ageMs = now - lastEventMs;
|
|
54
56
|
if (ageMs <= thresholdMs)
|
|
55
57
|
continue;
|
|
56
|
-
opts.logger.warn(`[watchdog] killing stalled session ${name} (busy, no
|
|
58
|
+
opts.logger.warn(`[watchdog] killing stalled session ${name} (busy, no progress for ${Math.round(ageMs / 1000)}s, threshold=${Math.round(thresholdMs / 1000)}s)`);
|
|
57
59
|
try {
|
|
58
60
|
trajectory.emit('session_stalled_killed', {
|
|
59
61
|
ageMs,
|
|
60
|
-
|
|
62
|
+
lastProgressAt: progressIso,
|
|
61
63
|
thresholdMs,
|
|
62
64
|
model: managed.config.model,
|
|
63
65
|
cwd: managed.cwd,
|
package/dist/src/types.d.ts
CHANGED
|
@@ -184,6 +184,12 @@ export interface SessionStats {
|
|
|
184
184
|
isReady: boolean;
|
|
185
185
|
startTime: string | null;
|
|
186
186
|
lastActivity: string | null;
|
|
187
|
+
/** v0.27.x — wall-clock ISO of the last PROGRESS event (text / tool_use /
|
|
188
|
+
* tool_result / thinking / result / init) — i.e. the subprocess produced
|
|
189
|
+
* real output. Distinct from lastActivity, which also moves on non-progress
|
|
190
|
+
* events like `system/api_retry`. The stalled-session watchdog keys off this
|
|
191
|
+
* so an API retry-storm (no output) is fast-failed instead of looking busy. */
|
|
192
|
+
lastProgressAt: string | null;
|
|
187
193
|
/**
|
|
188
194
|
* Approximate context window utilization (0-100).
|
|
189
195
|
* Estimated as (tokensIn + tokensOut) / 200,000 * 100.
|