2026-06-12 01:58:46 +02:00
|
|
|
# retoor <retoor@molodetz.nl>
|
|
|
|
|
|
2026-05-11 07:02:06 +02:00
|
|
|
import asyncio
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
import json
|
2026-05-11 07:02:06 +02:00
|
|
|
import logging
|
|
|
|
|
from abc import ABC, abstractmethod
|
|
|
|
|
from collections import deque
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
|
|
|
|
|
|
from devplacepy.database import db, get_table, get_setting, get_int_setting
|
2026-05-11 07:02:06 +02:00
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
class ConfigField:
|
2026-06-09 18:48:08 +02:00
|
|
|
def __init__(
|
|
|
|
|
self,
|
|
|
|
|
key,
|
|
|
|
|
label,
|
|
|
|
|
type="str",
|
|
|
|
|
default="",
|
|
|
|
|
help="",
|
|
|
|
|
options=None,
|
|
|
|
|
secret=False,
|
|
|
|
|
minimum=None,
|
|
|
|
|
maximum=None,
|
|
|
|
|
group="General",
|
|
|
|
|
):
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.key = key
|
|
|
|
|
self.label = label
|
|
|
|
|
self.type = type
|
|
|
|
|
self.default = default
|
|
|
|
|
self.help = help
|
|
|
|
|
self.options = options or []
|
|
|
|
|
self.secret = secret
|
|
|
|
|
self.minimum = minimum
|
|
|
|
|
self.maximum = maximum
|
|
|
|
|
self.group = group
|
|
|
|
|
|
|
|
|
|
def coerce(self, raw):
|
|
|
|
|
if self.type == "int":
|
|
|
|
|
try:
|
|
|
|
|
value = int(str(raw).strip())
|
|
|
|
|
except (TypeError, ValueError):
|
|
|
|
|
raise ValueError(f"{self.label} must be a whole number")
|
|
|
|
|
if self.minimum is not None and value < self.minimum:
|
|
|
|
|
raise ValueError(f"{self.label} must be at least {self.minimum}")
|
|
|
|
|
if self.maximum is not None and value > self.maximum:
|
|
|
|
|
raise ValueError(f"{self.label} must be at most {self.maximum}")
|
|
|
|
|
return value
|
|
|
|
|
if self.type == "float":
|
|
|
|
|
try:
|
|
|
|
|
value = float(str(raw).strip())
|
|
|
|
|
except (TypeError, ValueError):
|
|
|
|
|
raise ValueError(f"{self.label} must be a number")
|
|
|
|
|
if self.minimum is not None and value < self.minimum:
|
|
|
|
|
raise ValueError(f"{self.label} must be at least {self.minimum}")
|
|
|
|
|
if self.maximum is not None and value > self.maximum:
|
|
|
|
|
raise ValueError(f"{self.label} must be at most {self.maximum}")
|
|
|
|
|
return value
|
|
|
|
|
if self.type == "bool":
|
|
|
|
|
text = str(raw).strip()
|
|
|
|
|
if text in ("0", "1"):
|
|
|
|
|
return text == "1"
|
|
|
|
|
raise ValueError(f"{self.label} must be enabled or disabled")
|
|
|
|
|
if self.type == "select":
|
|
|
|
|
allowed = [option["value"] for option in self.options]
|
|
|
|
|
if raw not in allowed:
|
|
|
|
|
raise ValueError(f"{self.label} has an invalid selection")
|
|
|
|
|
return raw
|
|
|
|
|
if self.type == "url":
|
|
|
|
|
text = str(raw).strip()
|
|
|
|
|
if text and not (text.startswith("http://") or text.startswith("https://")):
|
|
|
|
|
raise ValueError(f"{self.label} must be a http(s) URL")
|
|
|
|
|
return text
|
|
|
|
|
return str(raw)
|
|
|
|
|
|
|
|
|
|
def to_storage(self, value):
|
|
|
|
|
if isinstance(value, bool):
|
|
|
|
|
return "1" if value else "0"
|
|
|
|
|
return str(value)
|
|
|
|
|
|
|
|
|
|
def read(self):
|
|
|
|
|
raw = get_setting(self.key, "")
|
|
|
|
|
if raw == "":
|
|
|
|
|
return self.default
|
|
|
|
|
try:
|
|
|
|
|
return self.coerce(raw)
|
|
|
|
|
except ValueError:
|
|
|
|
|
return self.default
|
|
|
|
|
|
|
|
|
|
def display_value(self):
|
|
|
|
|
if self.secret:
|
|
|
|
|
return ""
|
|
|
|
|
raw = get_setting(self.key, "")
|
|
|
|
|
if raw == "":
|
|
|
|
|
return self.to_storage(self.default)
|
|
|
|
|
return raw
|
|
|
|
|
|
|
|
|
|
def spec(self):
|
|
|
|
|
return {
|
|
|
|
|
"key": self.key,
|
|
|
|
|
"label": self.label,
|
|
|
|
|
"type": self.type,
|
|
|
|
|
"help": self.help,
|
|
|
|
|
"options": self.options,
|
|
|
|
|
"secret": self.secret,
|
|
|
|
|
"minimum": self.minimum,
|
|
|
|
|
"maximum": self.maximum,
|
|
|
|
|
"value": self.display_value(),
|
|
|
|
|
"is_set": bool(get_setting(self.key, "")) if self.secret else None,
|
|
|
|
|
"group": self.group,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-05-11 07:02:06 +02:00
|
|
|
class BaseService(ABC):
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
config_fields = []
|
|
|
|
|
interval_key = None
|
|
|
|
|
min_interval = 1
|
|
|
|
|
default_enabled = True
|
|
|
|
|
title = ""
|
|
|
|
|
description = ""
|
feat: add featured/locked columns and auto-rotation logic to news pipeline
- Add `ai_grade`, `featured`, `featured_locked`, `landing_locked`, `author`, `article_published`, `image_url`, `has_unique_image` columns to news table
- Extend `news_images` schema with `alt_text`, `phash`, `width`, `height`, `is_placeholder` columns
- Create `idx_news_featured` index for efficient featured queries
- Update admin toggle endpoints to set `featured_locked`/`landing_locked` when manually toggling
- Propagate `featured` and `image_url` fields through landing page, news list, and detail page rendering
- Update `get_featured_news` to return `featured` and `image_url` fields
- Document in AGENTS.md the full zero-maintenance pipeline: image perceptual hashing, placeholder detection, AI grading on cleaned text, reliability gate, effective score computation, and post-loop landing rotation
- Update README.md service description to reflect automatic image comparison and landing rotation capabilities
- Clarify docs_api.py summaries that toggling featured/landing now locks articles from auto-rotation
2026-06-19 00:08:41 +02:00
|
|
|
details = ""
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
DEFAULT_LOG_SIZE = 20
|
|
|
|
|
TICK_SECONDS = 1
|
2026-07-19 18:57:43 +02:00
|
|
|
PERSIST_SECONDS = 8
|
|
|
|
|
METRICS_SECONDS = 15
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
STALE_SECONDS = 15
|
|
|
|
|
|
2026-05-11 07:02:06 +02:00
|
|
|
def __init__(self, name: str, interval_seconds: int = 3600):
|
|
|
|
|
self.name = name
|
|
|
|
|
self.interval_seconds = interval_seconds
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.interval_key = self.interval_key or f"service_{name}_interval"
|
|
|
|
|
self.enabled_key = f"service_{name}_enabled"
|
|
|
|
|
self.command_key = f"service_{name}_command"
|
|
|
|
|
self.log_size_key = f"service_{name}_log_size"
|
|
|
|
|
self.log_buffer = deque(maxlen=self.DEFAULT_LOG_SIZE)
|
2026-05-11 07:02:06 +02:00
|
|
|
self._task = None
|
|
|
|
|
self._running = False
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self._shutdown = False
|
|
|
|
|
self._started_at = None
|
2026-05-11 07:02:06 +02:00
|
|
|
self._last_run = None
|
|
|
|
|
self._next_run = None
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self._next_due = None
|
|
|
|
|
self._run_pending = False
|
|
|
|
|
self._last_command = None
|
|
|
|
|
self._last_persist = None
|
2026-07-19 18:57:43 +02:00
|
|
|
self._last_metrics = None
|
|
|
|
|
self._metrics_snapshot = {}
|
|
|
|
|
self._state_row_id = None
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.enabled_field = ConfigField(
|
2026-06-09 18:48:08 +02:00
|
|
|
self.enabled_key,
|
|
|
|
|
"Enabled",
|
|
|
|
|
type="bool",
|
|
|
|
|
default=self.default_enabled,
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
help="When enabled the service runs on its interval and starts on boot.",
|
2026-06-09 18:48:08 +02:00
|
|
|
group="General",
|
|
|
|
|
)
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.interval_field = ConfigField(
|
2026-06-09 18:48:08 +02:00
|
|
|
self.interval_key,
|
|
|
|
|
"Run interval (seconds)",
|
|
|
|
|
type="int",
|
|
|
|
|
default=interval_seconds,
|
|
|
|
|
minimum=self.min_interval,
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
help=f"Delay between runs. Minimum {self.min_interval} seconds.",
|
2026-06-09 18:48:08 +02:00
|
|
|
group="General",
|
|
|
|
|
)
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.log_size_field = ConfigField(
|
2026-06-09 18:48:08 +02:00
|
|
|
self.log_size_key,
|
|
|
|
|
"Log buffer size",
|
|
|
|
|
type="int",
|
|
|
|
|
default=self.DEFAULT_LOG_SIZE,
|
|
|
|
|
minimum=1,
|
|
|
|
|
maximum=200,
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
help="Number of recent log lines to keep.",
|
2026-06-09 18:48:08 +02:00
|
|
|
group="Advanced",
|
|
|
|
|
)
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
|
|
|
|
|
def all_fields(self) -> list:
|
2026-06-09 18:48:08 +02:00
|
|
|
return [
|
|
|
|
|
self.enabled_field,
|
|
|
|
|
self.interval_field,
|
|
|
|
|
*self.config_fields,
|
|
|
|
|
self.log_size_field,
|
|
|
|
|
]
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
|
|
|
|
|
def _grouped_fields(self) -> list:
|
|
|
|
|
groups: dict = {}
|
|
|
|
|
order: list = []
|
|
|
|
|
for field in self.all_fields():
|
|
|
|
|
spec = field.spec()
|
|
|
|
|
group = spec["group"]
|
|
|
|
|
if group not in groups:
|
|
|
|
|
groups[group] = []
|
|
|
|
|
order.append(group)
|
|
|
|
|
groups[group].append(spec)
|
|
|
|
|
return [{"name": name, "fields": groups[name]} for name in order]
|
2026-05-11 07:02:06 +02:00
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def status(self) -> str:
|
|
|
|
|
return "running" if self._running else "stopped"
|
|
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
def is_enabled(self) -> bool:
|
2026-06-09 18:48:08 +02:00
|
|
|
return (
|
|
|
|
|
get_setting(self.enabled_key, "1" if self.default_enabled else "0") == "1"
|
|
|
|
|
)
|
2026-05-11 07:02:06 +02:00
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
def current_interval(self) -> int:
|
2026-06-09 18:48:08 +02:00
|
|
|
return max(
|
|
|
|
|
self.min_interval, get_int_setting(self.interval_key, self.interval_seconds)
|
|
|
|
|
)
|
2026-05-11 07:02:06 +02:00
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
def get_config(self) -> dict:
|
|
|
|
|
return {field.key: field.read() for field in self.all_fields()}
|
2026-05-11 07:02:06 +02:00
|
|
|
|
|
|
|
|
def log(self, message: str) -> None:
|
2026-05-14 04:12:19 +02:00
|
|
|
stamp = datetime.now(timezone.utc).strftime("%H:%M:%S")
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.log_buffer.append(f"[{stamp}] {message}")
|
2026-05-11 07:02:06 +02:00
|
|
|
logger.info(f"[{self.name}] {message}")
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
async def run_once(self) -> None:
|
|
|
|
|
pass
|
|
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
async def on_enable(self) -> None:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
async def on_disable(self) -> None:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def collect_metrics(self) -> dict:
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
def _safe_metrics(self) -> dict:
|
|
|
|
|
try:
|
|
|
|
|
return self.collect_metrics()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.warning(f"Could not collect metrics for {self.name}: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
2026-07-19 18:57:43 +02:00
|
|
|
def _current_metrics(self, now, force: bool = False) -> dict:
|
|
|
|
|
if not force and self._last_metrics is not None:
|
|
|
|
|
if (now - self._last_metrics).total_seconds() < self.METRICS_SECONDS:
|
|
|
|
|
return self._metrics_snapshot
|
|
|
|
|
self._last_metrics = now
|
|
|
|
|
self._metrics_snapshot = self._safe_metrics()
|
|
|
|
|
return self._metrics_snapshot
|
|
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
def start_supervisor(self) -> None:
|
|
|
|
|
if self._task is not None:
|
|
|
|
|
return
|
|
|
|
|
self._shutdown = False
|
|
|
|
|
self._task = asyncio.create_task(self._run_loop())
|
|
|
|
|
|
|
|
|
|
def request_shutdown(self) -> None:
|
|
|
|
|
self._shutdown = True
|
|
|
|
|
|
2026-05-11 07:02:06 +02:00
|
|
|
async def _run_loop(self) -> None:
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self._last_command = get_setting(self.command_key, "")
|
|
|
|
|
self.log("Supervisor started")
|
|
|
|
|
self._persist_state(force=True)
|
|
|
|
|
while not self._shutdown:
|
2026-05-11 07:02:06 +02:00
|
|
|
try:
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
await self._tick()
|
2026-05-11 07:02:06 +02:00
|
|
|
except asyncio.CancelledError:
|
|
|
|
|
break
|
|
|
|
|
except Exception as e:
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self.log(f"Loop error: {e}")
|
2026-05-11 07:02:06 +02:00
|
|
|
try:
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
await asyncio.sleep(self.TICK_SECONDS)
|
2026-05-11 07:02:06 +02:00
|
|
|
except asyncio.CancelledError:
|
|
|
|
|
break
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
if self._started_at is not None:
|
|
|
|
|
await self._safe_disable()
|
2026-05-11 07:02:06 +02:00
|
|
|
self._running = False
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self._started_at = None
|
|
|
|
|
self._persist_state(force=True)
|
|
|
|
|
self.log("Supervisor stopped")
|
2026-05-11 07:02:06 +02:00
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
async def _tick(self) -> None:
|
|
|
|
|
self._sync_log_size()
|
|
|
|
|
self._handle_commands()
|
|
|
|
|
if self.is_enabled():
|
|
|
|
|
if self._started_at is None:
|
|
|
|
|
self._started_at = datetime.now(timezone.utc)
|
|
|
|
|
self._running = True
|
|
|
|
|
self.log("Service enabled")
|
|
|
|
|
await self.on_enable()
|
|
|
|
|
due = self._next_due is None or datetime.now(timezone.utc) >= self._next_due
|
|
|
|
|
if self._run_pending or due:
|
|
|
|
|
self._run_pending = False
|
|
|
|
|
await self._execute_run()
|
|
|
|
|
elif self._started_at is not None:
|
|
|
|
|
await self._safe_disable()
|
|
|
|
|
self._started_at = None
|
|
|
|
|
self._running = False
|
|
|
|
|
self._next_due = None
|
|
|
|
|
self._next_run = None
|
|
|
|
|
self.log("Service disabled")
|
|
|
|
|
self._persist_state()
|
|
|
|
|
|
|
|
|
|
async def _safe_disable(self) -> None:
|
|
|
|
|
try:
|
|
|
|
|
await self.on_disable()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.log(f"on_disable error: {e}")
|
|
|
|
|
|
|
|
|
|
async def _execute_run(self) -> None:
|
|
|
|
|
self.interval_seconds = self.current_interval()
|
|
|
|
|
self._last_run = datetime.now(timezone.utc).isoformat()
|
|
|
|
|
self._next_run = None
|
|
|
|
|
self._persist_state(force=True)
|
|
|
|
|
try:
|
|
|
|
|
await self.run_once()
|
|
|
|
|
except asyncio.CancelledError:
|
|
|
|
|
raise
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.log(f"Error in run_once: {e}")
|
|
|
|
|
self.interval_seconds = self.current_interval()
|
2026-06-09 18:48:08 +02:00
|
|
|
self._next_due = datetime.now(timezone.utc) + timedelta(
|
|
|
|
|
seconds=self.interval_seconds
|
|
|
|
|
)
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self._next_run = self._next_due.isoformat()
|
|
|
|
|
self.log(f"Next run in {self.interval_seconds}s")
|
|
|
|
|
self._persist_state(force=True)
|
2026-05-11 07:02:06 +02:00
|
|
|
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
def _handle_commands(self) -> None:
|
|
|
|
|
raw = get_setting(self.command_key, "")
|
|
|
|
|
if not raw or raw == self._last_command:
|
2026-05-11 07:02:06 +02:00
|
|
|
return
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
self._last_command = raw
|
|
|
|
|
verb = raw.split(":", 1)[0]
|
|
|
|
|
if verb == "run":
|
|
|
|
|
self._run_pending = True
|
|
|
|
|
self.log("Run requested")
|
|
|
|
|
elif verb == "clear":
|
|
|
|
|
self.log_buffer.clear()
|
|
|
|
|
self.log("Logs cleared")
|
|
|
|
|
|
|
|
|
|
def _sync_log_size(self) -> None:
|
|
|
|
|
size = max(1, get_int_setting(self.log_size_key, self.DEFAULT_LOG_SIZE))
|
|
|
|
|
if size != self.log_buffer.maxlen:
|
|
|
|
|
self.log_buffer = deque(self.log_buffer, maxlen=size)
|
|
|
|
|
|
|
|
|
|
def _persist_state(self, force: bool = False) -> None:
|
|
|
|
|
now = datetime.now(timezone.utc)
|
|
|
|
|
if not force and self._last_persist is not None:
|
|
|
|
|
if (now - self._last_persist).total_seconds() < self.PERSIST_SECONDS:
|
|
|
|
|
return
|
|
|
|
|
self._last_persist = now
|
|
|
|
|
record = {
|
|
|
|
|
"name": self.name,
|
|
|
|
|
"status": self.status,
|
|
|
|
|
"last_run": self._last_run or "",
|
|
|
|
|
"next_run": self._next_run or "",
|
|
|
|
|
"started_at": self._started_at.isoformat() if self._started_at else "",
|
|
|
|
|
"heartbeat": now.isoformat(),
|
|
|
|
|
"logs": json.dumps(list(self.log_buffer)),
|
2026-07-19 18:57:43 +02:00
|
|
|
"metrics": json.dumps(self._current_metrics(now, force=force)),
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
"updated_at": now.isoformat(),
|
|
|
|
|
}
|
|
|
|
|
try:
|
|
|
|
|
table = get_table("service_state")
|
2026-07-19 18:57:43 +02:00
|
|
|
if self._state_row_id is None:
|
|
|
|
|
existing = table.find_one(name=self.name)
|
|
|
|
|
self._state_row_id = existing["id"] if existing else None
|
|
|
|
|
if self._state_row_id is not None:
|
|
|
|
|
table.update({**record, "id": self._state_row_id}, ["id"])
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
else:
|
2026-07-19 18:57:43 +02:00
|
|
|
self._state_row_id = table.insert(record)
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
except Exception as e:
|
|
|
|
|
logger.warning(f"Could not persist state for {self.name}: {e}")
|
|
|
|
|
|
|
|
|
|
def _read_state(self) -> dict:
|
|
|
|
|
if "service_state" not in db.tables:
|
|
|
|
|
return {}
|
|
|
|
|
row = db["service_state"].find_one(name=self.name)
|
|
|
|
|
return row or {}
|
|
|
|
|
|
|
|
|
|
def _display_status(self, enabled: bool, state: dict) -> str:
|
|
|
|
|
if not enabled:
|
|
|
|
|
return "stopped"
|
|
|
|
|
heartbeat = state.get("heartbeat")
|
|
|
|
|
if not heartbeat:
|
|
|
|
|
return "stalled"
|
|
|
|
|
try:
|
|
|
|
|
beat = datetime.fromisoformat(heartbeat)
|
|
|
|
|
except ValueError:
|
|
|
|
|
return "stalled"
|
|
|
|
|
if (datetime.now(timezone.utc) - beat).total_seconds() > self.STALE_SECONDS:
|
|
|
|
|
return "stalled"
|
|
|
|
|
return "running"
|
|
|
|
|
|
|
|
|
|
def _uptime(self, state: dict, status: str) -> str | None:
|
|
|
|
|
if status != "running":
|
|
|
|
|
return None
|
|
|
|
|
started = state.get("started_at")
|
|
|
|
|
if not started:
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
since = datetime.fromisoformat(started)
|
|
|
|
|
except ValueError:
|
|
|
|
|
return None
|
|
|
|
|
return str(datetime.now(timezone.utc) - since).split(".")[0]
|
|
|
|
|
|
|
|
|
|
def _logs(self, state: dict) -> list:
|
|
|
|
|
raw = state.get("logs")
|
|
|
|
|
if not raw:
|
|
|
|
|
return []
|
|
|
|
|
try:
|
|
|
|
|
return json.loads(raw)
|
|
|
|
|
except (ValueError, TypeError):
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def _metrics(self, state: dict) -> dict:
|
|
|
|
|
raw = state.get("metrics")
|
|
|
|
|
if not raw:
|
feat: add author-username search to feed/gists/projects listings and partial-index migration
Extend `database.text_search_clause` with an `author_field` parameter that resolves username matches to user UIDs, enabling author-username search across the three public listings (`/feed`, `/gists`, `/projects`). Update the corresponding API docs and README route descriptions to reflect the new search scope. Add six partial indexes (`idx_comments_target_live`, `idx_votes_target_live`, `idx_reactions_target_live`, `idx_gists_live_created`, `idx_projects_live_created`, `idx_attachments_user_created_live`) to optimize filtered queries on non-deleted rows. Introduce a hot-settings cache (`_hot_settings`) with a 2-second TTL for `maintenance_mode`, `rate_limit_per_minute`, and `rate_limit_window_seconds`, plus a periodic rate-limit store sweep (`_sweep_rate_limit_store`) to evict stale IP entries every 60 seconds. Add `GZipMiddleware` to the FastAPI app for response compression.
2026-06-20 00:24:51 +02:00
|
|
|
return self._safe_metrics()
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
try:
|
|
|
|
|
return json.loads(raw)
|
|
|
|
|
except (ValueError, TypeError):
|
feat: add author-username search to feed/gists/projects listings and partial-index migration
Extend `database.text_search_clause` with an `author_field` parameter that resolves username matches to user UIDs, enabling author-username search across the three public listings (`/feed`, `/gists`, `/projects`). Update the corresponding API docs and README route descriptions to reflect the new search scope. Add six partial indexes (`idx_comments_target_live`, `idx_votes_target_live`, `idx_reactions_target_live`, `idx_gists_live_created`, `idx_projects_live_created`, `idx_attachments_user_created_live`) to optimize filtered queries on non-deleted rows. Introduce a hot-settings cache (`_hot_settings`) with a 2-second TTL for `maintenance_mode`, `rate_limit_per_minute`, and `rate_limit_window_seconds`, plus a periodic rate-limit store sweep (`_sweep_rate_limit_store`) to evict stale IP entries every 60 seconds. Add `GZipMiddleware` to the FastAPI app for response compression.
2026-06-20 00:24:51 +02:00
|
|
|
return self._safe_metrics()
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
|
|
|
|
|
def describe(self) -> dict:
|
|
|
|
|
state = self._read_state()
|
|
|
|
|
enabled = self.is_enabled()
|
|
|
|
|
status = self._display_status(enabled, state)
|
|
|
|
|
return {
|
|
|
|
|
"name": self.name,
|
|
|
|
|
"title": self.title or self.name.capitalize(),
|
|
|
|
|
"description": self.description,
|
feat: add featured/locked columns and auto-rotation logic to news pipeline
- Add `ai_grade`, `featured`, `featured_locked`, `landing_locked`, `author`, `article_published`, `image_url`, `has_unique_image` columns to news table
- Extend `news_images` schema with `alt_text`, `phash`, `width`, `height`, `is_placeholder` columns
- Create `idx_news_featured` index for efficient featured queries
- Update admin toggle endpoints to set `featured_locked`/`landing_locked` when manually toggling
- Propagate `featured` and `image_url` fields through landing page, news list, and detail page rendering
- Update `get_featured_news` to return `featured` and `image_url` fields
- Document in AGENTS.md the full zero-maintenance pipeline: image perceptual hashing, placeholder detection, AI grading on cleaned text, reliability gate, effective score computation, and post-loop landing rotation
- Update README.md service description to reflect automatic image comparison and landing rotation capabilities
- Clarify docs_api.py summaries that toggling featured/landing now locks articles from auto-rotation
2026-06-19 00:08:41 +02:00
|
|
|
"details": self.details,
|
feat: add api key auth, devii agent, openai gateway, and admin service management
This commit introduces a comprehensive set of new features including API key authentication with CLI management commands (get, reset, backfill), a Devii agentic assistant with WebSocket terminal and session bootstrap, an OpenAI-compatible LLM gateway service, and an admin service management panel. It also adds Playwright browser automation for bot support, configures internal gateway URLs, refactors content editing/deletion to support JSON API responses, and updates documentation across AGENTS.md, README.md, and the developer docs site.
2026-06-08 17:38:33 +02:00
|
|
|
"enabled": enabled,
|
|
|
|
|
"status": status,
|
|
|
|
|
"interval_seconds": self.current_interval(),
|
|
|
|
|
"last_run": state.get("last_run") or None,
|
|
|
|
|
"next_run": state.get("next_run") or None,
|
|
|
|
|
"heartbeat": state.get("heartbeat") or None,
|
|
|
|
|
"uptime": self._uptime(state, status),
|
|
|
|
|
"log_buffer": self._logs(state),
|
|
|
|
|
"metrics": self._metrics(state),
|
|
|
|
|
"fields": [field.spec() for field in self.all_fields()],
|
|
|
|
|
"field_groups": self._grouped_fields(),
|
|
|
|
|
}
|