fixed chat textjson format, selected session for all, fixed android echo
This commit is contained in:
parent
f2aebcbad9
commit
1972c4d1b4
|
|
@ -96,14 +96,23 @@ const ChatScreen: React.FC = () => {
|
|||
const sender = (message.payload.sender as string) || '';
|
||||
if (sender === 'user' || sender === 'diagnostic') return;
|
||||
|
||||
const ariaMsg: ChatMessage = {
|
||||
id: nextId(),
|
||||
sender: 'aria',
|
||||
text: (message.payload.text as string) || '',
|
||||
timestamp: message.timestamp,
|
||||
attachments: message.payload.attachments as Attachment[] | undefined,
|
||||
};
|
||||
setMessages(prev => [...prev, ariaMsg]);
|
||||
const text = (message.payload.text as string) || '';
|
||||
const ts = message.timestamp;
|
||||
// Duplikat-Schutz: gleicher Text innerhalb 5s ignorieren
|
||||
setMessages(prev => {
|
||||
const isDuplicate = prev.some(m =>
|
||||
m.sender === 'aria' && m.text === text && Math.abs(m.timestamp - ts) < 5000
|
||||
);
|
||||
if (isDuplicate) return prev;
|
||||
const ariaMsg: ChatMessage = {
|
||||
id: nextId(),
|
||||
sender: 'aria',
|
||||
text,
|
||||
timestamp: ts,
|
||||
attachments: message.payload.attachments as Attachment[] | undefined,
|
||||
};
|
||||
return [...prev, ariaMsg];
|
||||
});
|
||||
}
|
||||
|
||||
// TTS-Audio abspielen wenn vorhanden
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import wave
|
|||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import urllib.request
|
||||
import numpy as np
|
||||
import sounddevice as sd
|
||||
import websockets
|
||||
|
|
@ -59,6 +60,7 @@ RVS_PORT = os.getenv("RVS_PORT", "443") # Port des RVS
|
|||
RVS_TLS = os.getenv("RVS_TLS", "true") # true = wss://, false = ws://
|
||||
RVS_TLS_FALLBACK = os.getenv("RVS_TLS_FALLBACK", "true") # Bei TLS-Fehler ws:// versuchen
|
||||
RVS_TOKEN = os.getenv("RVS_TOKEN", "") # Pairing-Token (gleich wie in der App)
|
||||
DIAGNOSTIC_URL = os.getenv("DIAGNOSTIC_URL", "http://127.0.0.1:3001") # Diagnostic API
|
||||
WHISPER_MODEL = os.getenv("WHISPER_MODEL", "small")
|
||||
WHISPER_LANGUAGE = os.getenv("WHISPER_LANGUAGE", "de")
|
||||
|
||||
|
|
@ -409,7 +411,8 @@ class ARIABridge:
|
|||
self.ws_url = self.config.get("ARIA_CORE_WS", CORE_WS_URL)
|
||||
self.core_auth_token = self.config.get("ARIA_AUTH_TOKEN", CORE_AUTH_TOKEN)
|
||||
self._req_id_counter = 0
|
||||
self._session_key = "aria-bridge" # Feste Session fuer die Bridge
|
||||
self._session_key = "main" # Fallback, wird per Diagnostic API aktualisiert
|
||||
self._diagnostic_url = self.config.get("DIAGNOSTIC_URL", DIAGNOSTIC_URL)
|
||||
# RVS-Verbindungsinfo aus Config oder Env
|
||||
rvs_host = self.config.get("RVS_HOST", RVS_HOST)
|
||||
rvs_port = self.config.get("RVS_PORT", RVS_PORT)
|
||||
|
|
@ -790,12 +793,28 @@ class ARIABridge:
|
|||
else:
|
||||
logger.info("[core] TTS unterdrueckt (Modus: %s)", self.current_mode.config.name)
|
||||
|
||||
def _fetch_active_session(self) -> None:
|
||||
"""Holt die aktive Session vom Diagnostic-Endpoint."""
|
||||
try:
|
||||
req = urllib.request.Request(f"{self._diagnostic_url}/api/session", method="GET")
|
||||
with urllib.request.urlopen(req, timeout=2) as resp:
|
||||
data = json.loads(resp.read().decode())
|
||||
new_key = data.get("sessionKey", "")
|
||||
if new_key and new_key != self._session_key:
|
||||
logger.info("[session] Aktive Session gewechselt: %s -> %s", self._session_key, new_key)
|
||||
self._session_key = new_key
|
||||
except Exception as e:
|
||||
logger.debug("[session] Diagnostic nicht erreichbar (%s) — nutze '%s'", e, self._session_key)
|
||||
|
||||
async def send_to_core(self, text: str, source: str = "bridge") -> None:
|
||||
"""Sendet Text an aria-core (OpenClaw chat.send Protokoll)."""
|
||||
if self.ws_core is None:
|
||||
logger.error("[core] Nicht verbunden — Nachricht verworfen: '%s'", text[:60])
|
||||
return
|
||||
|
||||
# Aktive Session vom Diagnostic holen
|
||||
self._fetch_active_session()
|
||||
|
||||
req_id = self._next_req_id()
|
||||
message = json.dumps({
|
||||
"type": "req",
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@ const state = {
|
|||
rvs: { status: "disconnected", lastError: null },
|
||||
proxy: { status: "unknown", lastError: null },
|
||||
};
|
||||
let activeSessionKey = "aria-diag-v3";
|
||||
const SESSION_KEY_FILE = "/tmp/aria-active-session";
|
||||
let activeSessionKey = (() => {
|
||||
try { return fs.readFileSync(SESSION_KEY_FILE, "utf-8").trim(); } catch { return "main"; }
|
||||
})();
|
||||
const logs = [];
|
||||
let gatewayWs = null;
|
||||
let rvsWs = null;
|
||||
|
|
@ -924,6 +927,9 @@ const server = http.createServer((req, res) => {
|
|||
} else if (req.url === "/api/state") {
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ state, logs: logs.slice(-100) }));
|
||||
} else if (req.url === "/api/session") {
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ sessionKey: activeSessionKey }));
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end("Not Found");
|
||||
|
|
@ -1375,8 +1381,10 @@ async function handleLoadChatHistory(clientWs) {
|
|||
if (!text) continue;
|
||||
|
||||
if (role === "user") {
|
||||
// Metadata-Prefix entfernen: "Sender (untrusted metadata):\n```json\n{...}\n```\n\n[timestamp] "
|
||||
text = text.replace(/^Sender \(untrusted metadata\):[\s\S]*?```\s*\n*(?:\[.*?\]\s*)?/m, "").trim();
|
||||
// Metadata-Prefix entfernen: "Sender (untrusted metadata):\n```json\n{...}\n```\n\n[timestamp] Text"
|
||||
text = text.replace(/^Sender \(untrusted metadata\):[\s\S]*?```[\s\S]*?```\s*\n*/m, "").trim();
|
||||
// Timestamp-Prefix entfernen: "[Sat 2026-03-28 14:51 UTC] "
|
||||
text = text.replace(/^\[.*?\]\s*/, "").trim();
|
||||
chatMessages.push({ type: "sent", text, meta: "Gateway direkt", ts: msg.timestamp || obj.timestamp || 0 });
|
||||
} else if (role === "assistant") {
|
||||
// Reply-Prefix entfernen: "[[reply_to_current]] "
|
||||
|
|
@ -1401,6 +1409,7 @@ function handleSetActiveSession(clientWs, sessionKey) {
|
|||
return;
|
||||
}
|
||||
activeSessionKey = sessionKey;
|
||||
try { fs.writeFileSync(SESSION_KEY_FILE, activeSessionKey); } catch {}
|
||||
log("info", "server", `Aktive Session: ${activeSessionKey}`);
|
||||
// Allen Clients mitteilen
|
||||
for (const c of browserClients) {
|
||||
|
|
@ -1417,6 +1426,7 @@ async function handleCreateSession(clientWs, sessionName) {
|
|||
try {
|
||||
// Session wird automatisch erstellt wenn man die erste Nachricht sendet
|
||||
activeSessionKey = sessionName;
|
||||
try { fs.writeFileSync(SESSION_KEY_FILE, activeSessionKey); } catch {}
|
||||
log("info", "server", `Neue Session erstellt und aktiviert: ${sessionName}`);
|
||||
// Allen Clients mitteilen
|
||||
for (const c of browserClients) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue