feat: admin panelini ve kurulum dokumanlarini genislet
This commit is contained in:
@@ -3,9 +3,10 @@ from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.admin.services import AdminService
|
||||
from app.db import get_session
|
||||
from app.config import get_settings as get_app_settings
|
||||
from app.db import SecretORM, get_session
|
||||
from app.llm.ollama_client import OllamaClient
|
||||
from app.models import MemoryRecord, OllamaStatus, RuntimeSettings, TelegramStatus, UserRecord
|
||||
from app.models import AutomationRecord, MemoryRecord, OllamaStatus, RuntimeSettings, TelegramStatus, UserProfileRecord, UserRecord
|
||||
|
||||
router = APIRouter(prefix="/admin", tags=["admin"])
|
||||
|
||||
@@ -25,7 +26,7 @@ def get_dashboard(service: AdminService = Depends(get_admin_service)):
|
||||
|
||||
|
||||
@router.get("/settings", response_model=RuntimeSettings)
|
||||
def get_settings(service: AdminService = Depends(get_admin_service)):
|
||||
def get_runtime_settings(service: AdminService = Depends(get_admin_service)):
|
||||
return service.get_runtime_settings()
|
||||
|
||||
|
||||
@@ -44,6 +45,16 @@ def post_user(payload: UserRecord, service: AdminService = Depends(get_admin_ser
|
||||
return service.save_user(payload)
|
||||
|
||||
|
||||
@router.get("/profiles", response_model=list[UserProfileRecord])
|
||||
def get_profiles(service: AdminService = Depends(get_admin_service)):
|
||||
return service.list_user_profiles()
|
||||
|
||||
|
||||
@router.get("/automations", response_model=list[AutomationRecord])
|
||||
def get_automations(service: AdminService = Depends(get_admin_service)):
|
||||
return service.list_automations()
|
||||
|
||||
|
||||
@router.get("/memory", response_model=list[MemoryRecord])
|
||||
def get_memory(service: AdminService = Depends(get_admin_service)):
|
||||
return service.list_memory()
|
||||
@@ -66,11 +77,18 @@ def post_secret(payload: SecretPayload, service: AdminService = Depends(get_admi
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@router.get("/integrations/llm", response_model=OllamaStatus)
|
||||
@router.get("/integrations/ollama", response_model=OllamaStatus)
|
||||
async def get_ollama_status(service: AdminService = Depends(get_admin_service)):
|
||||
async def get_llm_status(service: AdminService = Depends(get_admin_service)):
|
||||
runtime = service.get_runtime_settings()
|
||||
client = OllamaClient(runtime.ollama_base_url)
|
||||
return await client.status(runtime.default_model)
|
||||
settings = get_app_settings()
|
||||
secret = service.session.get(SecretORM, "zai_api_key") if runtime.model_provider == "zai" else None
|
||||
client = OllamaClient(
|
||||
base_url=runtime.local_base_url if runtime.model_provider == "local" else settings.zai_base_url,
|
||||
provider=runtime.model_provider,
|
||||
api_key=secret.value if secret else settings.zai_api_key,
|
||||
)
|
||||
return await client.status(runtime.local_model if runtime.model_provider == "local" else runtime.zai_model)
|
||||
|
||||
|
||||
@router.get("/integrations/telegram", response_model=TelegramStatus)
|
||||
|
||||
@@ -5,15 +5,18 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import (
|
||||
AuditLogORM,
|
||||
AutomationORM,
|
||||
AuthorizedUserORM,
|
||||
DEFAULT_TOOLS,
|
||||
MemoryItemORM,
|
||||
SecretORM,
|
||||
SettingORM,
|
||||
TelegramUserProfileORM,
|
||||
ToolStateORM,
|
||||
list_recent_logs,
|
||||
)
|
||||
from app.config import get_settings
|
||||
from app.models import DashboardSnapshot, MemoryRecord, RuntimeSettings, TelegramStatus, ToolToggle, UserRecord
|
||||
from app.models import AutomationRecord, DashboardSnapshot, MemoryRecord, RuntimeSettings, TelegramStatus, ToolToggle, UserProfileRecord, UserRecord
|
||||
|
||||
|
||||
class AdminService:
|
||||
@@ -24,20 +27,30 @@ class AdminService:
|
||||
settings = {
|
||||
item.key: item.value for item in self.session.scalars(select(SettingORM))
|
||||
}
|
||||
tools = list(self.session.scalars(select(ToolStateORM).order_by(ToolStateORM.name.asc())))
|
||||
tool_records = {
|
||||
tool.name: tool.enabled for tool in self.session.scalars(select(ToolStateORM).order_by(ToolStateORM.name.asc()))
|
||||
}
|
||||
return RuntimeSettings(
|
||||
terminal_mode=int(settings["terminal_mode"]),
|
||||
search_provider=settings["search_provider"],
|
||||
ollama_base_url=settings["ollama_base_url"],
|
||||
default_model=settings["default_model"],
|
||||
tools=[ToolToggle(name=tool.name, enabled=tool.enabled) for tool in tools],
|
||||
model_provider=settings["model_provider"],
|
||||
local_base_url=settings["local_base_url"],
|
||||
local_model=settings["local_model"],
|
||||
zai_model=settings["zai_model"],
|
||||
anythingllm_base_url=settings["anythingllm_base_url"],
|
||||
anythingllm_workspace_slug=settings["anythingllm_workspace_slug"],
|
||||
tools=[ToolToggle(name=name, enabled=tool_records.get(name, enabled)) for name, enabled in DEFAULT_TOOLS.items()],
|
||||
)
|
||||
|
||||
def update_runtime_settings(self, payload: RuntimeSettings) -> RuntimeSettings:
|
||||
self._save_setting("terminal_mode", str(payload.terminal_mode))
|
||||
self._save_setting("search_provider", payload.search_provider)
|
||||
self._save_setting("ollama_base_url", payload.ollama_base_url)
|
||||
self._save_setting("default_model", payload.default_model)
|
||||
self._save_setting("model_provider", payload.model_provider)
|
||||
self._save_setting("local_base_url", payload.local_base_url)
|
||||
self._save_setting("local_model", payload.local_model)
|
||||
self._save_setting("zai_model", payload.zai_model)
|
||||
self._save_setting("anythingllm_base_url", payload.anythingllm_base_url)
|
||||
self._save_setting("anythingllm_workspace_slug", payload.anythingllm_workspace_slug)
|
||||
|
||||
for tool in payload.tools:
|
||||
record = self.session.get(ToolStateORM, tool.name)
|
||||
@@ -92,6 +105,55 @@ class AdminService:
|
||||
self.session.commit()
|
||||
return user
|
||||
|
||||
def list_user_profiles(self) -> list[UserProfileRecord]:
|
||||
stmt = select(TelegramUserProfileORM).order_by(TelegramUserProfileORM.updated_at.desc())
|
||||
profiles: list[UserProfileRecord] = []
|
||||
for item in self.session.scalars(stmt):
|
||||
profiles.append(
|
||||
UserProfileRecord(
|
||||
telegram_user_id=item.telegram_user_id,
|
||||
display_name=item.display_name,
|
||||
bio=item.bio,
|
||||
occupation=item.occupation,
|
||||
primary_use_cases=self._decode_list(item.primary_use_cases),
|
||||
answer_priorities=self._decode_list(item.answer_priorities),
|
||||
tone_preference=item.tone_preference,
|
||||
response_length=item.response_length,
|
||||
language_preference=item.language_preference,
|
||||
workflow_preference=item.workflow_preference,
|
||||
interests=self._decode_list(item.interests),
|
||||
approval_preferences=self._decode_list(item.approval_preferences),
|
||||
avoid_preferences=item.avoid_preferences,
|
||||
onboarding_completed=item.onboarding_completed,
|
||||
last_onboarding_step=item.last_onboarding_step,
|
||||
)
|
||||
)
|
||||
return profiles
|
||||
|
||||
def list_automations(self) -> list[AutomationRecord]:
|
||||
stmt = select(AutomationORM).order_by(AutomationORM.created_at.desc(), AutomationORM.id.desc())
|
||||
records: list[AutomationRecord] = []
|
||||
for item in self.session.scalars(stmt):
|
||||
records.append(
|
||||
AutomationRecord(
|
||||
id=item.id,
|
||||
telegram_user_id=item.telegram_user_id,
|
||||
name=item.name,
|
||||
prompt=item.prompt,
|
||||
schedule_type=item.schedule_type, # type: ignore[arg-type]
|
||||
interval_hours=item.interval_hours,
|
||||
time_of_day=item.time_of_day,
|
||||
days_of_week=self._decode_list(item.days_of_week),
|
||||
status=item.status, # type: ignore[arg-type]
|
||||
last_run_at=item.last_run_at,
|
||||
next_run_at=item.next_run_at,
|
||||
last_result=item.last_result,
|
||||
created_at=item.created_at,
|
||||
updated_at=item.updated_at,
|
||||
)
|
||||
)
|
||||
return records
|
||||
|
||||
def list_memory(self) -> list[MemoryRecord]:
|
||||
stmt = select(MemoryItemORM).order_by(MemoryItemORM.created_at.desc(), MemoryItemORM.id.desc()).limit(50)
|
||||
return [
|
||||
@@ -140,3 +202,14 @@ class AdminService:
|
||||
if configured
|
||||
else "Telegram token is not configured.",
|
||||
)
|
||||
|
||||
def _decode_list(self, value: str) -> list[str]:
|
||||
import json
|
||||
|
||||
try:
|
||||
payload = json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
return []
|
||||
if not isinstance(payload, list):
|
||||
return []
|
||||
return [str(item).strip() for item in payload if str(item).strip()]
|
||||
|
||||
Reference in New Issue
Block a user