Replace the single hardcoded signed-out check with a guards list on each firm: any guard can trip mid-run via a URL substring (checked on every step) or a selector probe (checked when a step fails). Each guard defines recovery steps or a human-wait fallback, a per-run trigger cap, and a resume policy — 'continue' retries the tripped step, 'restart' rewinds the run to step 1. Runner bumped to 0.20.0; the server still ships the legacy signedOut/authSteps shape for stale runners, and a new runner synthesizes a guard from a legacy payload. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
import { claimRun } from '@/lib/db';
|
|
import { findAutomation, resolveSteps, resolveGuards, resolveAuthSteps } from '@/lib/automations';
|
|
import { corsJson, corsPreflight } from '../../cors';
|
|
|
|
/** The Python runner polls this. Returns the run plus the steps to execute, so
|
|
* the runner never needs its own copy of the automation definitions. */
|
|
export async function POST() {
|
|
const row = claimRun();
|
|
if (!row) return corsJson({ run: null });
|
|
|
|
const found = findAutomation(row.automation_id);
|
|
if (!found) {
|
|
return corsJson({ run: null, reason: `Unknown automation ${row.automation_id}` });
|
|
}
|
|
|
|
return corsJson({
|
|
run: {
|
|
id: row.id,
|
|
automationId: row.automation_id,
|
|
firm: found.firm.label,
|
|
label: found.automation.label,
|
|
steps: resolveSteps(found.firm, found.automation, safeInputs(row.inputs)),
|
|
guards: resolveGuards(found.firm),
|
|
// Pre-0.20 runners know nothing of guards; keep feeding them the
|
|
// old shape until they are restarted.
|
|
authSteps: resolveAuthSteps(found.firm),
|
|
},
|
|
});
|
|
}
|
|
|
|
/** Stored inputs are already clamped; this only guards against a malformed row. */
|
|
function safeInputs(json: string): Record<string, number> {
|
|
try {
|
|
const parsed = JSON.parse(json);
|
|
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
export async function OPTIONS() {
|
|
return corsPreflight();
|
|
}
|