mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Merge pull request #620 from diegosouzapw/release/v3.0.5
chore(release): v3.0.5 — Tags Grouping UI and Triage
This commit is contained in:
@@ -4,6 +4,14 @@
|
||||
|
||||
---
|
||||
|
||||
## [3.0.5] — 2026-03-25
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Limits UI:** Added tag grouping feature to the connections dashboard to improve visual organization for accounts with custom tags.
|
||||
|
||||
---
|
||||
|
||||
## [3.0.4] — 2026-03-25
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: OmniRoute API
|
||||
version: 3.0.4
|
||||
version: 3.0.5
|
||||
description: |
|
||||
OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
|
||||
endpoint that routes requests to multiple AI providers with load balancing,
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "omniroute",
|
||||
"version": "3.0.4",
|
||||
"version": "3.0.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "omniroute",
|
||||
"version": "3.0.4",
|
||||
"version": "3.0.5",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "omniroute",
|
||||
"version": "3.0.4",
|
||||
"version": "3.0.5",
|
||||
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
|
||||
@@ -334,11 +334,21 @@ export default function ProviderLimits() {
|
||||
if (groupBy !== "environment") return null;
|
||||
const groups = new Map();
|
||||
for (const conn of visibleConnections) {
|
||||
const key = conn.group || t("ungrouped");
|
||||
const key = (conn.providerSpecificData?.tag as string | undefined)?.trim() || t("ungrouped");
|
||||
if (!groups.has(key)) groups.set(key, []);
|
||||
groups.get(key).push(conn);
|
||||
}
|
||||
return groups;
|
||||
|
||||
// Convert to sorted array based on tag string (ungrouped at the end)
|
||||
const sortedGroups = new Map(
|
||||
[...groups.entries()].sort(([a], [b]) => {
|
||||
if (a === t("ungrouped")) return 1;
|
||||
if (b === t("ungrouped")) return -1;
|
||||
return a.localeCompare(b);
|
||||
})
|
||||
);
|
||||
|
||||
return sortedGroups;
|
||||
}, [groupBy, visibleConnections, t]);
|
||||
|
||||
const handleSetGroupBy = (value: "none" | "environment") => {
|
||||
@@ -359,7 +369,10 @@ export default function ProviderLimits() {
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined") return;
|
||||
const hasSaved = localStorage.getItem(LS_GROUP_BY) !== null;
|
||||
if (!hasSaved && connections.some((c) => c.group)) {
|
||||
if (
|
||||
!hasSaved &&
|
||||
connections.some((c) => (c.providerSpecificData?.tag as string | undefined)?.trim())
|
||||
) {
|
||||
setGroupBy("environment");
|
||||
}
|
||||
}, [connections]);
|
||||
|
||||
Reference in New Issue
Block a user