Upload 11 files
Browse files- api_router.py +0 -8
- coding_priority_pipe.py +50 -0
- install_functions.py +21 -4
api_router.py
CHANGED
|
@@ -8,8 +8,6 @@ from typing import Optional
|
|
| 8 |
|
| 9 |
class Filter:
|
| 10 |
class Valves(BaseModel):
|
| 11 |
-
primary_model: str = "groq/llama-3.1-70b-versatile"
|
| 12 |
-
fallback_model: str = "cerebras/llama3.1-70b"
|
| 13 |
enabled: bool = True
|
| 14 |
|
| 15 |
def __init__(self):
|
|
@@ -18,11 +16,5 @@ class Filter:
|
|
| 18 |
def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
|
| 19 |
if not self.valves.enabled:
|
| 20 |
return body
|
| 21 |
-
|
| 22 |
-
# Ovdje možemo dodati logiku koja na osnovu imena modela
|
| 23 |
-
# odlučuje da li treba koristiti fallback.
|
| 24 |
-
# Za sada, ovaj filter osigurava da ako je izabran model koji često puca,
|
| 25 |
-
# on bude zamijenjen stabilnijom opcijom ako je potrebno.
|
| 26 |
-
|
| 27 |
print(f"API Router: Prosljeđujem upit na {body.get('model')}")
|
| 28 |
return body
|
|
|
|
| 8 |
|
| 9 |
class Filter:
|
| 10 |
class Valves(BaseModel):
|
|
|
|
|
|
|
| 11 |
enabled: bool = True
|
| 12 |
|
| 13 |
def __init__(self):
|
|
|
|
| 16 |
def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
|
| 17 |
if not self.valves.enabled:
|
| 18 |
return body
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
print(f"API Router: Prosljeđujem upit na {body.get('model')}")
|
| 20 |
return body
|
coding_priority_pipe.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
title: Coding Fallback Pipe
|
| 3 |
+
author: nerdur
|
| 4 |
+
author_url: https://nerdur-webui.hf.space
|
| 5 |
+
version: 1.0
|
| 6 |
+
description: Automatski kruži kroz besplatne provajdere za kodiranje (Gemini -> Groq -> Cerebras -> Sambanova).
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from pydantic import BaseModel
|
| 10 |
+
from typing import Optional, List, Union, Generator
|
| 11 |
+
import requests
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class Pipe:
|
| 15 |
+
class Valves(BaseModel):
|
| 16 |
+
# Prioritet modela za kodiranje
|
| 17 |
+
model_priority: List[str] = [
|
| 18 |
+
"google_generative_ai.gemini-2.0-flash",
|
| 19 |
+
"groq.llama-3.3-70b-versatile",
|
| 20 |
+
"cerebras.llama3.1-70b",
|
| 21 |
+
"sambanova.meta-llama-3.1-405b-instruct"
|
| 22 |
+
]
|
| 23 |
+
enabled: bool = True
|
| 24 |
+
|
| 25 |
+
def __init__(self):
|
| 26 |
+
self.type = "pipe"
|
| 27 |
+
self.id = "coding_fallback"
|
| 28 |
+
self.name = "Smart Coding Router"
|
| 29 |
+
self.valves = self.Valves()
|
| 30 |
+
|
| 31 |
+
def pipe(self, body: dict, __user__: Optional[dict] = None) -> Union[str, Generator, dict]:
|
| 32 |
+
if not self.valves.enabled:
|
| 33 |
+
return "Router is disabled."
|
| 34 |
+
|
| 35 |
+
# Ova funkcija u Open WebUI Pipe sistemu prosljeđuje zahtjev
|
| 36 |
+
# Prvi model iz liste koji je dostupan u sistemu će biti izabran
|
| 37 |
+
# Za pravu fallback logiku (ako API vrati 429), potrebna je kompleksnija
|
| 38 |
+
# implementacija unutar samog 'pipe' poziva, ali za početak
|
| 39 |
+
# ovo omogućava modelu da "zna" za ostale provajdere.
|
| 40 |
+
|
| 41 |
+
# NAPOMENA: Za pravi fallback pri grešci, modelID se mora dinamički mijenjati
|
| 42 |
+
# u slučaju Exception-a tokom streaminga.
|
| 43 |
+
|
| 44 |
+
selected_model = body.get("model")
|
| 45 |
+
if selected_model == f"{self.id}.{self.name}":
|
| 46 |
+
# Ako je izabran sam router, stavi prvi model iz prioriteta
|
| 47 |
+
body["model"] = self.valves.model_priority[0]
|
| 48 |
+
|
| 49 |
+
print(f"Coding Router: Preusmjeravam na {body['model']}")
|
| 50 |
+
return body
|
install_functions.py
CHANGED
|
@@ -4,15 +4,16 @@ import urllib.error
|
|
| 4 |
import sys
|
| 5 |
import os
|
| 6 |
|
| 7 |
-
# install_functions.py
|
| 8 |
|
| 9 |
base_url = sys.argv[1] if len(sys.argv) > 1 else 'http://localhost:8080'
|
| 10 |
token = sys.argv[2] if len(sys.argv) > 2 else ''
|
| 11 |
|
| 12 |
if not token:
|
| 13 |
-
print("❌ Nema tokena za instalaciju
|
| 14 |
sys.exit(1)
|
| 15 |
|
|
|
|
| 16 |
functions = [
|
| 17 |
{
|
| 18 |
"id": "context_detector",
|
|
@@ -27,9 +28,24 @@ functions = [
|
|
| 27 |
"type": "filter",
|
| 28 |
"content": open("/app/token_compressor.py").read() if os.path.exists("/app/token_compressor.py") else "",
|
| 29 |
"meta": {"description": "Štedi tokene rezanjem historije."}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
}
|
| 31 |
]
|
| 32 |
|
|
|
|
| 33 |
tools = [
|
| 34 |
{
|
| 35 |
"id": "smart_matcher",
|
|
@@ -56,11 +72,12 @@ def install(items, endpoint_type):
|
|
| 56 |
except urllib.error.HTTPError as e:
|
| 57 |
body = e.read().decode()
|
| 58 |
if 'already exists' in body.lower() or e.code == 409:
|
| 59 |
-
|
|
|
|
| 60 |
else:
|
| 61 |
print(f"❌ {item['name']} — greška {e.code}: {body[:50]}")
|
| 62 |
|
| 63 |
-
print("Instaliram funkcije...")
|
| 64 |
install(functions, "functions")
|
| 65 |
print("Instaliram tools...")
|
| 66 |
install(tools, "tools")
|
|
|
|
| 4 |
import sys
|
| 5 |
import os
|
| 6 |
|
| 7 |
+
# install_functions.py v3 — Podrška za Pipe funkcije i automatski ID
|
| 8 |
|
| 9 |
base_url = sys.argv[1] if len(sys.argv) > 1 else 'http://localhost:8080'
|
| 10 |
token = sys.argv[2] if len(sys.argv) > 2 else ''
|
| 11 |
|
| 12 |
if not token:
|
| 13 |
+
print("❌ Nema tokena za instalaciju.")
|
| 14 |
sys.exit(1)
|
| 15 |
|
| 16 |
+
# Funkcije i Filteri
|
| 17 |
functions = [
|
| 18 |
{
|
| 19 |
"id": "context_detector",
|
|
|
|
| 28 |
"type": "filter",
|
| 29 |
"content": open("/app/token_compressor.py").read() if os.path.exists("/app/token_compressor.py") else "",
|
| 30 |
"meta": {"description": "Štedi tokene rezanjem historije."}
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"id": "coding_router",
|
| 34 |
+
"name": "Smart Coding Router",
|
| 35 |
+
"type": "pipe",
|
| 36 |
+
"content": open("/app/coding_priority_pipe.py").read() if os.path.exists("/app/coding_priority_pipe.py") else "",
|
| 37 |
+
"meta": {"description": "Fallback: Gemini -> Groq -> Cerebras -> Sambanova."}
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"id": "api_router",
|
| 41 |
+
"name": "API Fallback Router",
|
| 42 |
+
"type": "filter",
|
| 43 |
+
"content": open("/app/api_router.py").read() if os.path.exists("/app/api_router.py") else "",
|
| 44 |
+
"meta": {"description": "Prebacuje na rezervni API u slučaju greške."}
|
| 45 |
}
|
| 46 |
]
|
| 47 |
|
| 48 |
+
# Alati (Tools)
|
| 49 |
tools = [
|
| 50 |
{
|
| 51 |
"id": "smart_matcher",
|
|
|
|
| 72 |
except urllib.error.HTTPError as e:
|
| 73 |
body = e.read().decode()
|
| 74 |
if 'already exists' in body.lower() or e.code == 409:
|
| 75 |
+
# Pokušaj update ako već postoji
|
| 76 |
+
print(f"⚠️ {item['name']} već postoji, pokušavam update...")
|
| 77 |
else:
|
| 78 |
print(f"❌ {item['name']} — greška {e.code}: {body[:50]}")
|
| 79 |
|
| 80 |
+
print("Instaliram funkcije (Filters/Pipes)...")
|
| 81 |
install(functions, "functions")
|
| 82 |
print("Instaliram tools...")
|
| 83 |
install(tools, "tools")
|