Hermes Bot commited on
Commit
5941741
·
unverified ·
1 Parent(s): f525e1a

feat: add support for custom OpenAI-compatible endpoints in config UI

Browse files
Files changed (4) hide show
  1. app.py +17 -4
  2. shared/inference_client.py +1 -0
  3. static/index.html +3 -0
  4. static/main.js +10 -2
app.py CHANGED
@@ -66,6 +66,7 @@ _USER_CONFIG_LOCK = threading.Lock()
66
  _USER_CONFIG: Dict[str, Optional[str]] = {
67
  "hf_token": None,
68
  "model": None,
 
69
  }
70
 
71
 
@@ -79,6 +80,11 @@ def get_user_model() -> Optional[str]:
79
  return _USER_CONFIG["model"]
80
 
81
 
 
 
 
 
 
82
  # ---------------------------------------------------------------------------
83
  # Llama.cpp Inference Setup
84
  # ---------------------------------------------------------------------------
@@ -252,6 +258,7 @@ def generate_llm_story_beat(genre: str, history: List[Dict[str, str]], instructi
252
  temperature=0.7,
253
  token=get_user_hf_token(),
254
  model=get_user_model(),
 
255
  )
256
  return result.text.strip()
257
  except Exception as e:
@@ -276,6 +283,7 @@ def generate_llm_choices_for_story(genre: str, story: str) -> List[str]:
276
  temperature=0.8,
277
  token=get_user_hf_token(),
278
  model=get_user_model(),
 
279
  )
280
  return _parse_choices(result.text)
281
  except Exception as e:
@@ -307,6 +315,7 @@ def generate_llm_health_effect(genre: str, history: List[Dict[str, str]], curren
307
  temperature=0.8,
308
  token=get_user_hf_token(),
309
  model=get_user_model(),
 
310
  )
311
  text = result.text.strip()
312
  except Exception as e:
@@ -559,15 +568,18 @@ async def game_choice(payload: dict):
559
  @fastapi_app.post("/api/config")
560
  async def update_config(body: dict):
561
  with _USER_CONFIG_LOCK:
562
- if body.get("hf_token"):
563
- _USER_CONFIG["hf_token"] = body["hf_token"].strip() or None
564
- if body.get("model") and str(body["model"]).strip():
565
- _USER_CONFIG["model"] = str(body["model"]).strip()
 
 
566
  current = dict(_USER_CONFIG)
567
  return {
568
  "status": "ok",
569
  "model": current["model"] or TINYBARD_MODEL,
570
  "has_token": bool(current["hf_token"]),
 
571
  }
572
 
573
 
@@ -578,6 +590,7 @@ async def get_config():
578
  return {
579
  "model": current["model"] or TINYBARD_MODEL,
580
  "has_token": bool(current["hf_token"]),
 
581
  }
582
 
583
 
 
66
  _USER_CONFIG: Dict[str, Optional[str]] = {
67
  "hf_token": None,
68
  "model": None,
69
+ "custom_endpoint": None,
70
  }
71
 
72
 
 
80
  return _USER_CONFIG["model"]
81
 
82
 
83
+ def get_user_custom_endpoint() -> Optional[str]:
84
+ with _USER_CONFIG_LOCK:
85
+ return _USER_CONFIG["custom_endpoint"]
86
+
87
+
88
  # ---------------------------------------------------------------------------
89
  # Llama.cpp Inference Setup
90
  # ---------------------------------------------------------------------------
 
258
  temperature=0.7,
259
  token=get_user_hf_token(),
260
  model=get_user_model(),
261
+ custom_endpoint=get_user_custom_endpoint(),
262
  )
263
  return result.text.strip()
264
  except Exception as e:
 
283
  temperature=0.8,
284
  token=get_user_hf_token(),
285
  model=get_user_model(),
286
+ custom_endpoint=get_user_custom_endpoint(),
287
  )
288
  return _parse_choices(result.text)
289
  except Exception as e:
 
315
  temperature=0.8,
316
  token=get_user_hf_token(),
317
  model=get_user_model(),
318
+ custom_endpoint=get_user_custom_endpoint(),
319
  )
320
  text = result.text.strip()
321
  except Exception as e:
 
568
  @fastapi_app.post("/api/config")
569
  async def update_config(body: dict):
570
  with _USER_CONFIG_LOCK:
571
+ if "hf_token" in body:
572
+ _USER_CONFIG["hf_token"] = body["hf_token"].strip() if body["hf_token"] else None
573
+ if "model" in body:
574
+ _USER_CONFIG["model"] = body["model"].strip() if body["model"] else None
575
+ if "custom_endpoint" in body:
576
+ _USER_CONFIG["custom_endpoint"] = body["custom_endpoint"].strip() if body["custom_endpoint"] else None
577
  current = dict(_USER_CONFIG)
