Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Reference specific personas when requesting work:
## Learned User Preferences

- When preparing a merge to `main` or a release, keep `docs/CHANGELOG.md` **Unreleased** accurate; on request, align listed dependency or tooling changes with the delta since the previous git tag (including `pyproject.toml`).
- Prefer `docs/CHANGELOG.md` `Unreleased` entries grouped into `Added` / `Changed` / `Fixed` (instead of custom feature headings).
- Dependabot PRs should target `develop`, not `main` (set `target-branch: "develop"` in `.github/dependabot.yml`).

## Learned Workspace Facts

Expand Down
16 changes: 16 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,26 @@ All notable changes to this project will be documented in this file.
### Changed

- **FastAPI lifespan cleanup** — Controller shutdown now cancels the scheduled-step background loop and waits briefly for it to stop.
- **Supervaizer v2 agent methods** — SDK agents can now declare optional standard actions such as `agent.refresh` plus custom agent actions through the same `AgentMethods` structure used for job methods, and the A2A runtime registers those handlers automatically.

### Tests

- `tests/test_server.py` — scheduler task cancellation and bounded shutdown waiting during FastAPI lifespan shutdown.
- `tests/test_a2a.py` — standard and custom agent method dispatch through the v2 A2A controller.
- `tests/test_agent.py` — agent-level v2 method registration and contract validation.
- `tests/test_contracts.py` — typed agent method contract serialization.

### Tests

- `tests/test_common.py` — structured JSON log output for API access-denial records
- `just test`

| Status | Count |
| ---------- | ----- |
| ✅ Passed | 663 |
| 🤔 Skipped | 0 |
| 🔴 Failed | 0 |
| ⏱️ in | 136s |

## [1.1.1] - 2026-05-20

Expand Down
53 changes: 53 additions & 0 deletions src/supervaizer/scheduled_steps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved.
#
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, you can obtain one at
# https://mozilla.org/MPL/2.0/.

from __future__ import annotations

import asyncio
from typing import TYPE_CHECKING, Any

from supervaizer.common import log

if TYPE_CHECKING:
from supervaizer.server import Server

SCHEDULED_STEP_POLL_SECONDS = 60


def _execute_scheduled_method(method_path: str, params: dict[str, Any]) -> Any:
"""Execute a method by its full dotted path."""
module_name, func_name = method_path.rsplit(".", 1)
module = __import__(module_name, fromlist=[func_name])
method = getattr(module, func_name)
return method(**params)


async def _run_scheduled_step_loop(server: Server) -> None:
"""Poll for due scheduled steps and execute them."""
from supervaizer.case import Cases

while True:
await asyncio.sleep(SCHEDULED_STEP_POLL_SECONDS)
try:
cases = Cases()
due_steps = cases.get_due_scheduled_steps()
for _case, _step_index, update in due_steps:
if not update.scheduled_method:
continue
try:
object.__setattr__(update, "scheduled_status", "executing")
log.info(f"[Scheduled step] Executing: {update.name}")
_execute_scheduled_method(
update.scheduled_method,
update.scheduled_params or {},
)
object.__setattr__(update, "scheduled_status", "completed")
log.info(f"[Scheduled step] Completed: {update.name}")
except Exception as exc:
object.__setattr__(update, "scheduled_status", "failed")
log.error(f"[Scheduled step] Failed: {update.name}: {exc}")
except Exception as exc:
log.error(f"[Scheduled step loop] Error: {exc}")
Loading
Loading