mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
feat: add scheduler pause configuration
Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
31074099a1
commit
27c30f769a
6 files changed
+39
-2
No files matched your search
@@ -26,6 +26,7 @@ Create a `torch-config.json` file in your project root (or set `TORCH_CONFIG_PAT
|
||||
- `dashboard.defaultCadenceView` (`daily`, `weekly`, or `all`)
|
||||
- `dashboard.defaultStatusView` (`active` or `all`)
|
||||
- `scheduler.firstPromptByCadence.daily` / `.weekly`
|
||||
- `scheduler.paused.daily` / `.weekly` (array of agent names to pause locally)
|
||||
|
||||
Weekly alignment maintenance is available via `src/prompts/weekly/repo-fit-agent.md`, which is designed to keep TORCH defaults and docs tuned to the host repository over time.
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ Common settings:
|
||||
- `dashboard.defaultCadenceView` — default dashboard view (`daily`, `weekly`, `all`).
|
||||
- `dashboard.defaultStatusView` — default dashboard status filter (`active`, `all`).
|
||||
- `scheduler.firstPromptByCadence.daily` / `.weekly` — first-run scheduler starting agent.
|
||||
- `scheduler.paused.daily` / `.weekly` — array of agent names to exclude from scheduler rotation.
|
||||
|
||||
Default first-run daily scheduler prompt is `scheduler-update-agent`.
|
||||
|
||||
|
||||
+10
-1
@@ -259,15 +259,22 @@ async function cmdCheck(cadence) {
|
||||
const relays = getRelays();
|
||||
const namespace = getNamespace();
|
||||
const dateStr = todayDateStr();
|
||||
const config = loadTorchConfig();
|
||||
const pausedAgents = (cadence === 'daily' ? config.scheduler.paused.daily : config.scheduler.paused.weekly) || [];
|
||||
|
||||
console.error(`Checking locks: namespace=${namespace}, cadence=${cadence}, date=${dateStr}`);
|
||||
console.error(`Relays: ${relays.join(', ')}`);
|
||||
if (pausedAgents.length > 0) {
|
||||
console.error(`Paused agents: ${pausedAgents.join(', ')}`);
|
||||
}
|
||||
|
||||
const locks = await queryLocks(relays, cadence, dateStr, namespace);
|
||||
const lockedAgents = [...new Set(locks.map((l) => l.agent).filter(Boolean))];
|
||||
const roster = getRoster(cadence);
|
||||
|
||||
const excludedAgents = [...new Set([...lockedAgents, ...pausedAgents])];
|
||||
const unknownLockedAgents = lockedAgents.filter((agent) => !roster.includes(agent));
|
||||
const available = roster.filter((a) => !lockedAgents.includes(a));
|
||||
const available = roster.filter((a) => !excludedAgents.includes(a));
|
||||
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
@@ -276,6 +283,8 @@ async function cmdCheck(cadence) {
|
||||
cadence,
|
||||
date: dateStr,
|
||||
locked: lockedAgents.sort(),
|
||||
paused: pausedAgents.sort(),
|
||||
excluded: excludedAgents.sort(),
|
||||
available: available.sort(),
|
||||
lockCount: locks.length,
|
||||
unknownLockedAgents: unknownLockedAgents.sort(),
|
||||
|
||||
@@ -37,7 +37,7 @@ Use this document for all scheduler runs.
|
||||
Selection algorithm (MUST be followed exactly):
|
||||
|
||||
- Roster source: `src/prompts/roster.json` and the key matching `<cadence>`.
|
||||
- Let `roster` be that ordered array and `excluded` be the locked set from step 2.
|
||||
- Let `roster` be that ordered array and `excluded` be the `excluded` set (including paused and locked agents) from the JSON output of step 2.
|
||||
- Let `latest_file` be the lexicographically last filename in `<log_dir>`.
|
||||
- Determine `previous_agent` from `latest_file` using this precedence:
|
||||
1. Parse YAML frontmatter from `<log_dir>/<latest_file>` and use key `agent` when present and non-empty.
|
||||
|
||||
@@ -45,6 +45,7 @@ export function loadTorchConfig() {
|
||||
const dashboard = raw.dashboard || {};
|
||||
const scheduler = raw.scheduler || {};
|
||||
const firstPromptByCadence = scheduler.firstPromptByCadence || {};
|
||||
const paused = scheduler.paused || {};
|
||||
|
||||
cachedConfig = {
|
||||
configPath,
|
||||
@@ -77,6 +78,10 @@ export function loadTorchConfig() {
|
||||
daily: typeof firstPromptByCadence.daily === 'string' ? firstPromptByCadence.daily.trim() : null,
|
||||
weekly: typeof firstPromptByCadence.weekly === 'string' ? firstPromptByCadence.weekly.trim() : null,
|
||||
},
|
||||
paused: {
|
||||
daily: parseRoster(paused.daily) || [],
|
||||
weekly: parseRoster(paused.weekly) || [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { test, describe, it } from 'node:test';
|
||||
import assert from 'node:assert';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
|
||||
describe('CLI Smoke Test', () => {
|
||||
it('should print usage when no args provided', () => {
|
||||
@@ -14,4 +15,24 @@ describe('CLI Smoke Test', () => {
|
||||
assert.strictEqual(result.status, 1);
|
||||
assert.match(result.stderr.toString(), /--cadence <daily|weekly> is required/);
|
||||
});
|
||||
|
||||
it('should include paused agents in check output', () => {
|
||||
const configPath = 'test-torch-config.json';
|
||||
fs.writeFileSync(configPath, JSON.stringify({
|
||||
scheduler: { paused: { daily: ['paused-agent'] } }
|
||||
}));
|
||||
|
||||
try {
|
||||
const result = spawnSync('node', ['src/nostr-lock.mjs', 'check', '--cadence', 'daily'], {
|
||||
env: { ...process.env, TORCH_CONFIG_PATH: configPath }
|
||||
});
|
||||
const output = JSON.parse(result.stdout.toString());
|
||||
assert.deepStrictEqual(output.paused, ['paused-agent']);
|
||||
assert.ok(output.excluded.includes('paused-agent'));
|
||||
} finally {
|
||||
if (fs.existsSync(configPath)) {
|
||||
fs.unlinkSync(configPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user