mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-01 02:11:54 +00:00
Merge pull request #177 from PR0M3TH3AN/feat/nostr-platform-model-info-17811919130475421613
Add platform and model support to Nostr lock events
This commit is contained in:
9 files changed
+1481
-22
No files matched your search
@@ -437,6 +437,7 @@
|
||||
status: content.status ?? 'unknown',
|
||||
date: content.date ?? dTag.split('/')[3] ?? todayStr(),
|
||||
platform: content.platform ?? 'unknown',
|
||||
model: content.model ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -585,8 +586,14 @@
|
||||
left.appendChild(meta);
|
||||
header.appendChild(left);
|
||||
|
||||
const right = createElement('div', 'flex flex-col items-end gap-1');
|
||||
const badge = createElement('span', `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${ps.bg} ${ps.text}`, ps.label);
|
||||
header.appendChild(badge);
|
||||
right.appendChild(badge);
|
||||
|
||||
if (lock.model && lock.model !== 'unknown') {
|
||||
right.appendChild(createElement('span', 'text-xs text-muted mono opacity-75', lock.model));
|
||||
}
|
||||
header.appendChild(right);
|
||||
card.appendChild(header);
|
||||
|
||||
// Grid
|
||||
|
||||
@@ -143,6 +143,7 @@ a { color: inherit; }
|
||||
.w-full { width: 100%; }
|
||||
.shrink-0 { flex-shrink: 0; }
|
||||
.opacity-60 { opacity: 0.6; }
|
||||
.opacity-75 { opacity: 0.75; }
|
||||
|
||||
.text-center { text-align: center; }
|
||||
.text-xs { font-size: 0.75rem; line-height: 1rem; }
|
||||
|
||||
@@ -18,7 +18,7 @@ const FAILURE_CATEGORY = {
|
||||
const LOCK_INCIDENT_LINK = 'docs/agent-handoffs/learnings/2026-02-15-relay-health-preflight-job.md';
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = { cadence: null, platform: process.env.AGENT_PLATFORM || 'codex' };
|
||||
const args = { cadence: null, platform: process.env.AGENT_PLATFORM || 'codex', model: process.env.AGENT_MODEL || null };
|
||||
for (let i = 0; i < argv.length; i += 1) {
|
||||
const value = argv[i];
|
||||
if (!value.startsWith('--') && !args.cadence) {
|
||||
@@ -34,6 +34,10 @@ function parseArgs(argv) {
|
||||
args.platform = argv[i + 1] || args.platform;
|
||||
i += 1;
|
||||
}
|
||||
if (value === '--model') {
|
||||
args.model = argv[i + 1] || args.model;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
@@ -540,8 +544,11 @@ function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function acquireLockWithRetry({ selectedAgent, cadence, platform, lockRetry, idempotencyKey }) {
|
||||
async function acquireLockWithRetry({ selectedAgent, cadence, platform, model, lockRetry, idempotencyKey }) {
|
||||
const lockCommandArgs = ['run', 'lock:lock', '--', '--agent', selectedAgent, '--cadence', cadence];
|
||||
if (model) {
|
||||
lockCommandArgs.push('--model', model);
|
||||
}
|
||||
const backoffScheduleMs = [];
|
||||
let attempts = 0;
|
||||
const correlationId = idempotencyKey || `${cadence}:${selectedAgent}:${getRunDateKey()}`;
|
||||
@@ -551,6 +558,7 @@ async function acquireLockWithRetry({ selectedAgent, cadence, platform, lockRetr
|
||||
const result = await runCommand('npm', lockCommandArgs, {
|
||||
env: {
|
||||
AGENT_PLATFORM: platform,
|
||||
...(model ? { AGENT_MODEL: model } : {}),
|
||||
...(idempotencyKey ? { SCHEDULER_LOCK_IDEMPOTENCY_KEY: idempotencyKey } : {}),
|
||||
SCHEDULER_LOCK_CORRELATION_ID: correlationId,
|
||||
SCHEDULER_LOCK_ATTEMPT_ID: String(attempts),
|
||||
@@ -664,7 +672,7 @@ async function writeLog({ cadence, agent, status, reason, detail, platform, meta
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { cadence, platform } = parseArgs(process.argv.slice(2));
|
||||
const { cadence, platform, model } = parseArgs(process.argv.slice(2));
|
||||
if (!VALID_CADENCES.has(cadence)) {
|
||||
console.error('Usage: node scripts/agent/run-scheduler-cycle.mjs <daily|weekly>');
|
||||
process.exit(1);
|
||||
@@ -772,6 +780,7 @@ async function main() {
|
||||
selectedAgent,
|
||||
cadence,
|
||||
platform,
|
||||
model,
|
||||
lockRetry: schedulerConfig.lockRetry,
|
||||
idempotencyKey: deferralForAgent?.idempotency_key,
|
||||
});
|
||||
@@ -785,7 +794,8 @@ async function main() {
|
||||
const combinedLockOutput = `${lockResult.stderr}\n${lockResult.stdout}`;
|
||||
const diagnosticsSummary = summarizeLockFailureReasons(combinedLockOutput);
|
||||
const backendCategory = lockAttempt.finalBackendCategory || classifyLockBackendError(combinedLockOutput);
|
||||
const lockCommand = `AGENT_PLATFORM=${platform} npm run lock:lock -- --agent ${selectedAgent} --cadence ${cadence}`;
|
||||
const modelPart = model ? ` --model ${model}` : '';
|
||||
const lockCommand = `AGENT_PLATFORM=${platform} npm run lock:lock -- --agent ${selectedAgent} --cadence ${cadence}${modelPart}`;
|
||||
const stderrExcerpt = excerptText(lockResult.stderr);
|
||||
const stdoutExcerpt = excerptText(lockResult.stdout);
|
||||
const backoffSchedule = lockAttempt.backoffScheduleMs.join(', ');
|
||||
@@ -892,7 +902,7 @@ async function main() {
|
||||
|
||||
if (schedulerConfig.memoryPolicy.retrieveCommand) {
|
||||
const retrieveResult = await runCommand('bash', ['-lc', schedulerConfig.memoryPolicy.retrieveCommand], {
|
||||
env: { AGENT_PLATFORM: platform, SCHEDULER_AGENT: selectedAgent, SCHEDULER_CADENCE: cadence, SCHEDULER_PROMPT_PATH: promptPath },
|
||||
env: { AGENT_PLATFORM: platform, ...(model ? { AGENT_MODEL: model } : {}), SCHEDULER_AGENT: selectedAgent, SCHEDULER_CADENCE: cadence, SCHEDULER_PROMPT_PATH: promptPath },
|
||||
});
|
||||
outputChunks.push(retrieveResult.stdout, retrieveResult.stderr);
|
||||
if (retrieveResult.code !== 0) {
|
||||
@@ -911,7 +921,7 @@ async function main() {
|
||||
|
||||
if (schedulerConfig.handoffCommand) {
|
||||
const handoff = await runCommand('bash', ['-lc', schedulerConfig.handoffCommand], {
|
||||
env: { AGENT_PLATFORM: platform, SCHEDULER_AGENT: selectedAgent, SCHEDULER_CADENCE: cadence, SCHEDULER_PROMPT_PATH: promptPath },
|
||||
env: { AGENT_PLATFORM: platform, ...(model ? { AGENT_MODEL: model } : {}), SCHEDULER_AGENT: selectedAgent, SCHEDULER_CADENCE: cadence, SCHEDULER_PROMPT_PATH: promptPath },
|
||||
});
|
||||
outputChunks.push(handoff.stdout, handoff.stderr);
|
||||
if (handoff.code !== 0) {
|
||||
@@ -944,7 +954,7 @@ async function main() {
|
||||
|
||||
if (schedulerConfig.memoryPolicy.storeCommand) {
|
||||
const storeResult = await runCommand('bash', ['-lc', schedulerConfig.memoryPolicy.storeCommand], {
|
||||
env: { AGENT_PLATFORM: platform, SCHEDULER_AGENT: selectedAgent, SCHEDULER_CADENCE: cadence, SCHEDULER_PROMPT_PATH: promptPath },
|
||||
env: { AGENT_PLATFORM: platform, ...(model ? { AGENT_MODEL: model } : {}), SCHEDULER_AGENT: selectedAgent, SCHEDULER_CADENCE: cadence, SCHEDULER_PROMPT_PATH: promptPath },
|
||||
});
|
||||
outputChunks.push(storeResult.stdout, storeResult.stderr);
|
||||
if (storeResult.code !== 0) {
|
||||
@@ -1043,8 +1053,8 @@ async function main() {
|
||||
|
||||
const completeResult = await runCommand(
|
||||
'npm',
|
||||
['run', 'lock:complete', '--', '--agent', selectedAgent, '--cadence', cadence],
|
||||
{ env: { AGENT_PLATFORM: platform } },
|
||||
['run', 'lock:complete', '--', '--agent', selectedAgent, '--cadence', cadence, ...(model ? ['--model', model] : [])],
|
||||
{ env: { AGENT_PLATFORM: platform, ...(model ? { AGENT_MODEL: model } : {}) } },
|
||||
);
|
||||
|
||||
if (completeResult.code !== 0) {
|
||||
|
||||
@@ -43,7 +43,7 @@ const invariants = [
|
||||
],
|
||||
},
|
||||
schedulerSnippets: [
|
||||
"runCommand('npm', ['run', `lock:check:${cadence}`])",
|
||||
"runCommand('npm', ['run', `lock:check:${cadence}`",
|
||||
'checkPayload.excluded',
|
||||
'checkPayload.locked',
|
||||
'checkPayload.paused',
|
||||
|
||||
+10
-3
@@ -31,7 +31,8 @@ export function parseArgs(argv) {
|
||||
allRelaysDownMinutes: null,
|
||||
minSuccessRate: null,
|
||||
windowMinutes: null,
|
||||
full: false,
|
||||
platform: null,
|
||||
model: null,
|
||||
};
|
||||
let i = 0;
|
||||
|
||||
@@ -118,8 +119,14 @@ export function parseArgs(argv) {
|
||||
args.windowMinutes = parseInt(argv[++i], 10);
|
||||
} else if (arg.startsWith('--window-minutes=')) {
|
||||
args.windowMinutes = parseInt(arg.split('=')[1], 10);
|
||||
} else if (arg === '--full') {
|
||||
args.full = true;
|
||||
} else if (arg === '--platform') {
|
||||
args.platform = argv[++i];
|
||||
} else if (arg.startsWith('--platform=')) {
|
||||
args.platform = arg.split('=')[1];
|
||||
} else if (arg === '--model') {
|
||||
args.model = argv[++i];
|
||||
} else if (arg.startsWith('--model=')) {
|
||||
args.model = arg.split('=')[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-7
@@ -33,7 +33,7 @@ import {
|
||||
unpinMemory,
|
||||
} from './services/memory/index.js';
|
||||
import { ExitError } from './errors.mjs';
|
||||
import { todayDateStr, nowUnix, getIsoWeekStr } from './utils.mjs';
|
||||
import { todayDateStr, nowUnix, getIsoWeekStr, detectPlatform } from './utils.mjs';
|
||||
import { runRelayHealthCheck } from './relay-health.mjs';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
@@ -204,7 +204,10 @@ export async function cmdCheck(cadence, deps = {}) {
|
||||
* @returns {Promise<{status: string, eventId: string}>}
|
||||
* @throws {ExitError} If lock is denied (already locked, completed, or race lost)
|
||||
*/
|
||||
export async function cmdLock(agent, cadence, dryRun = false, deps = {}) {
|
||||
export async function cmdLock(agent, cadence, optionsOrDryRun = false, deps = {}) {
|
||||
const options = typeof optionsOrDryRun === 'object' ? optionsOrDryRun : { dryRun: !!optionsOrDryRun };
|
||||
const { dryRun = false, platform = null, model = null } = options;
|
||||
|
||||
const {
|
||||
getRelays = _getRelays,
|
||||
getNamespace = _getNamespace,
|
||||
@@ -290,7 +293,8 @@ export async function cmdLock(agent, cadence, dryRun = false, deps = {}) {
|
||||
status: 'started',
|
||||
namespace,
|
||||
date: dateStr,
|
||||
platform: process.env.AGENT_PLATFORM || 'unknown',
|
||||
platform: platform || process.env.AGENT_PLATFORM || detectPlatform() || 'unknown',
|
||||
model: model || process.env.AGENT_MODEL || 'unknown',
|
||||
lockedAt: new Date(now * 1000).toISOString(),
|
||||
expiresAt: new Date(expiresAt * 1000).toISOString(),
|
||||
}),
|
||||
@@ -436,7 +440,10 @@ export async function cmdList(cadence, deps = {}) {
|
||||
* @returns {Promise<{status: string, eventId: string}>}
|
||||
* @throws {ExitError} If no active lock exists for the agent
|
||||
*/
|
||||
export async function cmdComplete(agent, cadence, dryRun = false, deps = {}) {
|
||||
export async function cmdComplete(agent, cadence, optionsOrDryRun = false, deps = {}) {
|
||||
const options = typeof optionsOrDryRun === 'object' ? optionsOrDryRun : { dryRun: !!optionsOrDryRun };
|
||||
const { dryRun = false, platform = null, model = null } = options;
|
||||
|
||||
const {
|
||||
getRelays = _getRelays,
|
||||
getNamespace = _getNamespace,
|
||||
@@ -500,7 +507,8 @@ export async function cmdComplete(agent, cadence, dryRun = false, deps = {}) {
|
||||
status: 'completed',
|
||||
namespace,
|
||||
date: dateStr,
|
||||
platform: process.env.AGENT_PLATFORM || 'unknown',
|
||||
platform: platform || process.env.AGENT_PLATFORM || detectPlatform() || 'unknown',
|
||||
model: model || process.env.AGENT_MODEL || 'unknown',
|
||||
startedAt: startedAtIso,
|
||||
completedAt: new Date(now * 1000).toISOString(),
|
||||
}),
|
||||
@@ -614,7 +622,11 @@ export async function main(argv) {
|
||||
console.error(`ERROR: --cadence <${[...VALID_CADENCES].join('|')}> is required for lock`);
|
||||
throw new ExitError(1, 'Missing cadence');
|
||||
}
|
||||
await cmdLock(args.agent, args.cadence, args.dryRun);
|
||||
await cmdLock(args.agent, args.cadence, {
|
||||
dryRun: args.dryRun,
|
||||
platform: args.platform,
|
||||
model: args.model
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -627,7 +639,11 @@ export async function main(argv) {
|
||||
console.error(`ERROR: --cadence <${[...VALID_CADENCES].join('|')}> is required for complete`);
|
||||
throw new ExitError(1, 'Missing cadence');
|
||||
}
|
||||
await cmdComplete(args.agent, args.cadence, args.dryRun);
|
||||
await cmdComplete(args.agent, args.cadence, {
|
||||
dryRun: args.dryRun,
|
||||
platform: args.platform,
|
||||
model: args.model
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,3 +27,10 @@ export function getIsoWeekStr(dateInput) {
|
||||
|
||||
return `${date.getUTCFullYear()}-W${String(weekNo).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
export function detectPlatform() {
|
||||
if (process.env.JULES_API_KEY || process.env.JULES_SESSION_ID) return 'jules';
|
||||
if (process.env.CODEX_API_KEY || process.env.CODEX_SESSION_ID) return 'codex';
|
||||
if (process.env.GOOSE_API_KEY || process.env.GOOSE_SESSION_ID) return 'goose';
|
||||
return null;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ describe('Scheduler cycle ordering guarantees', () => {
|
||||
|
||||
const order = [
|
||||
"const preflight = await runLockHealthPreflight({ cadence, platform });",
|
||||
"const checkResult = await runCommand('npm', ['run', `lock:check:${cadence}`]);",
|
||||
"const checkResult = await runCommand('npm', ['run', `lock:check:${cadence}`",
|
||||
"const lockAttempt = await acquireLockWithRetry({",
|
||||
"if (schedulerConfig.handoffCommand)",
|
||||
"const artifactCheck = await runCommand('node', [",
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user