- Reorganize project structure and file locations - Add ReasoningController to manage model selection and reasoning mode - Update design and requirements for reasoning mode toggle - Implement model switching between Qwen3-4B-Instruct and Qwen3-4B-Thinking models - Remove deprecated files and consolidate project layout - Add new steering and specification documentation - Clean up and remove unnecessary files and directories - Prepare for enhanced AI sidebar functionality with more flexible model handling
104 lines
3.5 KiB
Python
104 lines
3.5 KiB
Python
"""Monitor for tracking Ollama availability and notifying on state changes."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Callable
|
|
from gi.repository import GLib
|
|
from .ollama_client import OllamaClient
|
|
|
|
|
|
class OllamaAvailabilityMonitor:
|
|
"""Monitors Ollama availability and notifies callbacks on state changes."""
|
|
|
|
def __init__(self, client: OllamaClient, check_interval_seconds: int = 30) -> None:
|
|
"""
|
|
Initialize the availability monitor.
|
|
|
|
Args:
|
|
client: OllamaClient instance to monitor
|
|
check_interval_seconds: How often to check availability (default: 30s)
|
|
"""
|
|
self._client = client
|
|
self._check_interval_ms = check_interval_seconds * 1000
|
|
self._callbacks: list[Callable[[bool], None]] = []
|
|
self._last_state: bool | None = None
|
|
self._timeout_id: int | None = None
|
|
self._is_running = False
|
|
|
|
def add_callback(self, callback: Callable[[bool], None]) -> None:
|
|
"""
|
|
Add a callback to be notified when availability changes.
|
|
|
|
Args:
|
|
callback: Function that takes a bool (True if available, False if not)
|
|
"""
|
|
if callback not in self._callbacks:
|
|
self._callbacks.append(callback)
|
|
|
|
def remove_callback(self, callback: Callable[[bool], None]) -> None:
|
|
"""Remove a previously registered callback."""
|
|
if callback in self._callbacks:
|
|
self._callbacks.remove(callback)
|
|
|
|
def start(self) -> None:
|
|
"""Start monitoring Ollama availability."""
|
|
if self._is_running:
|
|
return
|
|
|
|
self._is_running = True
|
|
# Do an immediate check
|
|
self._check_availability()
|
|
# Schedule periodic checks
|
|
self._timeout_id = GLib.timeout_add(
|
|
self._check_interval_ms,
|
|
self._check_availability
|
|
)
|
|
|
|
def stop(self) -> None:
|
|
"""Stop monitoring Ollama availability."""
|
|
if not self._is_running:
|
|
return
|
|
|
|
self._is_running = False
|
|
if self._timeout_id is not None:
|
|
GLib.source_remove(self._timeout_id)
|
|
self._timeout_id = None
|
|
|
|
def _check_availability(self) -> bool:
|
|
"""
|
|
Check current availability and notify callbacks if state changed.
|
|
|
|
Returns:
|
|
True to continue periodic checks, False to stop
|
|
"""
|
|
# Force a connection check
|
|
self._client._check_connection()
|
|
current_state = self._client.is_available
|
|
|
|
# Only notify if state changed
|
|
if self._last_state is None or self._last_state != current_state:
|
|
self._last_state = current_state
|
|
self._notify_callbacks(current_state)
|
|
|
|
# Return True to continue periodic checks
|
|
return True
|
|
|
|
def _notify_callbacks(self, is_available: bool) -> None:
|
|
"""Notify all registered callbacks of the availability state."""
|
|
for callback in self._callbacks:
|
|
try:
|
|
callback(is_available)
|
|
except Exception as e:
|
|
# Log error but don't let one callback failure affect others
|
|
print(f"Error in availability callback: {e}")
|
|
|
|
@property
|
|
def is_running(self) -> bool:
|
|
"""Check if the monitor is currently running."""
|
|
return self._is_running
|
|
|
|
@property
|
|
def current_state(self) -> bool | None:
|
|
"""Get the last known availability state (None if never checked)."""
|
|
return self._last_state
|