mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:30:42 +00:00
feat(cron): add agentId filtering to cron list
This commit is contained in:
@@ -23,7 +23,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Plugins/active-memory: skip session-store channel entries that contain `:` when resolving the recall subagent's channel, so QQ c2c agent IDs (e.g. `c2c:10D4F7C2…`) and other scoped conversation IDs do not reach bundled-plugin `dirName` validation and crash the recall run. The same guard already applied to explicit `channelId` params (#76704); this extends it to store-derived channels. (#77396) Thanks @hclsys.
|
||||
- Secrets/external channel contracts: also look in `<rootDir>/dist/` when resolving the `secret-contract-api` sidecar, so npm-published externalized channel plugins (e.g. `@openclaw/discord` since 2026.5.2) whose compiled artifacts live under `dist/` actually contribute their channel SecretRef contracts to the runtime snapshot. Without this, env-backed `channels.discord.token` SecretRefs silently failed to resolve at gateway start on 2026.5.3, leaving the channel `not configured` even though #76449 had landed the generic external-contract loader. Thanks @mogglemoss.
|
||||
- Models/auth: add `openclaw models auth list [--provider <id>] [--json]` so users can inspect saved per-agent auth profiles without dumping secrets or hitting the old “too many arguments” path. Thanks @vincentkoc.
|
||||
- Cron CLI: add `openclaw cron list --agent <id>` and normalize the requested agent id before filtering, while keeping `cron list` unfiltered when no agent is supplied. Fixes #77118. Thanks @zhanggttry.
|
||||
- Cron CLI: add `openclaw cron list --agent <id>`, normalize the requested agent id, and include jobs without a stored agent id under the configured default agent while keeping `cron list` unfiltered when no agent is supplied. Fixes #77118. Thanks @zhanggttry.
|
||||
- Control UI/header: show the active agent name in dashboard breadcrumbs without adding the current session key, keeping non-chat views oriented without crowding the topbar.
|
||||
- Control UI/cron: make the New Job sidebar collapsible so the jobs list can reclaim space while keeping the form one click away. Thanks @BunsDev.
|
||||
- Gateway/startup: keep model-catalog test helpers, run-session lookup code, QR pairing helpers, and TypeBox memory-tool schema construction out of hot startup import paths, reducing default gateway benchmark plugin-load and memory pressure.
|
||||
|
||||
@@ -218,7 +218,7 @@ openclaw cron run <job-id> --due
|
||||
openclaw cron runs --id <job-id> --limit 50
|
||||
```
|
||||
|
||||
`openclaw cron list` shows all matching jobs by default. Pass `--agent <id>` to show only jobs pinned to that normalized agent id.
|
||||
`openclaw cron list` shows all matching jobs by default. Pass `--agent <id>` to show only jobs whose effective normalized agent id matches; jobs without a stored agent id count as the configured default agent.
|
||||
|
||||
`cron runs` entries include delivery diagnostics with the intended cron target, the resolved target, message-tool sends, fallback use, and delivered state.
|
||||
|
||||
|
||||
@@ -64,6 +64,33 @@ describe("cron listPage sort guards", () => {
|
||||
expect(page.jobs.map((job) => job.id)).toEqual(["job-ops"]);
|
||||
});
|
||||
|
||||
it("matches omitted job agent ids to the configured default agent when filtering", async () => {
|
||||
const jobs = [
|
||||
createBaseJob({ id: "job-main", agentId: "main", name: "main" }),
|
||||
createBaseJob({ id: "job-ops", agentId: "ops", name: "ops" }),
|
||||
createBaseJob({ id: "job-unset", agentId: undefined, name: "unset" }),
|
||||
];
|
||||
const state = createMockCronStateForJobs({ jobs });
|
||||
state.deps.defaultAgentId = " Ops ";
|
||||
|
||||
const page = await listPage(state, { agentId: "ops" });
|
||||
|
||||
expect(page.jobs.map((job) => job.id)).toEqual(["job-ops", "job-unset"]);
|
||||
});
|
||||
|
||||
it("matches omitted job agent ids to main when no default agent is configured", async () => {
|
||||
const jobs = [
|
||||
createBaseJob({ id: "job-main", agentId: "main", name: "main" }),
|
||||
createBaseJob({ id: "job-ops", agentId: "ops", name: "ops" }),
|
||||
createBaseJob({ id: "job-unset", agentId: undefined, name: "unset" }),
|
||||
];
|
||||
const state = createMockCronStateForJobs({ jobs });
|
||||
|
||||
const page = await listPage(state, { agentId: "main" });
|
||||
|
||||
expect(page.jobs.map((job) => job.id)).toEqual(["job-main", "job-unset"]);
|
||||
});
|
||||
|
||||
it("keeps listPage unfiltered when agent id is omitted", async () => {
|
||||
const jobs = [
|
||||
createBaseJob({ id: "job-main", agentId: "main", name: "main" }),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { enqueueCommandInLane } from "../../process/command-queue.js";
|
||||
import { CommandLane } from "../../process/lanes.js";
|
||||
import { DEFAULT_AGENT_ID } from "../../routing/session-key.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
completeTaskRunByRunId,
|
||||
@@ -273,6 +274,14 @@ function sortJobs(jobs: CronJob[], sortBy: CronJobsSortBy, sortDir: CronSortDir)
|
||||
});
|
||||
}
|
||||
|
||||
function resolveEffectiveJobAgentId(job: CronJob, defaultAgentId: string | undefined) {
|
||||
return (
|
||||
normalizeOptionalAgentId(job.agentId) ??
|
||||
normalizeOptionalAgentId(defaultAgentId) ??
|
||||
DEFAULT_AGENT_ID
|
||||
);
|
||||
}
|
||||
|
||||
export async function listPage(state: CronServiceState, opts?: CronListPageOptions) {
|
||||
return await locked(state, async () => {
|
||||
await ensureLoadedForRead(state);
|
||||
@@ -289,7 +298,10 @@ export async function listPage(state: CronServiceState, opts?: CronListPageOptio
|
||||
if (enabledFilter === "disabled" && isJobEnabled(job)) {
|
||||
return false;
|
||||
}
|
||||
if (requestedAgentId && job.agentId !== requestedAgentId) {
|
||||
if (
|
||||
requestedAgentId &&
|
||||
resolveEffectiveJobAgentId(job, state.deps.defaultAgentId) !== requestedAgentId
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (!query) {
|
||||
|
||||
Reference in New Issue
Block a user