Align translation client with GenieHive auth

This commit is contained in:
welsberr 2026-04-28 21:57:48 -04:00
parent 7aa4c3f50e
commit 8e5c4ae551
4 changed files with 39 additions and 2 deletions

View File

@ -34,7 +34,7 @@ Recommended meaning of the fields:
- `provider`: translation backend. The supported provider is currently - `provider`: translation backend. The supported provider is currently
`geniehive`. `geniehive`.
- `model`: a GenieHive role ID or directly addressable model name. - `model`: a GenieHive role ID or directly addressable model name.
- `api_key`: the GenieHive client key. - `api_key`: the GenieHive client key, sent as the `X-Api-Key` request header.
- `timeout`: request timeout in seconds. - `timeout`: request timeout in seconds.
- `system_prompt`: the translation policy for the client. - `system_prompt`: the translation policy for the client.

View File

@ -34,6 +34,14 @@
{ "code": "hi", "name": "हिन्दी" } { "code": "hi", "name": "हिन्दी" }
] ]
}, },
"translation": {
"provider": "geniehive",
"base_url": "http://127.0.0.1:8800",
"model": "scientific_translator",
"api_key": "change-me-client-key",
"timeout": 120,
"system_prompt": "You are a careful scientific translator. Preserve meaning, structure, citations, and technical terms. Return only the translation."
},
"navigation": [ "navigation": [
{ "label": "Start Here", "href": "#start" }, { "label": "Start Here", "href": "#start" },
{ "label": "Key Resources", "href": "#resources" }, { "label": "Key Resources", "href": "#resources" },

View File

@ -60,7 +60,7 @@ class GenieHiveTranslator:
data = json.dumps(payload).encode("utf-8") data = json.dumps(payload).encode("utf-8")
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
if self.config.api_key: if self.config.api_key:
headers["Authorization"] = f"Bearer {self.config.api_key}" headers["X-Api-Key"] = self.config.api_key
req = request.Request(url, data=data, headers=headers, method="POST") req = request.Request(url, data=data, headers=headers, method="POST")
try: try:
with request.urlopen(req, timeout=self.config.timeout) as resp: with request.urlopen(req, timeout=self.config.timeout) as resp:

View File

@ -5,6 +5,7 @@ import unittest
from pathlib import Path from pathlib import Path
from types import SimpleNamespace from types import SimpleNamespace
import sys import sys
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
@ -313,6 +314,34 @@ class SciSiteForgeTests(unittest.TestCase):
self.assertIn("Spanish", user_text) self.assertIn("Spanish", user_text)
self.assertIn("evolución", user_text) self.assertIn("evolución", user_text)
def test_geniehive_translator_uses_geniehive_api_key_header(self) -> None:
translator = GenieHiveTranslator(
TranslationConfig(base_url="http://geniehive.local:8800", model="translation-role", api_key="abc123")
)
captured: dict[str, object] = {}
class FakeResponse:
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
def read(self):
return b'{"choices":[{"message":{"content":"Hola"}}]}'
def fake_urlopen(req, timeout):
captured["headers"] = dict(req.header_items())
captured["timeout"] = timeout
return FakeResponse()
with patch("scisiteforge.translations.request.urlopen", fake_urlopen):
self.assertEqual(translator.translate("Hello", "Spanish"), "Hola")
headers = captured["headers"]
self.assertEqual(headers["X-api-key"], "abc123")
self.assertNotIn("Authorization", headers)
def test_translate_site_builds_translator_from_config(self) -> None: def test_translate_site_builds_translator_from_config(self) -> None:
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory