feat(recipes): add sort by random option with seeded stable pagination

This commit is contained in:
Will Miao
2026-08-15 09:50:46 +08:00
parent ae185ee714
commit 93472e5d67
5 changed files with 348 additions and 10 deletions
+11 -2
View File
@@ -8,6 +8,7 @@ import asyncio
import json
import logging
import os
import random
import time
from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union, cast
from ..config import config
@@ -2781,7 +2782,9 @@ class RecipeScanner:
Args:
page: Current page number (1-based)
page_size: Number of items per page
sort_by: Sort method ('name' or 'date')
sort_by: Sort method ('name', 'date', 'loras_count', or 'random'
with an optional seed like 'random:abc123'; the part after
'random:' is the shuffle seed, not a direction)
search: Search term
filters: Dictionary of filters to apply
search_options: Dictionary of search options to apply
@@ -2962,7 +2965,7 @@ class RecipeScanner:
]
# Apply sorting if not already handled by pre-sorted cache
if ":" in sort_by or sort_field == "loras_count":
if ":" in sort_by or sort_field in ("loras_count", "random"):
field, order = (sort_by.split(":") + ["desc"])[:2]
reverse = order.lower() == "desc"
@@ -2985,6 +2988,12 @@ class RecipeScanner:
filtered_data.sort(
key=lambda x: len(x.get("loras", [])), reverse=reverse
)
elif field == "random":
# Seeded random shuffle: same seed -> same order (stable
# pagination across requests), matching the model pages.
seed = order if order.lower() not in ("asc", "desc") else None
rng = random.Random(seed or "random")
rng.shuffle(filtered_data)
# Calculate pagination
total_items = len(filtered_data)