openclaw-scheduler 0.2.10 → 0.2.11
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/CHANGELOG.md +6 -0
- package/dispatch/completion.mjs +1 -0
- package/dispatch/watcher.mjs +28 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.11] -- 2026-06-23
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- fix(dispatch): clarify that completion markers must run in the originating local dispatch shell, and allow watcher delivery from clean terminal `stop_reason=end_turn` replies without broadening plain `lastReply` success detection
|
|
9
|
+
- fix(watcher): use the fatal idle threshold for stalled-session errors while keeping quiet high-thinking sessions pending at the probe threshold
|
|
10
|
+
|
|
5
11
|
## [0.2.5] -- 2026-04-27
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/dispatch/completion.mjs
CHANGED
|
@@ -1134,6 +1134,7 @@ export function buildCompletionSignalInstructions({ label, taskPrompt, doneScrip
|
|
|
1134
1134
|
readinessChecks.forEach((line, idx) => lines.push(` ${idx + 1}. ${line}`));
|
|
1135
1135
|
lines.push('');
|
|
1136
1136
|
lines.push('Call this as your ABSOLUTE FINAL action -- nothing else runs after this:');
|
|
1137
|
+
lines.push(' IMPORTANT: run this command in the dispatch session shell on this host. Do not run it inside ssh, docker, tmux, or any remote shell; remote label stores cannot mark this dispatch complete.');
|
|
1137
1138
|
lines.push(` node '${doneScriptPath}' done --label '${escapedLabel}' \\`);
|
|
1138
1139
|
lines.push(' --summary "<human-readable summary of what you actually did>" \\');
|
|
1139
1140
|
lines.push(` --checklist '${checklistExample}' \\`);
|
package/dispatch/watcher.mjs
CHANGED
|
@@ -1052,6 +1052,22 @@ function hasStructuredCompletion(result) {
|
|
|
1052
1052
|
return hasCompletionSignal(result?.completion);
|
|
1053
1053
|
}
|
|
1054
1054
|
|
|
1055
|
+
function getCleanTerminalReply(status) {
|
|
1056
|
+
if (!status?.sessionKey) return null;
|
|
1057
|
+
const entry = getSessionStoreEntry(status.sessionKey);
|
|
1058
|
+
const sessionId = entry?.sessionId || null;
|
|
1059
|
+
const sessionAgent = status.sessionKey.split(':')[1] || 'main';
|
|
1060
|
+
const terminalJsonlReply = sessionId ? getSessionTerminalReply(sessionId, sessionAgent) : null;
|
|
1061
|
+
if (!sessionId || !terminalJsonlReply) return null;
|
|
1062
|
+
return isSessionCleanlyFinished(sessionId, sessionAgent) ? terminalJsonlReply : null;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
function getStrictTerminalReply(result, status) {
|
|
1066
|
+
const terminalJsonlReply = getCleanTerminalReply(status);
|
|
1067
|
+
if (!terminalJsonlReply) return null;
|
|
1068
|
+
return result?.lastReply || terminalJsonlReply;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1055
1071
|
if (!label) {
|
|
1056
1072
|
process.stderr.write('[watcher] --label is required\n');
|
|
1057
1073
|
process.exit(2);
|
|
@@ -1159,16 +1175,13 @@ function runOnceAndExit() {
|
|
|
1159
1175
|
}
|
|
1160
1176
|
|
|
1161
1177
|
if (status.sessionKey) {
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1164
|
-
const sessionAgent = status.sessionKey.split(':')[1] || 'main';
|
|
1165
|
-
const terminalJsonlReply = sessionId ? getSessionTerminalReply(sessionId, sessionAgent) : null;
|
|
1166
|
-
if (sessionId && terminalJsonlReply && isSessionCleanlyFinished(sessionId, sessionAgent)) {
|
|
1178
|
+
const terminalJsonlReply = getCleanTerminalReply(status);
|
|
1179
|
+
if (terminalJsonlReply) {
|
|
1167
1180
|
const result = dispatch('result', ['--label', label]);
|
|
1168
1181
|
if (hasStructuredCompletion(result)) {
|
|
1169
1182
|
deliverResult(label, result?.lastReply || terminalJsonlReply, 'completed (stop_reason=end_turn)', result?.completion || null);
|
|
1170
1183
|
}
|
|
1171
|
-
|
|
1184
|
+
deliverResult(label, terminalJsonlReply, 'completed (stop_reason=end_turn)', null);
|
|
1172
1185
|
}
|
|
1173
1186
|
}
|
|
1174
1187
|
|
|
@@ -1181,6 +1194,10 @@ function runOnceAndExit() {
|
|
|
1181
1194
|
if (hasStructuredCompletion(result)) {
|
|
1182
1195
|
deliverResult(label, result?.lastReply || null, null, result?.completion || null);
|
|
1183
1196
|
}
|
|
1197
|
+
const terminalReply = getStrictTerminalReply(result, status);
|
|
1198
|
+
if (terminalReply) {
|
|
1199
|
+
deliverResult(label, terminalReply, 'completed (stop_reason=end_turn)', null);
|
|
1200
|
+
}
|
|
1184
1201
|
|
|
1185
1202
|
const stallReason = ageMs >= idleFailureMs
|
|
1186
1203
|
? getRunningSessionStallReason(status, idleFailureMs)
|
|
@@ -1550,7 +1567,7 @@ while (Date.now() < deadline) {
|
|
|
1550
1567
|
deliverResult(label, result?.lastReply || terminalJsonlReply, 'completed (stop_reason=end_turn)', result?.completion || null);
|
|
1551
1568
|
// deliverResult exits
|
|
1552
1569
|
}
|
|
1553
|
-
|
|
1570
|
+
deliverResult(label, terminalJsonlReply, 'completed (stop_reason=end_turn)', null);
|
|
1554
1571
|
}
|
|
1555
1572
|
}
|
|
1556
1573
|
|
|
@@ -1569,6 +1586,10 @@ while (Date.now() < deadline) {
|
|
|
1569
1586
|
if (hasStructuredCompletion(result)) {
|
|
1570
1587
|
deliverResult(label, result?.lastReply || null, null, result?.completion || null);
|
|
1571
1588
|
}
|
|
1589
|
+
const terminalReply = getStrictTerminalReply(result, status);
|
|
1590
|
+
if (terminalReply) {
|
|
1591
|
+
deliverResult(label, terminalReply, 'completed (stop_reason=end_turn)', null);
|
|
1592
|
+
}
|
|
1572
1593
|
|
|
1573
1594
|
const stallReason = ageMs >= idleFailureMs
|
|
1574
1595
|
? getRunningSessionStallReason(status, idleFailureMs)
|