v3
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""Identity editor and current assistant name, authenticated by Alfred's admin UI.
|
||||
|
||||
Identity text stays in config/identity.md. All writes are atomic; dated revisions
|
||||
Identity is stored natively in Hermes SOUL.md, not injected into questions.
|
||||
All writes are atomic; dated revisions
|
||||
are kept separately. Technical names/paths/API identifiers are never renamed.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
@@ -19,7 +20,7 @@ from services import admin_console
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CONFIG = ROOT / 'config'
|
||||
IDENTITY = CONFIG / 'identity.md'
|
||||
IDENTITY = Path('/root/.hermes/SOUL.md')
|
||||
TRACKER = CONFIG / 'identity_name_state.json'
|
||||
HISTORY = CONFIG / 'identity_history'
|
||||
LOCK = threading.RLock()
|
||||
@@ -33,12 +34,10 @@ def active_name():
|
||||
|
||||
|
||||
def identity_path():
|
||||
# Avoid an admin Web editor writing outside the identity config directory.
|
||||
raw = Path(os.getenv('ALFRED_IDENTITY_FILE', str(IDENTITY))).expanduser()
|
||||
resolved = raw.resolve()
|
||||
if resolved.parent != CONFIG.resolve() or raw.is_symlink():
|
||||
raise ValueError('Le fichier ALFRED_IDENTITY_FILE est externe à config/ : édition Web refusée.')
|
||||
return resolved
|
||||
# No arbitrary paths from env or web; this editor controls one fixed Hermes file.
|
||||
if IDENTITY.is_symlink():
|
||||
raise ValueError('SOUL.md ne doit pas être un lien symbolique.')
|
||||
return IDENTITY
|
||||
|
||||
|
||||
def sha(text):
|
||||
@@ -115,7 +114,7 @@ def sync_identity_name(name=None):
|
||||
original = _read_text()
|
||||
if not original.strip():
|
||||
# No identity installed: don't silently create a new persona.
|
||||
raise ValueError('Le fichier identity.md est vide ou absent.')
|
||||
raise ValueError('Le fichier SOUL.md est vide ou absent.')
|
||||
old = _old_name(original)
|
||||
updated = _replace_persona_name(original, old, new)
|
||||
if updated != original:
|
||||
@@ -129,7 +128,7 @@ def sync_identity_name(name=None):
|
||||
|
||||
|
||||
def identity_for_hermes(text):
|
||||
"""Runtime guard: current name wins even if a legacy identity wasn't synced."""
|
||||
"""Legacy compatibility only. No longer used to build user prompts."""
|
||||
new = active_name()
|
||||
old = _old_name(text)
|
||||
content = _replace_persona_name(text, old, new) if text else text
|
||||
@@ -161,7 +160,7 @@ def register_identity_page(app):
|
||||
except (OSError, ValueError) as e:
|
||||
return jsonify(error=str(e)), 503
|
||||
res = jsonify(name=active_name(), text=content, revision=sha(content),
|
||||
file='config/identity.md')
|
||||
file='/root/.hermes/SOUL.md')
|
||||
res.headers['Cache-Control'] = 'no-store, private'
|
||||
return res
|
||||
|
||||
@@ -190,15 +189,11 @@ def register_identity_page(app):
|
||||
mode = (path.stat().st_mode & 0o777) if path.exists() else 0o600
|
||||
_save_atomic(path, text, mode)
|
||||
res = jsonify(ok=True, revision=sha(text), name=active_name(),
|
||||
updated=text != old, file='config/identity.md')
|
||||
updated=text != old, file='/root/.hermes/SOUL.md')
|
||||
res.headers['Cache-Control'] = 'no-store, private'
|
||||
return res
|
||||
except (OSError, ValueError) as e:
|
||||
return jsonify(error='Enregistrement impossible : '+str(e)), 500
|
||||
|
||||
app.register_blueprint(bp)
|
||||
# If a renamed assistant was configured before installation, reconcile on startup.
|
||||
try:
|
||||
sync_identity_name()
|
||||
except (OSError, ValueError) as e:
|
||||
app.logger.warning('Synchronisation identité différée : %s', e)
|
||||
# No startup rewrite: keep manually edited SOUL.md intact.
|
||||
|
||||
Reference in New Issue
Block a user