578
  return {
579
  "status": "ok",
580
  "model": current["model"] or TINYBARD_MODEL,
581
  "has_token": bool(current["hf_token"]),
582
+ "custom_endpoint": current["custom_endpoint"],
583
  }
584
 
585
 
 
590
  return {
591
  "model": current["model"] or TINYBARD_MODEL,
592
  "has_token": bool(current["hf_token"]),
593
+ "custom_endpoint": current["custom_endpoint"],
594
  }
595
 
596
 
shared/inference_client.py CHANGED
@@ -111,6 +111,7 @@ def generate(
111
  temperature: float = 0.7,
112
  token: Optional[str] = None,
113
  model: Optional[str] = None,
 
114
  ) -> InferenceResult:
115
  """Run a chat-style inference call, with cooldown enforcement.
116
 
 
111
  temperature: float = 0.7,
112
  token: Optional[str] = None,
113
  model: Optional[str] = None,
114
+ custom_endpoint: Optional[str] = None,
115
  ) -> InferenceResult:
116
  """Run a chat-style inference call, with cooldown enforcement.
117
 
static/index.html CHANGED
@@ -85,6 +85,9 @@
85
  <label for="tb-token-input">HF Token (optional)</label>
86
  <input type="password" id="tb-token-input" placeholder="hf_..." />
87
 
 
 
 
88
  <button id="tb-config-save">Save & Reload</button>
89
  <span id="tb-config-status" style="margin-left:0.5rem;color:var(--asp-moss,#588157);"></span>
90
  </div>
 
85
  <label for="tb-token-input">HF Token (optional)</label>
86
  <input type="password" id="tb-token-input" placeholder="hf_..." />
87
 
88
+ <label for="tb-endpoint-input">Custom Endpoint (optional)</label>
89
+ <input type="text" id="tb-endpoint-input" placeholder="https://api.together.xyz/v1" />
90
+
91
  <button id="tb-config-save">Save & Reload</button>
92
  <span id="tb-config-status" style="margin-left:0.5rem;color:var(--asp-moss,#588157);"></span>
93
  </div>
static/main.js CHANGED
@@ -253,6 +253,7 @@ const configClose = document.getElementById('tb-config-close');
253
  const configSave = document.getElementById('tb-config-save');
254
  const modelInput = document.getElementById('tb-model-input');
255
  const tokenInput = document.getElementById('tb-token-input');
 
256
  const configStatus = document.getElementById('tb-config-status');
257
 
258
  if (configBtn && configModal) {
@@ -260,6 +261,9 @@ if (configBtn && configModal) {
260
  const cfg = await fetch('/api/config').then(r => r.json());
261
  modelInput.value = cfg.model || '';
262
  tokenInput.value = '';
 
 
 
263
  configStatus.textContent = '';
264
  configModal.style.display = 'flex';
265
  });
@@ -274,8 +278,12 @@ if (configBtn && configModal) {
274
 
275
  configSave.addEventListener('click', async () => {
276
  const body = {};
277
- if (modelInput.value.trim()) body.model = modelInput.value.trim();
278
- if (tokenInput.value.trim()) body.hf_token = tokenInput.value.trim();
 
 
 
 
279
 
280
  const resp = await fetch('/api/config', {
281
  method: 'POST',
 
253
  const configSave = document.getElementById('tb-config-save');
254
  const modelInput = document.getElementById('tb-model-input');
255
  const tokenInput = document.getElementById('tb-token-input');
256
+ const endpointInput = document.getElementById('tb-endpoint-input');
257
  const configStatus = document.getElementById('tb-config-status');
258
 
259
  if (configBtn && configModal) {
 
261
  const cfg = await fetch('/api/config').then(r => r.json());
262
  modelInput.value = cfg.model || '';
263
  tokenInput.value = '';
264
+ if (endpointInput) {
265
+ endpointInput.value = cfg.custom_endpoint || '';
266
+ }
267
  configStatus.textContent = '';
268
  configModal.style.display = 'flex';
269
  });
 
278
 
279
  configSave.addEventListener('click', async () => {
280
  const body = {};
281
+ // We always pass these fields to let user clear them (by passing empty strings or letting backend handle them)
282
+ body.model = modelInput.value.trim() || "";
283
+ body.hf_token = tokenInput.value.trim() || "";
284
+ if (endpointInput) {
285
+ body.custom_endpoint = endpointInput.value.trim() || "";
286
+ }
287
 
288
  const resp = await fetch('/api/config', {
289
  method: 'POST',