mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-04-30 22:12:32 +08:00
fix(cron): warn when --agent is not specified on cron add (#42245)
* fix(cron): warn when --agent is not specified on cron add Warn users when creating a cron job without specifying the --agent flag, so they know the job will run with the default agent (main). Fixes #42196 * fix(cron): warn when cron add omits --agent * fix(cron): name default agent in warning --------- Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -49,6 +49,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Media: treat legacy Word/OLE attachments with `application/msword` or `application/x-cfb` MIME as binary so printable-looking `.doc` files are not embedded into prompts as text. Fixes #54176; carries forward #54380. Thanks @andyliu.
|
||||
- Config: accept documented `browser.tabCleanup` keys in strict root config validation, so configured tab cleanup no longer fails before runtime reads it. Fixes #74577. Thanks @lonexreb and @ezdlp.
|
||||
- Cron: validate disabled job schedule edits before persisting updates, so invalid cron changes no longer partially mutate stored jobs. Fixes #74459. Thanks @yfge.
|
||||
- CLI/cron: warn when `openclaw cron add --message` omits a nonblank `--agent`, including blank agent values and session-key jobs, so scheduled agent-turn jobs make default-agent fallback explicit while system events stay quiet. Fixes #42196; carries forward #42245. Thanks @ethanclaw.
|
||||
- Channels/status: keep Telegram, Slack, and Google Chat read-only allowlist/default-target accessors on config-only paths, so status and channel summaries do not resolve SecretRef-backed runtime credentials. Thanks @eusine.
|
||||
- Active Memory: clarify the deprecated `modelFallbackPolicy` warning and config help so `modelFallback` is described as a chain-resolution last resort, not runtime failover. (#74602) Thanks @jeffrey701.
|
||||
- Channels/Discord: keep read-only allowlist/default-target accessors from resolving SecretRef-backed bot tokens, so status and channel summaries no longer fail when tokens are only available in gateway runtime. (#74737) Thanks @eusine.
|
||||
|
||||
@@ -12,7 +12,7 @@ const mocks = vi.hoisted(() => {
|
||||
defaultRuntime.log(value.endsWith("\n") ? value.slice(0, -1) : value);
|
||||
}),
|
||||
writeJson: vi.fn((value: unknown, space = 2) => {
|
||||
defaultRuntime.log(JSON.stringify(value, null, space > 0 ? space : undefined));
|
||||
defaultRuntime.writeStdout(JSON.stringify(value, null, space > 0 ? space : undefined));
|
||||
}),
|
||||
exit: vi.fn((code: number) => {
|
||||
throw new Error(`__exit__:${code}`);
|
||||
@@ -548,6 +548,110 @@ describe("cron cli", () => {
|
||||
const addCall = callGatewayFromCli.mock.calls.find((call) => call[0] === "cron.add");
|
||||
const params = addCall?.[2] as { agentId?: string };
|
||||
expect(params?.agentId).toBe("ops");
|
||||
expect(defaultRuntime.error).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining("No --agent specified"),
|
||||
);
|
||||
});
|
||||
|
||||
it("warns when --agent is not specified on cron add with --message", async () => {
|
||||
await runCronCommand([
|
||||
"cron",
|
||||
"add",
|
||||
"--name",
|
||||
"No agent",
|
||||
"--cron",
|
||||
"* * * * *",
|
||||
"--message",
|
||||
"hello",
|
||||
]);
|
||||
|
||||
expect(defaultRuntime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("No --agent specified"),
|
||||
);
|
||||
expect(defaultRuntime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("default agent (main)"),
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the missing --agent warning off cron add JSON stdout", async () => {
|
||||
await runCronCommand([
|
||||
"cron",
|
||||
"add",
|
||||
"--name",
|
||||
"No agent JSON",
|
||||
"--cron",
|
||||
"* * * * *",
|
||||
"--message",
|
||||
"hello",
|
||||
"--json",
|
||||
]);
|
||||
|
||||
expect(defaultRuntime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("No --agent specified"),
|
||||
);
|
||||
const stdout = defaultRuntime.writeStdout.mock.calls.map(([value]) => value).join("\n");
|
||||
expect(stdout).not.toContain("No --agent specified");
|
||||
expect(JSON.parse(stdout)).toMatchObject({
|
||||
ok: true,
|
||||
params: {
|
||||
name: "No agent JSON",
|
||||
payload: { kind: "agentTurn", message: "hello" },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("warns when --agent is blank on cron add with --message", async () => {
|
||||
const params = await runCronAddAndGetParams([
|
||||
"--name",
|
||||
"Blank agent",
|
||||
"--cron",
|
||||
"* * * * *",
|
||||
"--message",
|
||||
"hello",
|
||||
"--agent",
|
||||
" ",
|
||||
]);
|
||||
|
||||
expect(params?.agentId).toBeUndefined();
|
||||
expect(defaultRuntime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("No --agent specified"),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not warn when --system-event is used (no agent needed)", async () => {
|
||||
await runCronCommand([
|
||||
"cron",
|
||||
"add",
|
||||
"--name",
|
||||
"System event",
|
||||
"--cron",
|
||||
"* * * * *",
|
||||
"--system-event",
|
||||
"tick",
|
||||
]);
|
||||
|
||||
expect(defaultRuntime.error).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining("No --agent specified"),
|
||||
);
|
||||
});
|
||||
|
||||
it("warns even when --session-key is provided (user should still specify agent explicitly)", async () => {
|
||||
await runCronCommand([
|
||||
"cron",
|
||||
"add",
|
||||
"--name",
|
||||
"With session key",
|
||||
"--cron",
|
||||
"* * * * *",
|
||||
"--message",
|
||||
"hello",
|
||||
"--session-key",
|
||||
"agent:my-agent:my-session",
|
||||
]);
|
||||
|
||||
expect(defaultRuntime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("No --agent specified"),
|
||||
);
|
||||
});
|
||||
|
||||
it("sets lightContext on cron add when --light-context is passed", async () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "../../shared/string-coerce.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
import type { GatewayRpcOpts } from "../gateway-rpc.js";
|
||||
import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js";
|
||||
import { parsePositiveIntOrUndefined } from "../program/helpers.js";
|
||||
@@ -231,6 +232,15 @@ export function registerCronAddCommand(cron: Command) {
|
||||
|
||||
const sessionKey = normalizeOptionalString(opts.sessionKey);
|
||||
|
||||
if (payload.kind === "agentTurn" && !agentId) {
|
||||
defaultRuntime.error(
|
||||
theme.warn(
|
||||
"No --agent specified; the job will run with the default agent (main). " +
|
||||
"Specify --agent to choose a specific agent.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const params = {
|
||||
name,
|
||||
description,
|
||||
|
||||
Reference in New Issue
Block a user