release: v0.50.102–v0.50.108 batch (code blocks, utf-8, image URLs, deletion warning, PermissionError, Docker docs, kimi-k2.5) (#755)
## Batch release: v0.50.102 – v0.50.108 Seven self-built PRs reviewed and approved by @nesquena, now consolidated into a single release branch. ### Included fixes | Version | PR | What it fixes | |---|---|---| | v0.50.102 | #746 | Code blocks lose newlines when not preceded by blank line (fixes #745) | | v0.50.103 | #743 | `encoding='utf-8'` on `write_text()` in `api/profiles.py` — Windows `.env` detection (fixes #741) | | v0.50.104 | #735 | Agent `MEDIA:localhost:*` image URLs rewritten to `document.baseURI` — remote users get working images (fixes #642) | | v0.50.105 | #736 | Profile deletion warning strengthened: "permanently deleted, cannot be undone" across all 6 locales (fixes #637) | | v0.50.106 | #738 | Catch `PermissionError` in `_signing_key()` — three-container Docker UID mismatch no longer crashes all HTTP requests | | v0.50.107 | #737 | Docs: three-container UID/GID alignment guide in README + `HERMES_UID`/`HERMES_GID` forwarded in compose (fixes #645) | | v0.50.108 | #742 | Add `kimi-k2.5` to Kimi/Moonshot provider model list (fixes #740) | ### Testing - **pytest**: 1510 passed, 1 warning (1 pre-existing unrelated failure excluded) - **QA harness**: 20/20 passed (`~/WebUI/scripts/run-browser-tests.sh`) - **Browser**: layout, slash autocomplete width, edit button, image URL rewrite, profile deletion dialog all verified All PRs reviewed and approved by @nesquena. Ready to merge and tag **v0.50.108**.
This commit is contained in:
@@ -51,13 +51,13 @@ def _record_login_attempt(ip: str) -> None:
|
||||
def _signing_key():
|
||||
"""Return a random signing key, generating and persisting one on first call."""
|
||||
key_file = STATE_DIR / '.signing_key'
|
||||
if key_file.exists():
|
||||
try:
|
||||
try:
|
||||
if key_file.exists():
|
||||
raw = key_file.read_bytes()
|
||||
if len(raw) >= 32:
|
||||
return raw[:32]
|
||||
except Exception:
|
||||
logger.debug("Failed to read signing key from file, generating new key")
|
||||
except Exception:
|
||||
logger.debug("Failed to read or access signing key file, using in-memory key")
|
||||
# Generate a new random key
|
||||
key = secrets.token_bytes(32)
|
||||
try:
|
||||
|
||||
@@ -533,6 +533,7 @@ _PROVIDER_MODELS = {
|
||||
{"id": "moonshot-v1-32k", "label": "Moonshot v1 32k"},
|
||||
{"id": "moonshot-v1-128k", "label": "Moonshot v1 128k"},
|
||||
{"id": "kimi-latest", "label": "Kimi Latest"},
|
||||
{"id": "kimi-k2.5", "label": "Kimi K2.5"},
|
||||
],
|
||||
"minimax": [
|
||||
{"id": "MiniMax-M2.7", "label": "MiniMax M2.7"},
|
||||
|
||||
@@ -208,7 +208,7 @@ def switch_profile(name: str) -> dict:
|
||||
# Write sticky default for CLI consistency
|
||||
try:
|
||||
ap_file = _DEFAULT_HERMES_HOME / 'active_profile'
|
||||
ap_file.write_text(name if name != 'default' else '')
|
||||
ap_file.write_text(name if name != 'default' else '', encoding='utf-8')
|
||||
except Exception:
|
||||
logger.debug("Failed to write active profile file")
|
||||
|
||||
@@ -357,7 +357,7 @@ def _write_endpoint_to_config(profile_dir: Path, base_url: str = None, api_key:
|
||||
if api_key:
|
||||
model_section['api_key'] = api_key
|
||||
cfg['model'] = model_section
|
||||
config_path.write_text(_yaml.dump(cfg, default_flow_style=False, allow_unicode=True))
|
||||
config_path.write_text(_yaml.dump(cfg, default_flow_style=False, allow_unicode=True), encoding='utf-8')
|
||||
|
||||
|
||||
def create_profile_api(name: str, clone_from: str = None,
|
||||
|
||||
Reference in New Issue
Block a user