mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
Merge 5b3460cb60
into 21d616f8ed
This commit is contained in:
commit
b3523d6455
@ -57,8 +57,8 @@ from open_webui.utils.logger import start_logger
|
||||
from open_webui.socket.main import (
|
||||
app as socket_app,
|
||||
periodic_usage_pool_cleanup,
|
||||
get_models_in_use,
|
||||
get_active_user_ids,
|
||||
get_requests_count_per_model,
|
||||
get_active_users_count,
|
||||
)
|
||||
from open_webui.routers import (
|
||||
audio,
|
||||
@ -1663,7 +1663,7 @@ async def get_current_usage(user=Depends(get_verified_user)):
|
||||
This is an experimental endpoint and subject to change.
|
||||
"""
|
||||
try:
|
||||
return {"model_ids": get_models_in_use(), "user_ids": get_active_user_ids()}
|
||||
return {"requests_per_model": get_requests_count_per_model(), "users_count": get_active_users_count()}
|
||||
except Exception as e:
|
||||
log.error(f"Error getting usage statistics: {e}")
|
||||
raise HTTPException(status_code=500, detail="Internal Server Error")
|
||||
|
@ -117,22 +117,22 @@ async def periodic_usage_pool_cleanup():
|
||||
|
||||
now = int(time.time())
|
||||
send_usage = False
|
||||
for model_id, connections in list(USAGE_POOL.items()):
|
||||
# Creating a list of sids to remove if they have timed out
|
||||
expired_sids = [
|
||||
sid
|
||||
for sid, details in connections.items()
|
||||
for model_id, messages in list(USAGE_POOL.items()):
|
||||
# Creating a list of messages to remove if they have timed out
|
||||
expired_messages = [
|
||||
message_id
|
||||
for message_id, details in messages.items()
|
||||
if now - details["updated_at"] > TIMEOUT_DURATION
|
||||
]
|
||||
|
||||
for sid in expired_sids:
|
||||
del connections[sid]
|
||||
for message_id in expired_messages:
|
||||
del messages[message_id]
|
||||
|
||||
if not connections:
|
||||
if not messages:
|
||||
log.debug(f"Cleaning up model {model_id} from usage pool")
|
||||
del USAGE_POOL[model_id]
|
||||
else:
|
||||
USAGE_POOL[model_id] = connections
|
||||
USAGE_POOL[model_id] = messages
|
||||
|
||||
send_usage = True
|
||||
await asyncio.sleep(TIMEOUT_DURATION)
|
||||
@ -146,10 +146,18 @@ app = socketio.ASGIApp(
|
||||
)
|
||||
|
||||
|
||||
def get_models_in_use():
|
||||
# List models that are currently in use
|
||||
models_in_use = list(USAGE_POOL.keys())
|
||||
return models_in_use
|
||||
def get_requests_count_per_model():
|
||||
"""Get currently used models and their current request count"""
|
||||
active_models = list(USAGE_POOL.keys())
|
||||
requests_count_per_model = {}
|
||||
for model in active_models:
|
||||
requests_count_per_model[model] = len(USAGE_POOL[model].keys())
|
||||
return requests_count_per_model
|
||||
|
||||
|
||||
def get_active_users_count():
|
||||
"""Get the number of active users."""
|
||||
return len(USER_POOL)
|
||||
|
||||
|
||||
def get_active_user_ids():
|
||||
@ -192,14 +200,15 @@ def get_active_status_by_user_id(user_id):
|
||||
@sio.on("usage")
|
||||
async def usage(sid, data):
|
||||
if sid in SESSION_POOL:
|
||||
model_id = data["model"]
|
||||
model_id = data["model_id"]
|
||||
message_id = data["message_id"]
|
||||
# Record the timestamp for the last update
|
||||
current_time = int(time.time())
|
||||
|
||||
# Store the new usage data and task
|
||||
USAGE_POOL[model_id] = {
|
||||
**(USAGE_POOL[model_id] if model_id in USAGE_POOL else {}),
|
||||
sid: {"updated_at": current_time},
|
||||
message_id: {"updated_at": current_time},
|
||||
}
|
||||
|
||||
|
||||
|
@ -1057,13 +1057,18 @@
|
||||
}
|
||||
};
|
||||
|
||||
const getChatEventEmitter = async (modelId: string, chatId: string = '') => {
|
||||
const socketEmitUsage = (modelId: string, messageId: string = '') => {
|
||||
$socket?.emit('usage', {
|
||||
action: 'chat',
|
||||
model_id: modelId,
|
||||
message_id: messageId
|
||||
});
|
||||
};
|
||||
|
||||
const getChatEventEmitter = async (modelId: string, messageId: string = '') => {
|
||||
socketEmitUsage(modelId, messageId);
|
||||
return setInterval(() => {
|
||||
$socket?.emit('usage', {
|
||||
action: 'chat',
|
||||
model: modelId,
|
||||
chat_id: chatId
|
||||
});
|
||||
socketEmitUsage(modelId, messageId);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
@ -1533,7 +1538,7 @@
|
||||
|
||||
let responseMessageId =
|
||||
responseMessageIds[`${modelId}-${modelIdx ? modelIdx : _modelIdx}`];
|
||||
const chatEventEmitter = await getChatEventEmitter(model.id, _chatId);
|
||||
const chatEventEmitter = await getChatEventEmitter(model.id, responseMessageId);
|
||||
|
||||
scrollToBottom();
|
||||
await sendPromptSocket(_history, model, responseMessageId, _chatId);
|
||||
|
@ -206,40 +206,48 @@
|
||||
</button>
|
||||
|
||||
{#if usage}
|
||||
{#if usage?.user_ids?.length > 0}
|
||||
<hr class=" border-gray-100 dark:border-gray-800 my-1 p-0" />
|
||||
<hr class=" border-gray-100 dark:border-gray-800 my-1 p-0" />
|
||||
|
||||
<Tooltip
|
||||
content={usage?.model_ids && usage?.model_ids.length > 0
|
||||
? `${$i18n.t('Running')}: ${usage.model_ids.join(', ')} ✨`
|
||||
: ''}
|
||||
<Tooltip
|
||||
content={usage?.requests_per_model && Object.keys(usage?.requests_per_model).length > 0
|
||||
? `${$i18n.t('Running')}: ${Object.entries(usage?.requests_per_model).reduce((a, b) => a + b[0] + ' (' + b[1] + '), ', '')} ✨`
|
||||
: ''}
|
||||
>
|
||||
<div
|
||||
class="flex rounded-md py-1 px-3 text-xs gap-2.5 items-center"
|
||||
on:mouseenter={() => {
|
||||
getUsageInfo();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="flex rounded-md py-1 px-3 text-xs gap-2.5 items-center"
|
||||
on:mouseenter={() => {
|
||||
getUsageInfo();
|
||||
}}
|
||||
>
|
||||
<div class=" flex items-center">
|
||||
<span class="relative flex size-2">
|
||||
<span
|
||||
class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
|
||||
/>
|
||||
<span class="relative inline-flex rounded-full size-2 bg-green-500" />
|
||||
</span>
|
||||
</div>
|
||||
<div class=" flex items-center">
|
||||
<span class="relative flex size-2">
|
||||
<span
|
||||
class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
|
||||
/>
|
||||
<span class="relative inline-flex rounded-full size-2 bg-green-500" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class=" ">
|
||||
<div class=" ">
|
||||
{#if usage?.users_count}
|
||||
<span class="">
|
||||
{$i18n.t('Active Users')}:
|
||||
</span>
|
||||
<span class=" font-semibold">
|
||||
{usage?.user_ids?.length}
|
||||
{usage?.users_count}<br>
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if usage?.requests_per_model}
|
||||
<span class="">
|
||||
{$i18n.t('Running Requests')}:
|
||||
</span>
|
||||
<span class=" font-semibold">
|
||||
{Object.values(usage?.requests_per_model).reduce((a, b) => a + b, 0)}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
</div>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
<!-- <DropdownMenu.Item class="flex items-center py-1.5 px-3 text-sm ">
|
||||
|
@ -1061,6 +1061,7 @@
|
||||
"RTL": "RTL",
|
||||
"Run": "Ausführen",
|
||||
"Running": "Läuft",
|
||||
"Running Requests": "Laufende Anfragen",
|
||||
"Save": "Speichern",
|
||||
"Save & Create": "Erstellen",
|
||||
"Save & Update": "Aktualisieren",
|
||||
|
@ -1061,6 +1061,7 @@
|
||||
"RTL": "",
|
||||
"Run": "",
|
||||
"Running": "",
|
||||
"Running Requests": "",
|
||||
"Save": "",
|
||||
"Save & Create": "",
|
||||
"Save & Update": "",
|
||||
|
@ -22,8 +22,6 @@ export const MODEL_DOWNLOAD_POOL = writable({});
|
||||
export const mobile = writable(false);
|
||||
|
||||
export const socket: Writable<null | Socket> = writable(null);
|
||||
export const activeUserIds: Writable<null | string[]> = writable(null);
|
||||
export const USAGE_POOL: Writable<null | string[]> = writable(null);
|
||||
|
||||
export const theme = writable('system');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user