mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-02 01:26:13 +00:00
feat(cron): add --account flag for multi-account delivery routing (#26284)
* feat(cron): add --account flag for multi-account delivery routing Add support for explicit delivery account routing in cron jobs across CLI, normalization, delivery planning, and isolated delivery target resolution. Highlights: - Add --account <id> to cron add and cron edit - Add optional delivery.accountId to cron types and delivery plan - Normalize and trim delivery.accountId in cron create/update normalization - Prefer explicit accountId over session lastAccountId and bindings fallback - Thread accountId through isolated cron run delivery resolution - Preserve cron edit --best-effort-deliver/--no-best-effort-deliver behavior by keeping implicit announce mode - Expand tests for account passthrough/merge/precedence and CLI account flows * cron: resolve rebase duplicate accountId fields --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -92,6 +92,7 @@ export function registerCronAddCommand(cron: Command) {
|
||||
"--to <dest>",
|
||||
"Delivery destination (E.164, Telegram chatId, or Discord channel/user)",
|
||||
)
|
||||
.option("--account <id>", "Channel account id for delivery (multi-account setups)")
|
||||
.option("--best-effort-deliver", "Do not fail the job if delivery fails", false)
|
||||
.option("--json", "Output JSON", false)
|
||||
.action(async (opts: GatewayRpcOpts & Record<string, unknown>, cmd?: Command) => {
|
||||
@@ -221,6 +222,15 @@ export function registerCronAddCommand(cron: Command) {
|
||||
throw new Error("--announce/--no-deliver require --session isolated.");
|
||||
}
|
||||
|
||||
const accountId =
|
||||
typeof opts.account === "string" && opts.account.trim()
|
||||
? opts.account.trim()
|
||||
: undefined;
|
||||
|
||||
if (accountId && (sessionTarget !== "isolated" || payload.kind !== "agentTurn")) {
|
||||
throw new Error("--account requires an isolated agentTurn job with delivery.");
|
||||
}
|
||||
|
||||
const deliveryMode =
|
||||
sessionTarget === "isolated" && payload.kind === "agentTurn"
|
||||
? hasAnnounce
|
||||
@@ -265,6 +275,7 @@ export function registerCronAddCommand(cron: Command) {
|
||||
? opts.channel.trim()
|
||||
: undefined,
|
||||
to: typeof opts.to === "string" && opts.to.trim() ? opts.to.trim() : undefined,
|
||||
accountId,
|
||||
bestEffort: opts.bestEffortDeliver ? true : undefined,
|
||||
}
|
||||
: undefined,
|
||||
|
||||
@@ -59,6 +59,7 @@ export function registerCronEditCommand(cron: Command) {
|
||||
"--to <dest>",
|
||||
"Delivery destination (E.164, Telegram chatId, or Discord channel/user)",
|
||||
)
|
||||
.option("--account <id>", "Channel account id for delivery (multi-account setups)")
|
||||
.option("--best-effort-deliver", "Do not fail job if delivery fails")
|
||||
.option("--no-best-effort-deliver", "Fail job when delivery fails")
|
||||
.action(async (id, opts) => {
|
||||
@@ -209,6 +210,7 @@ export function registerCronEditCommand(cron: Command) {
|
||||
const hasTimeoutSeconds = Boolean(timeoutSeconds && Number.isFinite(timeoutSeconds));
|
||||
const hasDeliveryModeFlag = opts.announce || typeof opts.deliver === "boolean";
|
||||
const hasDeliveryTarget = typeof opts.channel === "string" || typeof opts.to === "string";
|
||||
const hasDeliveryAccount = typeof opts.account === "string";
|
||||
const hasBestEffort = typeof opts.bestEffortDeliver === "boolean";
|
||||
const hasAgentTurnPatch =
|
||||
typeof opts.message === "string" ||
|
||||
@@ -217,6 +219,7 @@ export function registerCronEditCommand(cron: Command) {
|
||||
hasTimeoutSeconds ||
|
||||
hasDeliveryModeFlag ||
|
||||
hasDeliveryTarget ||
|
||||
hasDeliveryAccount ||
|
||||
hasBestEffort;
|
||||
if (hasSystemEventPatch && hasAgentTurnPatch) {
|
||||
throw new Error("Choose at most one payload change");
|
||||
@@ -235,14 +238,14 @@ export function registerCronEditCommand(cron: Command) {
|
||||
patch.payload = payload;
|
||||
}
|
||||
|
||||
if (hasDeliveryModeFlag || hasDeliveryTarget || hasBestEffort) {
|
||||
const deliveryMode =
|
||||
opts.announce || opts.deliver === true
|
||||
? "announce"
|
||||
: opts.deliver === false
|
||||
? "none"
|
||||
: "announce";
|
||||
const delivery: Record<string, unknown> = { mode: deliveryMode };
|
||||
if (hasDeliveryModeFlag || hasDeliveryTarget || hasDeliveryAccount || hasBestEffort) {
|
||||
const delivery: Record<string, unknown> = {};
|
||||
if (hasDeliveryModeFlag) {
|
||||
delivery.mode = opts.announce || opts.deliver === true ? "announce" : "none";
|
||||
} else if (hasBestEffort) {
|
||||
// Back-compat: toggling best-effort alone has historically implied announce mode.
|
||||
delivery.mode = "announce";
|
||||
}
|
||||
if (typeof opts.channel === "string") {
|
||||
const channel = opts.channel.trim();
|
||||
delivery.channel = channel ? channel : undefined;
|
||||
@@ -251,6 +254,10 @@ export function registerCronEditCommand(cron: Command) {
|
||||
const to = opts.to.trim();
|
||||
delivery.to = to ? to : undefined;
|
||||
}
|
||||
if (typeof opts.account === "string") {
|
||||
const account = opts.account.trim();
|
||||
delivery.accountId = account ? account : undefined;
|
||||
}
|
||||
if (typeof opts.bestEffortDeliver === "boolean") {
|
||||
delivery.bestEffort = opts.bestEffortDeliver;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user