principles-disciple 1.34.1 → 1.34.2
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/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -40,6 +40,15 @@ import { CorrectionCueLearner } from '../core/correction-cue-learner.js';
|
|
|
40
40
|
const WORKFLOW_TTL_MS = 5 * 60 * 1000; // 5 minutes default TTL for helper workflows
|
|
41
41
|
import { OpenClawTrinityRuntimeAdapter } from '../core/nocturnal-trinity.js';
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Atomic file write — write to temp then rename to prevent partial writes on crash.
|
|
45
|
+
*/
|
|
46
|
+
function atomicWriteFileSync(filePath: string, data: string): void {
|
|
47
|
+
const tmpPath = filePath + '.tmp';
|
|
48
|
+
fs.writeFileSync(tmpPath, data, 'utf8');
|
|
49
|
+
fs.renameSync(tmpPath, filePath);
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
// ── Workflow Watchdog ────────────────────────────────────────────────────────
|
|
44
53
|
// Detects stale/orphaned workflows, invalid results, and cleanup failures.
|
|
45
54
|
// Runs every heartbeat cycle, catching bugs like:
|
|
@@ -683,7 +692,7 @@ function shouldSkipForDedup(
|
|
|
683
692
|
* Load and migrate the evolution queue. Returns empty array if file doesn't exist.
|
|
684
693
|
*/
|
|
685
694
|
function loadEvolutionQueue(queuePath: string): EvolutionQueueItem[] {
|
|
686
|
-
|
|
695
|
+
// eslint-disable-next-line no-useless-assignment
|
|
687
696
|
let rawQueue: RawQueueItem[] = [];
|
|
688
697
|
try {
|
|
689
698
|
rawQueue = JSON.parse(fs.readFileSync(queuePath, 'utf8'));
|
|
@@ -724,7 +733,7 @@ function enqueueNewSleepReflectionTask(
|
|
|
724
733
|
recentPainContext,
|
|
725
734
|
});
|
|
726
735
|
|
|
727
|
-
|
|
736
|
+
atomicWriteFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
728
737
|
logger?.info?.(`[PD:EvolutionWorker] Enqueued sleep_reflection task ${taskId}`);
|
|
729
738
|
}
|
|
730
739
|
|
|
@@ -869,7 +878,7 @@ async function doEnqueuePainTask(
|
|
|
869
878
|
retryCount: 0, maxRetries: 3,
|
|
870
879
|
});
|
|
871
880
|
|
|
872
|
-
|
|
881
|
+
atomicWriteFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
873
882
|
fs.appendFileSync(painFlagPath, `\nstatus: queued\ntask_id: ${taskId}\n`, 'utf8');
|
|
874
883
|
result.enqueued = true;
|
|
875
884
|
|
|
@@ -1658,7 +1667,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1658
1667
|
|
|
1659
1668
|
// Write claimed state (includes any pain changes from above) and release lock
|
|
1660
1669
|
if (queueChanged) {
|
|
1661
|
-
|
|
1670
|
+
atomicWriteFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
1662
1671
|
}
|
|
1663
1672
|
releaseLock();
|
|
1664
1673
|
for (const sleepTask of sleepReflectionTasks) {
|
|
@@ -1912,7 +1921,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1912
1921
|
freshQueue[idx] = sleepTask;
|
|
1913
1922
|
}
|
|
1914
1923
|
}
|
|
1915
|
-
|
|
1924
|
+
atomicWriteFileSync(queuePath, JSON.stringify(freshQueue, null, 2));
|
|
1916
1925
|
|
|
1917
1926
|
// Log completions to EvolutionLogger
|
|
1918
1927
|
for (const sleepTask of sleepReflectionTasks) {
|
|
@@ -2097,7 +2106,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
2097
2106
|
}
|
|
2098
2107
|
|
|
2099
2108
|
if (queueChanged) {
|
|
2100
|
-
|
|
2109
|
+
atomicWriteFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
2101
2110
|
}
|
|
2102
2111
|
|
|
2103
2112
|
// Pipeline observability: log stage-level summary at end of cycle
|
|
@@ -2215,7 +2224,7 @@ export async function registerEvolutionTaskSession(
|
|
|
2215
2224
|
if (!task.started_at) {
|
|
2216
2225
|
task.started_at = new Date().toISOString();
|
|
2217
2226
|
}
|
|
2218
|
-
|
|
2227
|
+
atomicWriteFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
2219
2228
|
return true;
|
|
2220
2229
|
} finally {
|
|
2221
2230
|
releaseLock();
|
|
@@ -2255,7 +2264,7 @@ interface WorkerStatusReport {
|
|
|
2255
2264
|
function writeWorkerStatus(stateDir: string, report: WorkerStatusReport): void {
|
|
2256
2265
|
try {
|
|
2257
2266
|
const statusPath = path.join(stateDir, 'worker-status.json');
|
|
2258
|
-
|
|
2267
|
+
atomicWriteFileSync(statusPath, JSON.stringify(report, null, 2));
|
|
2259
2268
|
} catch (statusErr) {
|
|
2260
2269
|
// Non-critical: worker-status.json is for monitoring, failure is acceptable
|
|
2261
2270
|
// (no logger available in this standalone helper)
|
|
@@ -2286,7 +2295,7 @@ async function processEvolutionQueueWithResult(
|
|
|
2286
2295
|
const purgeResult = purgeStaleFailedTasks(queue, logger);
|
|
2287
2296
|
if (purgeResult.purged > 0) {
|
|
2288
2297
|
// Write back the cleaned queue
|
|
2289
|
-
|
|
2298
|
+
atomicWriteFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
2290
2299
|
}
|
|
2291
2300
|
|
|
2292
2301
|
queueResult.total = queue.length;
|
|
@@ -103,6 +103,15 @@ import { getPrincipleState, setPrincipleState } from '../core/principle-training
|
|
|
103
103
|
import type { Implementation } from '../types/principle-tree-schema.js';
|
|
104
104
|
import { validateNocturnalSnapshotIngress } from '../core/nocturnal-snapshot-contract.js';
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Atomic file write — write to temp then rename to prevent partial writes on crash.
|
|
108
|
+
*/
|
|
109
|
+
function atomicWriteFileSync(filePath: string, data: string): void {
|
|
110
|
+
const tmpPath = filePath + '.tmp';
|
|
111
|
+
fs.writeFileSync(tmpPath, data, 'utf8');
|
|
112
|
+
fs.renameSync(tmpPath, filePath);
|
|
113
|
+
}
|
|
114
|
+
|
|
106
115
|
// ---------------------------------------------------------------------------
|
|
107
116
|
// #251: Sync trainingStore sample counts after registration
|
|
108
117
|
// ---------------------------------------------------------------------------
|
|
@@ -385,10 +394,7 @@ function persistArtifact(
|
|
|
385
394
|
fs.mkdirSync(dir, { recursive: true });
|
|
386
395
|
}
|
|
387
396
|
|
|
388
|
-
|
|
389
|
-
const tmpPath = artifactPath + '.tmp';
|
|
390
|
-
fs.writeFileSync(tmpPath, JSON.stringify(sampleRecord, null, 2), 'utf8');
|
|
391
|
-
fs.renameSync(tmpPath, artifactPath);
|
|
397
|
+
atomicWriteFileSync(artifactPath, JSON.stringify(sampleRecord, null, 2));
|
|
392
398
|
return artifactPath;
|
|
393
399
|
}
|
|
394
400
|
|