diff --git a/pyproject.toml b/pyproject.toml index c797de3..5010cf4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,11 +9,11 @@ dependencies = [ "httpx>=0.28.1", "langfuse>=3.5.0", "nicegui>=2.24.1", - "niceguiasyncelement", + "niceguiex", "psutil>=6.1.0", "pydantic-ai>=1.0.9", "pyyaml>=6.0.2", ] [tool.uv.sources] -niceguiasyncelement = { git = "https://git.project-insanity.de/gmarth/NiceGuiAsyncElement.git" } +niceguiex = { git = "https://git.project-insanity.de/gmarth/NiceGUIEx.git" } diff --git a/src/components/model_info.py b/src/components/model_info.py index 163419e..32ee1a4 100644 --- a/src/components/model_info.py +++ b/src/components/model_info.py @@ -1,16 +1,17 @@ from nicegui import ui -from niceguiasyncelement import AsyncCard +from niceguiex.async_elements import AsyncColumn from pathlib import Path from utils import ollama from typing import Optional -class ModelInfoComponent(AsyncCard): +class ModelInfoComponent(AsyncColumn): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - async def build(self, model_info: dict) -> None: + async def build(self, model_name: dict) -> None: + model_info = await ollama.model_info(model_name) # self.classes('max-w-1/2') self.style('width: 1200px; max-width: none') with self: diff --git a/src/components/ollama_downloader.py b/src/components/ollama_downloader.py index d0da025..f0ac3b8 100644 --- a/src/components/ollama_downloader.py +++ b/src/components/ollama_downloader.py @@ -1,10 +1,10 @@ from nicegui import ui, binding -from niceguiasyncelement import AsyncCard +from niceguiex.async_elements import AsyncColumn from pathlib import Path from utils import ollama -class OllamaDownloaderComponent(AsyncCard): +class OllamaDownloaderComponent(AsyncColumn): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/src/components/ollama_model_edit.py b/src/components/ollama_model_edit.py index 117ccc9..a57280d 100644 --- a/src/components/ollama_model_edit.py +++ b/src/components/ollama_model_edit.py @@ -1,12 +1,12 @@ from nicegui import ui, binding -from niceguiasyncelement import AsyncCard +from niceguiex.async_elements import AsyncColumn from pathlib import Path from utils import ollama from typing import Optional from pprint import pprint -class OllamaModelEditComponent(AsyncCard): +class OllamaModelEditComponent(AsyncColumn): model_info: dict model_name_original: str @@ -73,6 +73,7 @@ class OllamaModelEditComponent(AsyncCard): self.use_stop = False async def build(self, model_name: str, model_info: dict) -> None: + self.dialog_size = 'w-1/2' self.classes('w-full') self.model_name = model_name self.model_name_original = model_name diff --git a/src/components/ollama_quick_test.py b/src/components/ollama_quick_test.py index d935629..b636c1f 100644 --- a/src/components/ollama_quick_test.py +++ b/src/components/ollama_quick_test.py @@ -1,11 +1,11 @@ from nicegui import ui -from niceguiasyncelement import AsyncCard +from niceguiex.async_elements import AsyncColumn from pathlib import Path from utils import ollama from typing import Optional -class ModelQuickTestComponent(AsyncCard): +class ModelQuickTestComponent(AsyncColumn): model: Optional[str] def __init__(self, *args, **kwargs): diff --git a/src/pages/__init__.py b/src/pages/__init__.py index b5790d5..fa4281a 100644 --- a/src/pages/__init__.py +++ b/src/pages/__init__.py @@ -1,5 +1,4 @@ -from .welcome import WelcomePage from .ollama_manager import OllamaManagerPage from .dashboard import DashboardPage -__all__ = ['WelcomePage', 'OllamaManagerPage', 'DashboardPage'] +__all__ = ['OllamaManagerPage', 'DashboardPage'] diff --git a/src/pages/ollama_manager.py b/src/pages/ollama_manager.py index 8ccea14..074371e 100644 --- a/src/pages/ollama_manager.py +++ b/src/pages/ollama_manager.py @@ -2,7 +2,7 @@ from nicegui import ui from utils import ollama from typing import Literal, List, Dict, Optional from pprint import pprint -from niceguiasyncelement import AsyncColumn +from niceguiex.async_elements import AsyncColumn from components.ollama_downloader import OllamaDownloaderComponent from components.ollama_model_edit import OllamaModelEditComponent from components.ollama_quick_test import ModelQuickTestComponent @@ -61,20 +61,9 @@ class OllamaManagerPage(AsyncColumn): self.models_container.refresh() async def _download_model_dialog(self): - with ui.dialog().classes('max-w-none') as dialog: - await OllamaDownloaderComponent.create() - await dialog + await OllamaDownloaderComponent.as_dialog() self.models_container.refresh() - async def _test_model_dialog(self, model): - with ui.dialog() as dialog: - await ModelQuickTestComponent.create(model) - await dialog - - async def _loaded_models(self): - loaded = await ollama.active_models() - print(loaded) - async def _delete_model(self, model): with ui.dialog() as dialog, ui.card(): ui.label('Are you sure?') @@ -198,26 +187,14 @@ class OllamaManagerPage(AsyncColumn): ui.label(f"Modified: {time_ago}").classes('text-xs text-grey-5') except: pass - with ui.row().classes('gap-2'): - ui.button(icon='chat', on_click=lambda m=model['name']: self._test_model_dialog(m)).props('round flat').tooltip('Test Model') + ui.button(icon='chat', on_click=lambda m=model['name']: ModelQuickTestComponent.as_dialog(m)).props('round flat').tooltip('Test Model') ui.button(icon='edit', on_click=lambda m=model['name']: self._model_edit_model_dialog(m)).props('round flat').tooltip('Model Info') - ui.button(icon='info', on_click=lambda m=model['name']: self._model_information_dialog(m)).props('round flat').tooltip('Model Info') + ui.button(icon='info', on_click=lambda m=model['name']: ModelInfoComponent.as_dialog(m)).props('round flat').tooltip('Model Info') ui.button(icon='delete', on_click=lambda m=model['name']: self._delete_model(m)).props('round flat color=negative').tooltip('Delete Model') async def _model_edit_model_dialog(self, model_name): model_info = await ollama.model_info(model_name) - with ui.dialog() as dialog: - await OllamaModelEditComponent.create(model_name, model_info) - result = await dialog - + result = await OllamaModelEditComponent.as_dialog(model_name, model_info) if result: self.models_container.refresh() # type: ignore - - async def _model_information_dialog(self, model_name): - model_info = await ollama.model_info(model_name) - - with ui.dialog().classes('max-w-none') as dialog: - await ModelInfoComponent.create(model_info) - - await dialog diff --git a/src/pages/welcome.py b/src/pages/welcome.py deleted file mode 100644 index 77b4059..0000000 --- a/src/pages/welcome.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import Literal -from nicegui import ui - - -class WelcomePage(ui.column): - def __init__(self, *, wrap: bool = False, align_items: None | Literal['start'] | Literal['end'] | Literal['center'] | Literal['baseline'] | Literal['stretch'] = None) -> None: - super().__init__(wrap=wrap, align_items=align_items) - - with self: - ui.label('something') diff --git a/src/tools/base_tool.py b/src/tools/base_tool.py index 1cf66e9..d7768a7 100644 --- a/src/tools/base_tool.py +++ b/src/tools/base_tool.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import Dict, Callable, Awaitable, Optional, Any from nicegui import app -from niceguiasyncelement import AsyncColumn +from niceguiex.async_elements import AsyncColumn import inspect from utils import SystemMonitor, GPUMonitor, OllamaMonitor diff --git a/src/tools/simple_chat/tool.py b/src/tools/simple_chat/tool.py index d92ec7e..845f146 100644 --- a/src/tools/simple_chat/tool.py +++ b/src/tools/simple_chat/tool.py @@ -2,10 +2,8 @@ from typing import Dict, Callable, Awaitable from nicegui import ui, binding, app from tools.base_tool import BaseTool, BasePage from utils import ollama -from typing import Literal, List, Optional, Any +from typing import Literal, List, Optional from datetime import datetime -from dataclasses import dataclass -from niceguiasyncelement import AsyncColumn import json diff --git a/src/tools/simple_chat_pydantic/auto_scroll_area.py b/src/tools/simple_chat_pydantic/auto_scroll_area.py deleted file mode 100644 index 2572e4c..0000000 --- a/src/tools/simple_chat_pydantic/auto_scroll_area.py +++ /dev/null @@ -1,72 +0,0 @@ -from typing import Optional -from nicegui import ui - - -class AutoScrollArea(ui.scroll_area): - """A scroll area that automatically scrolls to bottom when new content is added - - Features: - - Auto-scrolls to bottom when at bottom and new content arrives - - Stops auto-scroll when user scrolls up manually - - Resumes auto-scroll when user scrolls back to bottom - """ - - _auto_scroll_enabled: bool = True - _auto_scroll_timer: Optional[ui.timer] = None - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - # Set up scroll monitoring - # self._handle_scroll - self.on_scroll(self._handle_scroll_event) - self.on('wheel', self._handle_wheel, ['deltaY']) - - # Create timer for auto-scrolling - self._auto_scroll_timer = ui.timer(0.1, lambda: self.scroll_to(percent=1)) - self._auto_scroll_timer.activate() - - def _scroll_event_test(self, e): - print(e.vertical_percentage) - - def _handle_scroll_event(self, event_data): - """Handle scroll events to detect when user is at bottom""" - - if not self._auto_scroll_timer: - print('no timer instantiated.') - return - - # If scrolled to bottom (100%), enable auto-scroll - if event_data.vertical_percentage > 0.99: # Using 0.99 for some tolerance - if not self._auto_scroll_timer.active: - self._auto_scroll_timer.activate() - - def _handle_wheel(self, event_data): - """Handle mouse wheel events to detect manual scrolling""" - delta_y = event_data.args['deltaY'] - if not self._auto_scroll_timer: - print('no timer instantiated.') - return - # If scrolling up (negative delta), disable auto-scroll - if delta_y < 0: - if self._auto_scroll_timer.active: - self._auto_scroll_timer.deactivate() - - def enable_auto_scroll(self): - """Manually enable auto-scrolling""" - if self._auto_scroll_timer: - if not self._auto_scroll_timer.active: - self._auto_scroll_timer.activate() - - def disable_auto_scroll(self): - """Manually disable auto-scrolling""" - - if self._auto_scroll_timer: - if self._auto_scroll_timer.active: - self._auto_scroll_timer.deactivate() - - def cleanup(self): - """Clean up timer when component is destroyed""" - if self._auto_scroll_timer: - self._auto_scroll_timer.deactivate() - self._auto_scroll_timer = None diff --git a/src/tools/simple_chat_pydantic/tool.py b/src/tools/simple_chat_pydantic/tool.py index 1827f4d..ff68644 100644 --- a/src/tools/simple_chat_pydantic/tool.py +++ b/src/tools/simple_chat_pydantic/tool.py @@ -8,7 +8,7 @@ from pydantic_ai.models.openai import OpenAIChatModel from pydantic_ai.providers.ollama import OllamaProvider from .chat_message import ChatMessageComponent -from .auto_scroll_area import AutoScrollArea +from niceguiex.components import AutoScrollArea class SimpleChatTool(BaseTool): diff --git a/uv.lock b/uv.lock index ff4df9e..b42a65b 100644 --- a/uv.lock +++ b/uv.lock @@ -128,7 +128,7 @@ dependencies = [ { name = "httpx" }, { name = "langfuse" }, { name = "nicegui" }, - { name = "niceguiasyncelement" }, + { name = "niceguiex" }, { name = "psutil" }, { name = "pydantic-ai" }, { name = "pyyaml" }, @@ -140,7 +140,7 @@ requires-dist = [ { name = "httpx", specifier = ">=0.28.1" }, { name = "langfuse", specifier = ">=3.5.0" }, { name = "nicegui", specifier = ">=2.24.1" }, - { name = "niceguiasyncelement", git = "https://git.project-insanity.de/gmarth/NiceGuiAsyncElement.git" }, + { name = "niceguiex", git = "https://git.project-insanity.de/gmarth/NiceGUIEx.git" }, { name = "psutil", specifier = ">=6.1.0" }, { name = "pydantic-ai", specifier = ">=1.0.9" }, { name = "pyyaml", specifier = ">=6.0.2" }, @@ -1009,9 +1009,9 @@ wheels = [ ] [[package]] -name = "niceguiasyncelement" +name = "niceguiex" version = "0.1.0" -source = { git = "https://git.project-insanity.de/gmarth/NiceGuiAsyncElement.git#2475cc8bd27b5f9b5047908968ab6d46b69dd4ca" } +source = { git = "https://git.project-insanity.de/gmarth/NiceGUIEx.git#1012cf3d73f3d88485287ec819ef65ee9cb6fb64" } dependencies = [ { name = "nicegui" }, ]