fix(flow): activate schedules via Scheduler Service (#479, 0.66.1)#480
fix(flow): activate schedules via Scheduler Service (#479, 0.66.1)#480natocTo wants to merge 3 commits into
Conversation
flow schedule only wrote the keboola.scheduler Storage config, so the
schedule showed enabled but the cron trigger never fired until re-saved
in the UI. Register the config with the Scheduler Service after the
upsert (POST /schedules) and deregister it in schedule-remove
(DELETE /configurations/{id}) before deleting the config. Activation
failure is non-fatal: the config stays written, the result carries
activated=false plus a warning, and the exit code stays 0.
Deduplicate the scheduler-config target matching used by list_flow_schedules, set_flow_schedule, and remove_flow_schedule into _schedules_targeting_flow, skip SchedulerClient construction in remove_flow_schedule when no schedule targets the flow, and trim scheduler_client docstrings to match sibling clients.
a00df6d to
096dcdc
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes a functional gap in kbagent flow schedule / flow schedule-remove by adding a Scheduler Service HTTP client and wiring Flow schedule writes/removals to also register/deregister the schedule on the Scheduler Service, aligning CLI behavior with the UI and preventing “enabled but never fires” schedules.
Changes:
- Add
SchedulerClientand integrate it intoFlowServiceso schedules are activated (POST /schedules) after upsert and deregistered (DELETE /configurations/{id}) before deletion. - Extend CLI output/result payloads to include
activatedandwarnings(human + JSON) without changing command signatures. - Add/expand tests and update changelog + embedded plugin/docs to document the new behavior and version gate (0.66.1).
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Bumps locked project version to 0.66.1. |
| pyproject.toml | Bumps package version to 0.66.1. |
| src/keboola_agent_cli/scheduler_client.py | New Scheduler Service client for activation/removal calls. |
| src/keboola_agent_cli/services/flow_service.py | Calls Scheduler Service on schedule upsert/remove; returns activated + warnings. |
| src/keboola_agent_cli/services/schedule_service.py | Updates docstring to clarify read vs write paths (Scheduler Service required for activation). |
| src/keboola_agent_cli/commands/flow.py | Prints activation state and warnings for flow schedule and flow schedule-remove. |
| src/keboola_agent_cli/commands/context.py | Updates command help text to reflect activation/deregistration semantics and warnings behavior. |
| src/keboola_agent_cli/changelog.py | Adds 0.66.1 entries describing the fix and migration note. |
| tests/test_scheduler_client.py | New unit tests for URL derivation, request envelope, headers, and error mapping. |
| tests/test_flow_service.py | Adds service-layer tests covering activation/deregistration, warning behavior, and tolerated 404. |
| tests/test_flow_cli.py | Adds CLI tests ensuring warnings are surfaced in human + JSON mode, exit code remains 0. |
| plugins/kbagent/skills/kbagent/references/gotchas.md | Documents the 0.66.1 behavior + migration/version gate. |
| plugins/kbagent/skills/kbagent/references/commands-reference.md | Updates command reference to mention activation/deregistration since v0.66.1. |
| plugins/kbagent/agents/keboola-expert.md | Adds gotcha/version gate guidance for the expert agent. |
| plugins/kbagent/.claude-plugin/plugin.json | Bumps plugin version to 0.66.1. |
| CLAUDE.md | Updates internal command notes with new schedule activation behavior. |
| .claude-plugin/marketplace.json | Bumps marketplace plugin version reference to 0.66.1. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| warnings.append( | ||
| f"Schedule config {schedule_id} was {status} but could not be " | ||
| f"activated on the Scheduler Service: {exc.message}. The cron " | ||
| "trigger will NOT fire until activation succeeds -- re-run this " | ||
| "command with a token that can manage schedules." | ||
| ) |
There was a problem hiding this comment.
Agreed — for an update of a previously registered schedule the service keeps serving the old registration, so "will NOT fire" was an overclaim (it was only accurate for the initial-create case). Reworded in fd558b5 to "The service may not reflect the updated configuration until activation succeeds" and updated the service test assertion accordingly.
Say 'deactivated' instead of 'activated' in the success line when --disabled was used, and soften the activation-failure warning: a previously registered schedule may keep running with its old state, so the service 'may not reflect the updated configuration' rather than 'will NOT fire'.
Why
Closes #479.
kbagent flow scheduleonly wrote thekeboola.schedulerStorage configuration and never called the Scheduler Service, so the schedule showedstate: enabledbut the cron trigger never fired until the schedule was re-saved in the UI.flow schedule-removehad the mirror problem: it deleted the Storage config but left the service-side registration behind. The failure was silent — the command reported success.What changed
flow schedulenow registers the config with the Scheduler Service (POST /schedules) after the upsert — also for--disabled, which deregisters the trigger. The result carriesactivated: true/falseandwarnings.Warning: ...; JSON:warningsarray), exit code stays 0.flow schedule-removederegisters each schedule from the service (DELETE /configurations/{id}, 404 tolerated) before deleting its Storage config.flow_service.py,schedule_service.py,AGENT_CONTEXT).Layers
scheduler_client.py—SchedulerClient(BaseHttpClient), URL derivedconnection.→scheduler., authX-StorageApi-Token, methodsactivate_schedule/remove_schedule. Modeled onai_client.py.FlowServicegains an injectedscheduler_client_factory(same DI pattern asai_client_factory);set_flow_schedule/remove_flow_schedulecall the service after/before the Storage writes.commands/flow.pyprints activation state and warnings; no signature changes.permissions.py/server/routers/ SKILL.md table changes (routes call the same service and inherit the fix).Tests & docs
tests/test_scheduler_client.py(pytest-httpx: URL derivation, request envelopes, auth header, 403/404 mapping).test_flow_service.py: activation after create AND update,--disabledstill calls the service, 403 →activated: false+ warning without raising, remove deregisters beforedelete_config, 404 tolerated, other failures warn but don't block.test_flow_cli.py: warnings in human + JSON output, exit stays 0.make checkgreen: 4236 passed, lint/format/ty/command-sync/error-codes clean.changelog.py(0.66.1),CLAUDE.md,AGENT_CONTEXT,commands-reference.md,gotchas.md(since v0.66.1entry incl. the 'schedules created by older versions stay dormant' migration note),keboola-expert.md§3 gotcha + VERSION GATE.Verification (real stack)
Manual smoke test against a dev project on
connection.north-europe.azure.keboola.com:flow schedule --cron '0 6 * * *'→activated: true;GET {scheduler_url}/schedulesconfirmed the registration exists on the service (previously it did not, which is exactly the bug).flow schedule-remove --yes→ config deleted ANDGET /schedulesshows the registration is gone.self-review skipped: kbagent Claude Code plugin not installed in this environment.