Fixes #7667 Task 1: Fix cron operation timeouts - Increase default gateway tool timeout from 10s to 30s - Increase cron-specific tool timeout to 60s - Increase CLI default timeout from 10s to 30s - Prevents timeouts when gateway is busy with long-running jobs Task 2: Add timestamp validation - New validateScheduleTimestamp() function in validate-timestamp.ts - Rejects atMs timestamps more than 1 minute in the past - Rejects atMs timestamps more than 10 years in the future - Applied to both cron.add and cron.update operations - Provides helpful error messages with current time and offset Task 3: Enable file sync for manual edits - Track file modification time (storeFileMtimeMs) in CronServiceState - Check file mtime in ensureLoaded() and reload if changed - Recompute next runs after reload to maintain accuracy - Update mtime after persist() to prevent reload loop - Dashboard now picks up manual edits to ~/.openclaw/cron/jobs.json
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import { callGateway } from "../../gateway/call.js";
|
|
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../utils/message-channel.js";
|
|
|
|
export const DEFAULT_GATEWAY_URL = "ws://127.0.0.1:18789";
|
|
|
|
export type GatewayCallOptions = {
|
|
gatewayUrl?: string;
|
|
gatewayToken?: string;
|
|
timeoutMs?: number;
|
|
};
|
|
|
|
export function resolveGatewayOptions(opts?: GatewayCallOptions) {
|
|
// Prefer an explicit override; otherwise let callGateway choose based on config.
|
|
const url =
|
|
typeof opts?.gatewayUrl === "string" && opts.gatewayUrl.trim()
|
|
? opts.gatewayUrl.trim()
|
|
: undefined;
|
|
const token =
|
|
typeof opts?.gatewayToken === "string" && opts.gatewayToken.trim()
|
|
? opts.gatewayToken.trim()
|
|
: undefined;
|
|
const timeoutMs =
|
|
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
|
? Math.max(1, Math.floor(opts.timeoutMs))
|
|
: 30_000;
|
|
return { url, token, timeoutMs };
|
|
}
|
|
|
|
export async function callGatewayTool<T = Record<string, unknown>>(
|
|
method: string,
|
|
opts: GatewayCallOptions,
|
|
params?: unknown,
|
|
extra?: { expectFinal?: boolean },
|
|
) {
|
|
const gateway = resolveGatewayOptions(opts);
|
|
return await callGateway<T>({
|
|
url: gateway.url,
|
|
token: gateway.token,
|
|
method,
|
|
params,
|
|
timeoutMs: gateway.timeoutMs,
|
|
expectFinal: extra?.expectFinal,
|
|
clientName: GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT,
|
|
clientDisplayName: "agent",
|
|
mode: GATEWAY_CLIENT_MODES.BACKEND,
|
|
});
|
|
}
|