Download install_functions.py from Nerdur/webui: direct link, hf CLI and curl.
- Browser
- Download file 17.3 kB
-
https://huggingface.co/spaces/Nerdur/webui/resolve/main/install_functions.py
- Command line
-
hf download hf://spaces/Nerdur/webui/install_functions.py
-
curl -L -o install_functions.py https://huggingface.co/spaces/Nerdur/webui/resolve/main/install_functions.py
17.3 kB
| """ | |
| Instalira sve funkcije (filters, tools, actions) i kreira Custom Model Preset. | |
| Poziva se automatski iz setup_endpoints.sh pri startu Space-a. | |
| Koristi: python3 install_functions.py <base_url> <token> | |
| """ | |
| import json | |
| import urllib.request | |
| import urllib.error | |
| import sys | |
| import os | |
| BASE_URL = sys.argv[1] if len(sys.argv) > 1 else 'http://localhost:8080' | |
| TOKEN = sys.argv[2] if len(sys.argv) > 2 else '' | |
| if not TOKEN: | |
| print("β No token provided.") | |
| sys.exit(1) | |
| HEADERS = { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': f'Bearer {TOKEN}' | |
| } | |
| APP_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # Helpers | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def api(method, path, data=None): | |
| url = BASE_URL + path | |
| body = json.dumps(data).encode() if data is not None else None | |
| req = urllib.request.Request(url, data=body, headers=HEADERS, method=method) | |
| try: | |
| with urllib.request.urlopen(req) as r: | |
| return r.status, json.loads(r.read().decode()) | |
| except urllib.error.HTTPError as e: | |
| return e.code, e.read().decode() | |
| def install_function(func_id, name, func_type, content): | |
| """Instaliraj ili aΕΎuriraj funkciju.""" | |
| # Provjeri postoji li | |
| status, _ = api('GET', f'/api/v1/functions/id/{func_id}') | |
| payload = { | |
| 'id': func_id, | |
| 'name': name, | |
| 'type': func_type, | |
| 'content': content, | |
| 'meta': {'description': name} | |
| } | |
| if status == 200: | |
| s, r = api('POST', f'/api/v1/functions/id/{func_id}/update', payload) | |
| label = "aΕΎuriran" if s == 200 else f"greΕ‘ka {s}" | |
| else: | |
| s, r = api('POST', '/api/v1/functions/create', payload) | |
| label = "instaliran" if s == 200 else f"greΕ‘ka {s}" | |
| # Aktiviraj | |
| api('POST', f'/api/v1/functions/id/{func_id}/toggle') | |
| icon = "β " if s == 200 else "β" | |
| print(f" {icon} [{func_type}] {name} β {label}") | |
| return s == 200 | |
| def load_json_function(filepath): | |
| """UΔitaj funkciju iz JSON export fajla.""" | |
| with open(filepath) as f: | |
| d = json.load(f) | |
| item = d[0] if isinstance(d, list) else d | |
| # Detektuj tip iz sadrΕΎaja | |
| content = item.get('content', '') | |
| if 'class Filter' in content: | |
| ftype = 'filter' | |
| elif 'class Pipe' in content: | |
| ftype = 'pipe' | |
| elif 'class Tools' in content or 'class Action' in content: | |
| ftype = 'action' | |
| else: | |
| ftype = item.get('meta', {}).get('type', 'filter') | |
| return item['id'], item['name'], ftype, content | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 1. Instaliraj sve JSON funkcije | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nπ¦ Instaliram funkcije iz JSON fajlova...") | |
| JSON_FILES = [ | |
| 'global_system_prompt_filter.json', | |
| '__easysearch_v0_4_3__high-performance_web_search_filter.json', | |
| 'token_saver.json', | |
| 'context_clip_filter.json', | |
| 'auto_disable_native_tools.json', | |
| 'auto_memory.json', | |
| '__mermaid_doctor_-_heals_broken_mermaid_diagrams_generated_by_small_or_hallucinating_models.json', | |
| 'github_simple.json', | |
| 'pdf_tools_-_rich_ui_for_in_context_basic_editing_.json', | |
| ] | |
| installed_filter_ids = [] | |
| for fname in JSON_FILES: | |
| fpath = os.path.join(APP_DIR, fname) | |
| if not os.path.exists(fpath): | |
| print(f" β οΈ {fname} nije pronaΔen, preskaΔem") | |
| continue | |
| func_id, name, ftype, content = load_json_function(fpath) | |
| ok = install_function(func_id, name, ftype, content) | |
| if ok and ftype == 'filter': | |
| installed_filter_ids.append(func_id) | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 2. Instaliraj naΕ‘e custom Python funkcije | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nπ οΈ Instaliram custom funkcije...") | |
| CUSTOM_FUNCTIONS = [ | |
| ('context_detector', 'Context Detector', 'filter', 'context_detector.py'), | |
| ('token_compressor', 'Token Compressor', 'filter', 'token_compressor.py'), | |
| ('coding_fallback', 'π Smart Coding Router', 'pipe', 'coding_priority_pipe.py'), | |
| ('smart_matcher', 'Smart Matcher', 'tool', 'smart_matcher.py'), | |
| ] | |
| for func_id, name, ftype, pyfile in CUSTOM_FUNCTIONS: | |
| fpath = os.path.join(APP_DIR, pyfile) | |
| if not os.path.exists(fpath): | |
| print(f" β οΈ {pyfile} nije pronaΔen") | |
| continue | |
| content = open(fpath).read() | |
| ok = install_function(func_id, name, ftype, content) | |
| if ok and ftype == 'filter': | |
| installed_filter_ids.append(func_id) | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 3. Postavi Global System Prompt | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nπ Postavljam Global System Prompt...") | |
| SYSTEM_PROMPT_FILE = os.path.join(APP_DIR, 'system_prompt.txt') | |
| if os.path.exists(SYSTEM_PROMPT_FILE): | |
| system_prompt = open(SYSTEM_PROMPT_FILE).read() | |
| # Update valve za global_system_prompt_filter | |
| valve_payload = { | |
| 'system_message': system_prompt, | |
| 'timezone': 'Europe/Sarajevo', | |
| 'skip_tags': [] | |
| } | |
| s, r = api('POST', '/api/v1/functions/id/global_system_prompt_filter/valves/update', valve_payload) | |
| if s == 200: | |
| print(" β System prompt postavljen") | |
| else: | |
| print(f" β οΈ GreΕ‘ka pri postavljanju system prompta: {s}") | |
| else: | |
| print(" β οΈ system_prompt.txt nije pronaΔen") | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 4. Kreiraj Custom Model Preset | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nπ€ Kreiram Custom Model Preset...") | |
| # Sve filter ID-ove koji treba biti aktivni na modelu | |
| ALL_FILTER_IDS = list(dict.fromkeys([ | |
| 'global_system_prompt_filter', | |
| 'easysearch', | |
| 'token_saver', | |
| 'context_clip_filter', | |
| 'auto_disable_native_tools', | |
| 'auto_memory', | |
| 'context_detector', | |
| 'token_compressor', | |
| 'mermaid_doctor', | |
| ] + installed_filter_ids)) | |
| model_payload = { | |
| 'id': 'nerdur_assistant', | |
| 'name': 'π§ Nerdur Assistant (Full)', | |
| 'base_model_id': 'coding_fallback.coding_fallback', | |
| 'meta': { | |
| 'description': 'Smart Coding Router sa svim filterima: web search, memory, token saver, context detector i viΕ‘e.', | |
| 'profile_image_url': '/static/favicon.png', | |
| 'tags': [{'name': 'custom'}, {'name': 'coding'}], | |
| 'capabilities': { | |
| 'vision': False, | |
| 'citations': True, | |
| 'usage': True, | |
| } | |
| }, | |
| 'params': { | |
| 'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', | |
| 'temperature': 0.2, | |
| 'max_tokens': 4096, | |
| }, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| 'tool_ids': ['smart_matcher'], | |
| 'action_ids': ['pdf_tools_rich_ui_editor'], | |
| } | |
| # Provjeri postoji li model | |
| status, _ = api('GET', '/api/v1/models/model?id=nerdur_assistant') | |
| if status == 200: | |
| s, r = api('POST', '/api/v1/models/model/update?id=nerdur_assistant', model_payload) | |
| label = "aΕΎuriran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| else: | |
| s, r = api('POST', '/api/v1/models/create', model_payload) | |
| label = "kreiran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| icon = "β " if s == 200 else "β" | |
| print(f" {icon} Model 'π§ Nerdur Assistant (Full)' β {label}") | |
| print("\nβ Instalacija zavrΕ‘ena!") | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 5. Kreiraj Gemini 2.5 Flash Preset | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nβ‘ Kreiram Gemini 2.5 Flash Preset...") | |
| gemini_payload = { | |
| 'id': 'nerdur_gemini_flash', | |
| 'name': 'β‘ Gemini 2.5 Flash (Coding)', | |
| 'base_model_id': 'models/gemini-2.5-flash', | |
| 'meta': { | |
| 'description': 'Gemini 2.5 Flash sa svim filterima β web search, memory, token saver i viΕ‘e.', | |
| 'profile_image_url': '/static/favicon.png', | |
| 'tags': [{'name': 'custom'}, {'name': 'coding'}, {'name': 'gemini'}], | |
| 'capabilities': { | |
| 'vision': True, | |
| 'citations': True, | |
| 'usage': True, | |
| } | |
| }, | |
| 'params': { | |
| 'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', | |
| 'temperature': 0.2, | |
| 'max_tokens': 8192, | |
| }, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| 'tool_ids': ['smart_matcher'], | |
| 'action_ids': ['pdf_tools_rich_ui_editor'], | |
| } | |
| status, _ = api('GET', '/api/v1/models/model?id=nerdur_gemini_flash') | |
| if status == 200: | |
| s, r = api('POST', '/api/v1/models/model/update?id=nerdur_gemini_flash', gemini_payload) | |
| label = "aΕΎuriran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| else: | |
| s, r = api('POST', '/api/v1/models/create', gemini_payload) | |
| label = "kreiran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| icon = "β " if s == 200 else "β" | |
| print(f" {icon} Model 'β‘ Gemini 2.5 Flash (Coding)' β {label}") | |
| print("\nβ Svi modeli kreirani!") | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 6. Groq preset | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nπ Kreiram Groq preset...") | |
| groq_payload = { | |
| 'id': 'nerdur_groq_coding', | |
| 'name': 'π Groq Llama 3.3 70B (Coding)', | |
| 'base_model_id': 'llama-3.3-70b-versatile', | |
| 'meta': { | |
| 'description': 'Kimi K2 na Groq β izuzetno brz, odliΔan za kodiranje, besplatan.', | |
| 'profile_image_url': '/static/favicon.png', | |
| 'tags': [{'name': 'custom'}, {'name': 'coding'}, {'name': 'groq'}], | |
| 'capabilities': {'vision': False, 'citations': True, 'usage': True} | |
| }, | |
| 'params': { | |
| 'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', | |
| 'temperature': 0.2, | |
| 'max_tokens': 8192, | |
| }, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| 'tool_ids': ['smart_matcher'], | |
| 'action_ids': ['pdf_tools_rich_ui_editor'], | |
| } | |
| status, _ = api('GET', '/api/v1/models/model?id=nerdur_groq_coding') | |
| if status == 200: | |
| s, r = api('POST', '/api/v1/models/model/update?id=nerdur_groq_coding', groq_payload) | |
| label = "aΕΎuriran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| else: | |
| s, r = api('POST', '/api/v1/models/create', groq_payload) | |
| label = "kreiran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| print(f" {'β ' if s == 200 else 'β'} 'π Groq Kimi K2 (Coding)' β {label}") | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 7. Cerebras preset | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nπ§ Kreiram Cerebras preset...") | |
| cerebras_payload = { | |
| 'id': 'nerdur_cerebras_coding', | |
| 'name': 'π§ Cerebras Llama 4 Scout (Coding)', | |
| 'base_model_id': 'llama-4-scout-17b-16e-instruct', | |
| 'meta': { | |
| 'description': 'Llama 3.3 70B na Cerebras β jedan od najbrΕΎih inference engine-a, besplatan.', | |
| 'profile_image_url': '/static/favicon.png', | |
| 'tags': [{'name': 'custom'}, {'name': 'coding'}, {'name': 'cerebras'}], | |
| 'capabilities': {'vision': False, 'citations': True, 'usage': True} | |
| }, | |
| 'params': { | |
| 'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', | |
| 'temperature': 0.2, | |
| 'max_tokens': 8192, | |
| }, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| 'tool_ids': ['smart_matcher'], | |
| 'action_ids': ['pdf_tools_rich_ui_editor'], | |
| } | |
| status, _ = api('GET', '/api/v1/models/model?id=nerdur_cerebras_coding') | |
| if status == 200: | |
| s, r = api('POST', '/api/v1/models/model/update?id=nerdur_cerebras_coding', cerebras_payload) | |
| label = "aΕΎuriran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| else: | |
| s, r = api('POST', '/api/v1/models/create', cerebras_payload) | |
| label = "kreiran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| print(f" {'β ' if s == 200 else 'β'} 'π§ Cerebras Llama 3.3 (Coding)' β {label}") | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 8. SambaNova preset | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| print("\nβ‘ Kreiram SambaNova preset...") | |
| sambanova_payload = { | |
| 'id': 'nerdur_sambanova_coding', | |
| 'name': 'β‘ SambaNova Llama 3.3 (Coding)', | |
| 'base_model_id': 'Meta-Llama-3.3-70B-Instruct', | |
| 'meta': { | |
| 'description': 'Llama 3.3 70B na SambaNova β brz inference, dobar za kodiranje, besplatan.', | |
| 'profile_image_url': '/static/favicon.png', | |
| 'tags': [{'name': 'custom'}, {'name': 'coding'}, {'name': 'sambanova'}], | |
| 'capabilities': {'vision': False, 'citations': True, 'usage': True} | |
| }, | |
| 'params': { | |
| 'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', | |
| 'temperature': 0.2, | |
| 'max_tokens': 8192, | |
| }, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| 'tool_ids': ['smart_matcher'], | |
| 'action_ids': ['pdf_tools_rich_ui_editor'], | |
| } | |
| status, _ = api('GET', '/api/v1/models/model?id=nerdur_sambanova_coding') | |
| if status == 200: | |
| s, r = api('POST', '/api/v1/models/model/update?id=nerdur_sambanova_coding', sambanova_payload) | |
| label = "aΕΎuriran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| else: | |
| s, r = api('POST', '/api/v1/models/create', sambanova_payload) | |
| label = "kreiran" if s == 200 else f"greΕ‘ka {s}: {str(r)[:100]}" | |
| print(f" {'β ' if s == 200 else 'β'} 'β‘ SambaNova Llama 3.3 (Coding)' β {label}") | |
| print("\nπ Svih 5 preseta kreirano!") | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # 9. Dodatni presets za sve aktivne provajdere | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # BriΕ‘emo presete koji ne rade i duplikate | |
| DELETE_IDS = [ | |
| 'nerdur_claude', 'nerdur_gpt4o', 'nerdur_deepseek', 'nerdur_xai', | |
| 'nerdur_openrouter_free', 'nerdur_fireworks', | |
| 'nerdur_groq_coding', # brisemo stari groq da izbjegnemo duplikat | |
| ] | |
| print("\nποΈ BriΕ‘em presete koji ne rade i duplikate...") | |
| for did in DELETE_IDS: | |
| s, r = api('DELETE', f'/api/v1/models/model/delete?id={did}') | |
| if s == 200: | |
| print(f" ποΈ {did} β obrisan") | |
| else: | |
| print(f" β οΈ {did} β nije pronaΔen (OK)") | |
| # Kreiraj Groq preset ponovo (Δist, bez duplikata) | |
| print("\nπ Kreiram Groq Llama preset (Δist)...") | |
| groq_clean = { | |
| 'id': 'nerdur_groq_llama', | |
| 'name': 'π Groq Llama 3.3 70B (Coding)', | |
| 'base_model_id': 'llama-3.3-70b-versatile', | |
| 'meta': {'description': 'Groq Llama 3.3 70B β brz i pouzdan za kodiranje.'}, | |
| 'params': {'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', 'temperature': 0.2, 'max_tokens': 8192}, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| } | |
| s, r = api('GET', '/api/v1/models/model?id=nerdur_groq_llama') | |
| if s == 200: | |
| api('POST', '/api/v1/models/model/update?id=nerdur_groq_llama', groq_clean) | |
| print(" β Groq Llama preset β aΕΎuriran") | |
| else: | |
| api('POST', '/api/v1/models/create', groq_clean) | |
| print(" β Groq Llama preset β kreiran") | |
| # Kreiraj Mistral preset | |
| print("\nπ΅ Kreiram Mistral preset...") | |
| mistral_clean = { | |
| 'id': 'nerdur_mistral', | |
| 'name': 'π΅ Mistral Large (Coding)', | |
| 'base_model_id': 'mistral-large-latest', | |
| 'meta': {'description': 'Mistral Large β europski model, odliΔan za kodiranje.'}, | |
| 'params': {'system': open(SYSTEM_PROMPT_FILE).read() if os.path.exists(SYSTEM_PROMPT_FILE) else '', 'temperature': 0.2, 'max_tokens': 8192}, | |
| 'filter_ids': ALL_FILTER_IDS, | |
| } | |
| s, r = api('GET', '/api/v1/models/model?id=nerdur_mistral') | |
| if s == 200: | |
| api('POST', '/api/v1/models/model/update?id=nerdur_mistral', mistral_clean) | |
| print(" β Mistral preset β aΕΎuriran") | |
| else: | |
| api('POST', '/api/v1/models/create', mistral_clean) | |
| print(" β Mistral preset β kreiran") | |
| print("\nπ Instalacija kompletna!") | |