diff --git a/backend/omni/CHANGELOG.md b/backend/omni/CHANGELOG.md index 26e235bf..15ba5d35 100644 --- a/backend/omni/CHANGELOG.md +++ b/backend/omni/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- `enabled` field on `ModelProvider` +- `GET /api/models` now skips providers where `enabled=False`, so only active providers contribute models to the aggregated list. + ## [0.0.3] - 2026-04-28 ### Added diff --git a/backend/omni/src/modai/modules/chat/__tests__/test_chat_llm_modules.py b/backend/omni/src/modai/modules/chat/__tests__/test_chat_llm_modules.py index a1e215c8..7a0949ee 100644 --- a/backend/omni/src/modai/modules/chat/__tests__/test_chat_llm_modules.py +++ b/backend/omni/src/modai/modules/chat/__tests__/test_chat_llm_modules.py @@ -1227,6 +1227,7 @@ def _make_provider( name=name, base_url=base_url, api_key=api_key, + enabled=True, properties={}, created_at=None, updated_at=None, @@ -1240,6 +1241,7 @@ def _real_provider() -> ModelProviderResponse: name="myopenai", base_url=os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1"), api_key=os.environ.get("UNIT_TEST_OPENAI_API_KEY", ""), + enabled=True, properties={}, created_at=None, updated_at=None, diff --git a/backend/omni/src/modai/modules/model_provider/__tests__/test_central_model_provider_router.py b/backend/omni/src/modai/modules/model_provider/__tests__/test_central_model_provider_router.py index 5dff7100..79ae81ed 100644 --- a/backend/omni/src/modai/modules/model_provider/__tests__/test_central_model_provider_router.py +++ b/backend/omni/src/modai/modules/model_provider/__tests__/test_central_model_provider_router.py @@ -73,6 +73,7 @@ def mock_provider_modules(self): name="OpenAI Production", base_url="https://api.openai.com/v1", api_key="sk-...", + enabled=True, properties={}, created_at="2024-01-15T10:30:00Z", updated_at="2024-01-15T10:30:00Z", @@ -106,6 +107,7 @@ def mock_provider_modules(self): name="Local Ollama", base_url="http://localhost:11434", api_key="", + enabled=True, properties={}, created_at="2024-01-16T14:20:00Z", updated_at="2024-01-16T14:20:00Z", @@ -203,6 +205,49 @@ def test_get_all_models_endpoint(self, test_client): assert "created" in model assert "owned_by" in model + def test_get_all_models_excludes_disabled_providers(self, mock_session_module): + """Test GET /models does not return models from disabled providers.""" + disabled_provider = ModelProviderResponse( + id="openai-disabled", + type="openai", + name="Disabled Provider", + base_url="https://api.disabled.com/v1", + api_key="sk-disabled", + enabled=False, + properties={}, + created_at="2024-01-15T10:30:00Z", + updated_at="2024-01-15T10:30:00Z", + ) + disabled_models = ModelResponse( + data=[ + { + "id": "gpt-secret", + "object": "model", + "created": 1686935002, + "owned_by": "openai", + } + ] + ) + disabled_module = DummyModelProviderModule( + "openai", [disabled_provider], {"openai-disabled": disabled_models} + ) + + dependencies = ModuleDependencies( + {"disabled_provider": disabled_module, "session": mock_session_module} + ) + router = CentralModelProviderRouter(dependencies, config={}) + app = FastAPI() + app.include_router(router.router) + client = TestClient(app) + + response = client.get("/api/models") + + assert response.status_code == 200 + data = response.json() + model_ids = [m["id"] for m in data["data"]] + assert not any("gpt-secret" in mid for mid in model_ids) + assert data["data"] == [] + def test_get_all_providers_with_pagination(self, test_client): """Test GET /api/models/providers with pagination""" response = test_client.get("/api/models/providers?limit=1&offset=0") diff --git a/backend/omni/src/modai/modules/model_provider/__tests__/test_model_provider.py b/backend/omni/src/modai/modules/model_provider/__tests__/test_model_provider.py index e61e5c30..faed6b29 100644 --- a/backend/omni/src/modai/modules/model_provider/__tests__/test_model_provider.py +++ b/backend/omni/src/modai/modules/model_provider/__tests__/test_model_provider.py @@ -224,6 +224,7 @@ def test_create_provider( name="NewProvider", url="https://api.new.com", properties=expected_properties, + enabled=False, ) def test_create_provider_validation_error( @@ -295,6 +296,7 @@ def test_update_provider( name="UpdatedProvider", url="https://api.updated.com", properties=expected_properties, + enabled=None, ) def test_update_provider_not_found( @@ -379,6 +381,7 @@ def test_complex_properties_handling( name="ComplexProvider", url="https://api.complex.com", properties=expected_properties, + enabled=False, ) @pytest.mark.skipif( diff --git a/backend/omni/src/modai/modules/model_provider/central_router.py b/backend/omni/src/modai/modules/model_provider/central_router.py index e5cc71d7..9c8ef8d4 100644 --- a/backend/omni/src/modai/modules/model_provider/central_router.py +++ b/backend/omni/src/modai/modules/model_provider/central_router.py @@ -146,8 +146,10 @@ async def get_all_models(self, request: Request) -> ModelsListResponse: request, limit=None, offset=None ) - # For each provider, get its models + # For each provider, get its models (only enabled ones) for provider in providers_response.providers: + if not provider.enabled: + continue try: models_response = await provider_module.get_models( request, provider.id diff --git a/backend/omni/src/modai/modules/model_provider/module.py b/backend/omni/src/modai/modules/model_provider/module.py index 05ea69b1..de44cd0a 100644 --- a/backend/omni/src/modai/modules/model_provider/module.py +++ b/backend/omni/src/modai/modules/model_provider/module.py @@ -19,6 +19,7 @@ class ModelProviderResponse(BaseModel): name: str base_url: str api_key: str + enabled: bool properties: dict[str, Any] created_at: str | None updated_at: str | None @@ -30,6 +31,7 @@ class ModelProviderCreateRequest(BaseModel): name: str base_url: str api_key: str + enabled: bool | None = None properties: dict[str, Any] = {} diff --git a/backend/omni/src/modai/modules/model_provider/openai_provider.py b/backend/omni/src/modai/modules/model_provider/openai_provider.py index e0579cbf..25222a7b 100644 --- a/backend/omni/src/modai/modules/model_provider/openai_provider.py +++ b/backend/omni/src/modai/modules/model_provider/openai_provider.py @@ -95,11 +95,12 @@ async def create_provider( properties = (provider_data.properties or {}).copy() properties["api_key"] = provider_data.api_key - # Create new provider + # Create new provider (disabled by default) provider = await self.provider_store.add_provider( name=provider_data.name, url=provider_data.base_url, properties=properties, + enabled=False, ) return self._create_provider_response(provider) @@ -129,6 +130,7 @@ async def update_provider( name=provider_data.name, url=provider_data.base_url, properties=properties, + enabled=provider_data.enabled, ) if not provider: raise HTTPException( @@ -208,6 +210,7 @@ def _create_provider_response( name=provider.name, base_url=provider.url, api_key=api_key, + enabled=provider.enabled, properties=properties, created_at=provider.created_at.isoformat() if provider.created_at else None, updated_at=provider.updated_at.isoformat() if provider.updated_at else None, diff --git a/backend/omni/src/modai/modules/model_provider_store/module.py b/backend/omni/src/modai/modules/model_provider_store/module.py index c209664b..0af745a3 100644 --- a/backend/omni/src/modai/modules/model_provider_store/module.py +++ b/backend/omni/src/modai/modules/model_provider_store/module.py @@ -21,6 +21,7 @@ class ModelProvider: name: str url: str properties: dict[str, Any] + enabled: bool = False created_at: datetime | None = None updated_at: datetime | None = None @@ -67,7 +68,7 @@ async def get_provider(self, provider_id: str) -> ModelProvider | None: @abstractmethod async def add_provider( - self, name: str, url: str, properties: dict[str, Any] + self, name: str, url: str, properties: dict[str, Any], enabled: bool = False ) -> ModelProvider: """ Adds a new model provider configuration. @@ -75,6 +76,7 @@ async def add_provider( name: Human-readable name for the provider url: API endpoint URL for the provider properties: Configuration properties specific to the provider + enabled: Whether the provider is active (default: False) Returns: Created ModelProvider object @@ -91,6 +93,7 @@ async def update_provider( name: str, url: str, properties: dict[str, Any], + enabled: bool | None = None, ) -> ModelProvider | None: """ Updates an existing model provider configuration. @@ -100,6 +103,7 @@ async def update_provider( name: New name for the provider (optional) url: New URL for the provider (optional) properties: New properties for the provider (optional) + enabled: Whether the provider is active (None = keep current) Returns: Updated ModelProvider object if found, None otherwise diff --git a/backend/omni/src/modai/modules/model_provider_store/sql_model_provider_store.py b/backend/omni/src/modai/modules/model_provider_store/sql_model_provider_store.py index 38b40f3a..d66c00ba 100644 --- a/backend/omni/src/modai/modules/model_provider_store/sql_model_provider_store.py +++ b/backend/omni/src/modai/modules/model_provider_store/sql_model_provider_store.py @@ -9,6 +9,7 @@ import json from sqlalchemy import ( + Boolean, create_engine, MetaData, Table, @@ -58,6 +59,9 @@ def __init__(self, dependencies: ModuleDependencies, config: dict[str, Any]): Column("name", String(128), unique=True, index=True), Column("url", String(1000)), Column("properties", JSON), + Column( + "enabled", Boolean, default=False, nullable=False, server_default="0" + ), Column("created_at", DateTime, default=datetime.now), Column("updated_at", DateTime, default=datetime.now), ) @@ -85,6 +89,7 @@ def _row_to_provider(self, row) -> ModelProvider: name=row.name, url=row.url, properties=properties, + enabled=bool(row.enabled) if row.enabled is not None else False, created_at=row.created_at, updated_at=row.updated_at, ) @@ -131,7 +136,7 @@ async def get_provider(self, provider_id: str) -> ModelProvider | None: return None async def add_provider( - self, name: str, url: str, properties: dict[str, Any] + self, name: str, url: str, properties: dict[str, Any], enabled: bool = False ) -> ModelProvider: provider_id = self._generate_provider_id() with self._get_session() as session: @@ -146,6 +151,7 @@ async def add_provider( name=name.strip(), url=url.strip(), properties=properties, + enabled=enabled, created_at=now, updated_at=now, ) @@ -159,6 +165,7 @@ async def add_provider( name=name.strip(), url=url.strip(), properties=properties, + enabled=enabled, created_at=now, updated_at=now, ) @@ -169,6 +176,7 @@ async def update_provider( name: str, url: str, properties: dict[str, Any], + enabled: bool | None = None, ) -> ModelProvider | None: with self._get_session() as session: # Check if provider exists first @@ -185,6 +193,7 @@ async def update_provider( properties = {} now = datetime.now() + new_enabled = enabled if enabled is not None else bool(existing_row.enabled) # Update the provider update_stmt = ( @@ -194,6 +203,7 @@ async def update_provider( name=name.strip(), url=url.strip(), properties=properties, + enabled=new_enabled, updated_at=now, ) ) @@ -207,6 +217,7 @@ async def update_provider( name=name.strip(), url=url.strip(), properties=properties, + enabled=new_enabled, created_at=existing_row.created_at, updated_at=now, ) diff --git a/docs/biome.json b/docs/biome.json index 1583625c..b977a658 100644 --- a/docs/biome.json +++ b/docs/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.13/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", "root": true, "vcs": { "enabled": true, diff --git a/docs/package.json b/docs/package.json index a7420f13..41d37e38 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,7 +14,7 @@ "mermaid": "^11.14.0" }, "devDependencies": { - "@biomejs/biome": "^2.4.13", + "@biomejs/biome": "^2.4.15", "@rspress/core": "^2.0.9", "typescript": "^6.0.3" } diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 236654a9..67339339 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -13,8 +13,8 @@ importers: version: 11.14.0 devDependencies: '@biomejs/biome': - specifier: ^2.4.13 - version: 2.4.13 + specifier: ^2.4.15 + version: 2.4.15 '@rspress/core': specifier: ^2.0.9 version: 2.0.9(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/mdast@4.0.4)(@types/react@19.2.14)(micromark-util-types@2.0.2)(micromark@4.0.2) @@ -27,59 +27,59 @@ packages: '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@biomejs/biome@2.4.13': - resolution: {integrity: sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA==} + '@biomejs/biome@2.4.15': + resolution: {integrity: sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.4.13': - resolution: {integrity: sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg==} + '@biomejs/cli-darwin-arm64@2.4.15': + resolution: {integrity: sha512-rF3PPqLq1yoST79zaQbDjVJwsuIeci/O+9bgNmC5QpgOqz6aqYuzA4abyAGx+mgyiDXn4A049xAN8gijbuR1Qg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.4.13': - resolution: {integrity: sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg==} + '@biomejs/cli-darwin-x64@2.4.15': + resolution: {integrity: sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.4.13': - resolution: {integrity: sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg==} + '@biomejs/cli-linux-arm64-musl@2.4.15': + resolution: {integrity: sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.4.13': - resolution: {integrity: sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ==} + '@biomejs/cli-linux-arm64@2.4.15': + resolution: {integrity: sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.4.13': - resolution: {integrity: sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ==} + '@biomejs/cli-linux-x64-musl@2.4.15': + resolution: {integrity: sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.4.13': - resolution: {integrity: sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ==} + '@biomejs/cli-linux-x64@2.4.15': + resolution: {integrity: sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.4.13': - resolution: {integrity: sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A==} + '@biomejs/cli-win32-arm64@2.4.15': + resolution: {integrity: sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.4.13': - resolution: {integrity: sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ==} + '@biomejs/cli-win32-x64@2.4.15': + resolution: {integrity: sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -1341,39 +1341,39 @@ snapshots: package-manager-detector: 1.6.0 tinyexec: 1.1.1 - '@biomejs/biome@2.4.13': + '@biomejs/biome@2.4.15': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.4.13 - '@biomejs/cli-darwin-x64': 2.4.13 - '@biomejs/cli-linux-arm64': 2.4.13 - '@biomejs/cli-linux-arm64-musl': 2.4.13 - '@biomejs/cli-linux-x64': 2.4.13 - '@biomejs/cli-linux-x64-musl': 2.4.13 - '@biomejs/cli-win32-arm64': 2.4.13 - '@biomejs/cli-win32-x64': 2.4.13 - - '@biomejs/cli-darwin-arm64@2.4.13': + '@biomejs/cli-darwin-arm64': 2.4.15 + '@biomejs/cli-darwin-x64': 2.4.15 + '@biomejs/cli-linux-arm64': 2.4.15 + '@biomejs/cli-linux-arm64-musl': 2.4.15 + '@biomejs/cli-linux-x64': 2.4.15 + '@biomejs/cli-linux-x64-musl': 2.4.15 + '@biomejs/cli-win32-arm64': 2.4.15 + '@biomejs/cli-win32-x64': 2.4.15 + + '@biomejs/cli-darwin-arm64@2.4.15': optional: true - '@biomejs/cli-darwin-x64@2.4.13': + '@biomejs/cli-darwin-x64@2.4.15': optional: true - '@biomejs/cli-linux-arm64-musl@2.4.13': + '@biomejs/cli-linux-arm64-musl@2.4.15': optional: true - '@biomejs/cli-linux-arm64@2.4.13': + '@biomejs/cli-linux-arm64@2.4.15': optional: true - '@biomejs/cli-linux-x64-musl@2.4.13': + '@biomejs/cli-linux-x64-musl@2.4.15': optional: true - '@biomejs/cli-linux-x64@2.4.13': + '@biomejs/cli-linux-x64@2.4.15': optional: true - '@biomejs/cli-win32-arm64@2.4.13': + '@biomejs/cli-win32-arm64@2.4.15': optional: true - '@biomejs/cli-win32-x64@2.4.13': + '@biomejs/cli-win32-x64@2.4.15': optional: true '@braintree/sanitize-url@7.1.2': {} diff --git a/e2e_tests/tests_omni_full/biome.json b/e2e_tests/tests_omni_full/biome.json index 35d8998c..48dffb4f 100644 --- a/e2e_tests/tests_omni_full/biome.json +++ b/e2e_tests/tests_omni_full/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.13/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", "root": true, "vcs": { "enabled": true, diff --git a/frontend/omni/CHANGELOG.md b/frontend/omni/CHANGELOG.md index 5cfcf104..21e4671f 100644 --- a/frontend/omni/CHANGELOG.md +++ b/frontend/omni/CHANGELOG.md @@ -7,10 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- LLM provider management: each provider card now has a toggle switch to enable or disable the provider. Disabled providers are hidden from the model selection list. + ### Changed - The sidebar is now resizable. - Chat sidebar entry is now a collapsible menu. +- LLM provider management: replaced the always-visible "Add Provider" form with a "New" button. Clicking it reveals an inline form with Save and Cancel actions. ### Fixed diff --git a/frontend/omni/biome.json b/frontend/omni/biome.json index f2e3db6d..3396f3a7 100644 --- a/frontend/omni/biome.json +++ b/frontend/omni/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.13/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", "root": true, "vcs": { "enabled": true, diff --git a/frontend/omni/package.json b/frontend/omni/package.json index 9ea54fe7..b2f3c1e6 100644 --- a/frontend/omni/package.json +++ b/frontend/omni/package.json @@ -36,6 +36,7 @@ "@tailwindcss/vite": "^4.3.0", "bits-ui": "^2.18.1", "happy-dom": "^20.9.0", + "shadcn-svelte": "^1.2.7", "tailwind-variants": "^3.2.2", "typescript": "^6.0.3", "vite": "^8.0.12", diff --git a/frontend/omni/pnpm-lock.yaml b/frontend/omni/pnpm-lock.yaml index 19b1a9f7..bfb12732 100644 --- a/frontend/omni/pnpm-lock.yaml +++ b/frontend/omni/pnpm-lock.yaml @@ -75,6 +75,9 @@ importers: happy-dom: specifier: ^20.9.0 version: 20.9.0 + shadcn-svelte: + specifier: ^1.2.7 + version: 1.2.7(svelte@5.55.5(@typescript-eslint/types@8.57.2)) tailwind-variants: specifier: ^3.2.2 version: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.0) @@ -144,24 +147,28 @@ packages: engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [musl] '@biomejs/cli-linux-arm64@2.4.15': resolution: {integrity: sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [glibc] '@biomejs/cli-linux-x64-musl@2.4.15': resolution: {integrity: sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [musl] '@biomejs/cli-linux-x64@2.4.15': resolution: {integrity: sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [glibc] '@biomejs/cli-win32-arm64@2.4.15': resolution: {integrity: sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w==} @@ -265,36 +272,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0': resolution: {integrity: sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.0': resolution: {integrity: sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.0': resolution: {integrity: sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0': resolution: {integrity: sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0': resolution: {integrity: sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0': resolution: {integrity: sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==} @@ -378,24 +391,28 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.3.0': resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.3.0': resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.3.0': resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.3.0': resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==} @@ -537,6 +554,10 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -684,24 +705,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} @@ -744,6 +769,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} @@ -779,6 +807,12 @@ packages: '@sveltejs/kit': optional: true + shadcn-svelte@1.2.7: + resolution: {integrity: sha512-mWuQk4H4gtV+J2wJQ7nEPKNnB/v86AALFryZU0SSM7ChHmJJMZ1kH+qIuxYKrXm9vOOOcSWHRsWzPDB71DnjYA==} + hasBin: true + peerDependencies: + svelte: ^5.0.0 + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1368,6 +1402,8 @@ snapshots: clsx@2.1.1: {} + commander@14.0.3: {} + commander@8.3.0: {} convert-source-map@2.0.0: {} @@ -1519,6 +1555,8 @@ snapshots: nanoid@3.3.12: {} + node-fetch-native@1.6.7: {} + obug@2.1.1: {} pathe@2.0.3: {} @@ -1566,6 +1604,14 @@ snapshots: lz-string: 1.5.0 svelte: 5.55.5(@typescript-eslint/types@8.57.2) + shadcn-svelte@1.2.7(svelte@5.55.5(@typescript-eslint/types@8.57.2)): + dependencies: + commander: 14.0.3 + node-fetch-native: 1.6.7 + postcss: 8.5.14 + svelte: 5.55.5(@typescript-eslint/types@8.57.2) + tailwind-merge: 3.6.0 + siginfo@2.0.0: {} source-map-js@1.2.1: {} diff --git a/frontend/omni/src/app.css b/frontend/omni/src/app.css index c279263f..6712abca 100644 --- a/frontend/omni/src/app.css +++ b/frontend/omni/src/app.css @@ -1,4 +1,5 @@ @import "tailwindcss"; +@import "shadcn-svelte/tailwind.css"; @plugin "@tailwindcss/typography"; @theme inline { diff --git a/frontend/omni/src/lib/shadcnui/components/ui/sidebar/constants.ts b/frontend/omni/src/lib/shadcnui/components/ui/sidebar/constants.ts index 4de44351..1347e83c 100644 --- a/frontend/omni/src/lib/shadcnui/components/ui/sidebar/constants.ts +++ b/frontend/omni/src/lib/shadcnui/components/ui/sidebar/constants.ts @@ -1,4 +1,4 @@ -export const SIDEBAR_COOKIE_NAME = "sidebar:state"; +export const SIDEBAR_COOKIE_NAME = "sidebar_state"; export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; export const SIDEBAR_WIDTH = "16rem"; export const SIDEBAR_WIDTH_MOBILE = "18rem"; diff --git a/frontend/omni/src/modules/llm-provider-management/AddProviderForm.svelte b/frontend/omni/src/modules/llm-provider-management/AddProviderForm.svelte index d2b8b8bf..47a1e81c 100644 --- a/frontend/omni/src/modules/llm-provider-management/AddProviderForm.svelte +++ b/frontend/omni/src/modules/llm-provider-management/AddProviderForm.svelte @@ -1,5 +1,5 @@
- {t("subtitle", { defaultValue: "Manage your OpenAI-compatible LLM providers." })} -
++ {t("subtitle", { defaultValue: "Manage your OpenAI-compatible LLM providers." })} +
+