Files
openclaw/src/agents/tools/gateway.ts
Tyler Yust 3a03e38378 fix(cron): fix timeout, add timestamp validation, enable file sync
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
2026-02-04 01:03:59 -08:00

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,
});
}