Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c1dac86d5 | |||
| 8fb95b884f |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
+1
-1
File diff suppressed because one or more lines are too long
Binary file not shown.
BIN
Binary file not shown.
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
#Sun Mar 29 11:40:22 CEST 2026
|
#Sun Mar 29 12:08:20 CEST 2026
|
||||||
base.2=/home/duffy/Dokumente/programmierung/ARIA-AGENT/android/android/app/build/intermediates/dex/release/mergeDexRelease/classes2.dex
|
base.2=/home/duffy/Dokumente/programmierung/ARIA-AGENT/android/android/app/build/intermediates/dex/release/mergeDexRelease/classes2.dex
|
||||||
path.2=classes2.dex
|
path.2=classes2.dex
|
||||||
base.1=/home/duffy/Dokumente/programmierung/ARIA-AGENT/android/android/app/build/intermediates/global_synthetics_dex/release/classes.dex
|
base.1=/home/duffy/Dokumente/programmierung/ARIA-AGENT/android/android/app/build/intermediates/global_synthetics_dex/release/classes.dex
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -17,6 +17,7 @@ import {
|
|||||||
import DocumentPicker, {
|
import DocumentPicker, {
|
||||||
DocumentPickerResponse,
|
DocumentPickerResponse,
|
||||||
} from 'react-native-document-picker';
|
} from 'react-native-document-picker';
|
||||||
|
import RNFS from 'react-native-fs';
|
||||||
|
|
||||||
// --- Typen ---
|
// --- Typen ---
|
||||||
|
|
||||||
@@ -74,15 +75,17 @@ const FileUpload: React.FC<FileUploadProps> = ({ onFileSelected, onCancel }) =>
|
|||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// In Produktion: Datei lesen und zu Base64 konvertieren
|
// Datei lesen und zu Base64 konvertieren
|
||||||
// const base64 = await RNFS.readFile(selectedFile.fileCopyUri || selectedFile.uri, 'base64');
|
const filePath = selectedFile.fileCopyUri || selectedFile.uri;
|
||||||
const base64Placeholder = '';
|
// URI-Schema entfernen fuer RNFS (file:// → absoluter Pfad)
|
||||||
|
const cleanPath = filePath.replace('file://', '');
|
||||||
|
const base64 = await RNFS.readFile(cleanPath, 'base64');
|
||||||
|
|
||||||
const fileData: FileData = {
|
const fileData: FileData = {
|
||||||
name: selectedFile.name || 'unbenannt',
|
name: selectedFile.name || 'unbenannt',
|
||||||
type: selectedFile.type || 'application/octet-stream',
|
type: selectedFile.type || 'application/octet-stream',
|
||||||
size: selectedFile.size || 0,
|
size: selectedFile.size || 0,
|
||||||
base64: base64Placeholder,
|
base64,
|
||||||
uri: selectedFile.uri,
|
uri: selectedFile.uri,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -87,12 +87,33 @@ const ChatScreen: React.FC = () => {
|
|||||||
console.error('[Chat] Fehler beim Laden des Verlaufs:', err);
|
console.error('[Chat] Fehler beim Laden des Verlaufs:', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loadMessages();
|
loadMessages().then(() => {
|
||||||
|
// Auto-Scroll nach Laden des Verlaufs
|
||||||
|
setTimeout(() => flatListRef.current?.scrollToEnd({ animated: false }), 200);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// RVS-Nachrichten abonnieren
|
// RVS-Nachrichten abonnieren
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubMessage = rvs.onMessage((message: RVSMessage) => {
|
const unsubMessage = rvs.onMessage((message: RVSMessage) => {
|
||||||
|
// STT-Ergebnis: Spracheingabe-Placeholder mit transkribiertem Text ersetzen
|
||||||
|
if (message.type === 'stt_result') {
|
||||||
|
const sttText = (message.payload.text as string) || '';
|
||||||
|
if (sttText) {
|
||||||
|
setMessages(prev => prev.map(m =>
|
||||||
|
m.sender === 'user' && m.text.includes('Spracheingabe wird verarbeitet')
|
||||||
|
? { ...m, text: sttText }
|
||||||
|
: m
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// Keine Sprache erkannt — Placeholder entfernen
|
||||||
|
setMessages(prev => prev.filter(m =>
|
||||||
|
!(m.sender === 'user' && m.text.includes('Spracheingabe wird verarbeitet'))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (message.type === 'chat') {
|
if (message.type === 'chat') {
|
||||||
// Nur Nachrichten von ARIA anzeigen — eigene Nachrichten werden lokal hinzugefuegt
|
// Nur Nachrichten von ARIA anzeigen — eigene Nachrichten werden lokal hinzugefuegt
|
||||||
const sender = (message.payload.sender as string) || '';
|
const sender = (message.payload.sender as string) || '';
|
||||||
@@ -159,7 +180,7 @@ const ChatScreen: React.FC = () => {
|
|||||||
const userMsg: ChatMessage = {
|
const userMsg: ChatMessage = {
|
||||||
id: nextId(),
|
id: nextId(),
|
||||||
sender: 'user',
|
sender: 'user',
|
||||||
text: '[Sprachnachricht]',
|
text: '🎙 Spracheingabe wird verarbeitet...',
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
attachments: [{ type: 'audio', name: 'Sprachaufnahme' }],
|
attachments: [{ type: 'audio', name: 'Sprachaufnahme' }],
|
||||||
};
|
};
|
||||||
@@ -204,9 +225,14 @@ const ChatScreen: React.FC = () => {
|
|||||||
// Auto-Scroll bei neuen Nachrichten
|
// Auto-Scroll bei neuen Nachrichten
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messages.length > 0) {
|
if (messages.length > 0) {
|
||||||
|
// Laengerer Delay damit FlatList fertig gerendert hat
|
||||||
|
setTimeout(() => {
|
||||||
|
flatListRef.current?.scrollToEnd({ animated: false });
|
||||||
|
}, 300);
|
||||||
|
// Nochmal animiert fuer den Fall dass sich die Hoehe geaendert hat
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
flatListRef.current?.scrollToEnd({ animated: true });
|
flatListRef.current?.scrollToEnd({ animated: true });
|
||||||
}, 100);
|
}, 600);
|
||||||
}
|
}
|
||||||
}, [messages]);
|
}, [messages]);
|
||||||
|
|
||||||
@@ -262,9 +288,8 @@ const ChatScreen: React.FC = () => {
|
|||||||
const userMsg: ChatMessage = {
|
const userMsg: ChatMessage = {
|
||||||
id: nextId(),
|
id: nextId(),
|
||||||
sender: 'user',
|
sender: 'user',
|
||||||
text: '[Sprachnachricht]',
|
text: '🎙 Spracheingabe wird verarbeitet...',
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
attachments: [{ type: 'audio', name: 'Sprachaufnahme' }],
|
|
||||||
};
|
};
|
||||||
setMessages(prev => [...prev, userMsg]);
|
setMessages(prev => [...prev, userMsg]);
|
||||||
|
|
||||||
|
|||||||
+52
-4
@@ -954,10 +954,40 @@ class ARIABridge:
|
|||||||
await self.ws_core.send(raw_message)
|
await self.ws_core.send(raw_message)
|
||||||
|
|
||||||
elif msg_type == "file":
|
elif msg_type == "file":
|
||||||
# Datei von der App → an aria-core
|
# Datei von der App → als Text-Nachricht an aria-core
|
||||||
logger.info("[rvs] Datei empfangen: %s", payload.get("name", "?"))
|
file_name = payload.get("name", "unbekannt")
|
||||||
if self.ws_core:
|
file_type = payload.get("type", "")
|
||||||
await self.ws_core.send(raw_message)
|
file_b64 = payload.get("base64", "")
|
||||||
|
file_size = payload.get("size", 0)
|
||||||
|
width = payload.get("width", 0)
|
||||||
|
height = payload.get("height", 0)
|
||||||
|
logger.info("[rvs] Datei empfangen: %s (%s, %dKB)",
|
||||||
|
file_name, file_type, len(file_b64) // 1365 if file_b64 else 0)
|
||||||
|
|
||||||
|
if file_b64 and file_type.startswith("image/"):
|
||||||
|
# Bild: als temporaere Datei speichern und Pfad an ARIA melden
|
||||||
|
ext = ".jpg" if "jpeg" in file_type or "jpg" in file_type else ".png"
|
||||||
|
tmp = tempfile.NamedTemporaryFile(suffix=ext, dir="/tmp", delete=False, prefix="aria_img_")
|
||||||
|
tmp.write(base64.b64decode(file_b64))
|
||||||
|
tmp.close()
|
||||||
|
text = (f"[Bild von Stefan via App: {file_name}"
|
||||||
|
f"{f', {width}x{height}px' if width else ''}"
|
||||||
|
f" — gespeichert als {tmp.name}]"
|
||||||
|
f" Bitte analysiere das Bild.")
|
||||||
|
await self.send_to_core(text, source="app-file")
|
||||||
|
elif file_b64:
|
||||||
|
# Andere Datei: speichern und Pfad melden
|
||||||
|
ext = Path(file_name).suffix or ".bin"
|
||||||
|
tmp = tempfile.NamedTemporaryFile(suffix=ext, dir="/tmp", delete=False, prefix="aria_file_")
|
||||||
|
tmp.write(base64.b64decode(file_b64))
|
||||||
|
tmp.close()
|
||||||
|
text = (f"[Datei von Stefan via App: {file_name}"
|
||||||
|
f" ({file_type}, {file_size} bytes)"
|
||||||
|
f" — gespeichert als {tmp.name}]")
|
||||||
|
await self.send_to_core(text, source="app-file")
|
||||||
|
else:
|
||||||
|
text = f"[Stefan hat eine Datei gesendet: {file_name} ({file_type}) — aber keine Daten empfangen]"
|
||||||
|
await self.send_to_core(text, source="app-file")
|
||||||
|
|
||||||
elif msg_type == "audio":
|
elif msg_type == "audio":
|
||||||
# Audio von der App → decodieren → STT → an aria-core
|
# Audio von der App → decodieren → STT → an aria-core
|
||||||
@@ -1017,9 +1047,27 @@ class ARIABridge:
|
|||||||
|
|
||||||
if text.strip():
|
if text.strip():
|
||||||
logger.info("[rvs] STT Ergebnis: '%s'", text[:80])
|
logger.info("[rvs] STT Ergebnis: '%s'", text[:80])
|
||||||
|
# STT-Ergebnis zurueck an die App senden (zur Anzeige, nicht nochmal verarbeiten)
|
||||||
|
await self._send_to_rvs({
|
||||||
|
"type": "stt_result",
|
||||||
|
"payload": {
|
||||||
|
"text": text,
|
||||||
|
"sender": "user",
|
||||||
|
},
|
||||||
|
"timestamp": int(asyncio.get_event_loop().time() * 1000),
|
||||||
|
})
|
||||||
await self.send_to_core(text, source="app-voice")
|
await self.send_to_core(text, source="app-voice")
|
||||||
else:
|
else:
|
||||||
logger.info("[rvs] Keine Sprache erkannt — ignoriert")
|
logger.info("[rvs] Keine Sprache erkannt — ignoriert")
|
||||||
|
await self._send_to_rvs({
|
||||||
|
"type": "stt_result",
|
||||||
|
"payload": {
|
||||||
|
"text": "",
|
||||||
|
"error": "Keine Sprache erkannt",
|
||||||
|
"sender": "user",
|
||||||
|
},
|
||||||
|
"timestamp": int(asyncio.get_event_loop().time() * 1000),
|
||||||
|
})
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("[rvs] Audio-Verarbeitung fehlgeschlagen")
|
logger.exception("[rvs] Audio-Verarbeitung fehlgeschlagen")
|
||||||
|
|||||||
@@ -501,7 +501,9 @@
|
|||||||
}
|
}
|
||||||
if (msg.type === 'rvs_chat') {
|
if (msg.type === 'rvs_chat') {
|
||||||
const p = msg.msg.payload || {};
|
const p = msg.msg.payload || {};
|
||||||
addChat('received', p.text || '?', `via RVS (${p.sender || '?'})`);
|
const sender = p.sender || '?';
|
||||||
|
const chatType = (sender === 'aria') ? 'received' : 'sent';
|
||||||
|
addChat(chatType, p.text || '?', `via RVS (${sender})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.type === 'proxy_result') {
|
if (msg.type === 'proxy_result') {
|
||||||
|
|||||||
@@ -338,6 +338,14 @@ function handleGatewayMessage(msg) {
|
|||||||
log("info", "gateway", `ANTWORT: "${text.slice(0, 200)}"`);
|
log("info", "gateway", `ANTWORT: "${text.slice(0, 200)}"`);
|
||||||
if (pipelineActive) pipelineEnd(true, `"${text.slice(0, 120)}"`);
|
if (pipelineActive) pipelineEnd(true, `"${text.slice(0, 120)}"`);
|
||||||
broadcast({ type: "chat_final", text, payload });
|
broadcast({ type: "chat_final", text, payload });
|
||||||
|
// Antwort auch an RVS weiterleiten → App bekommt ARIAs Antworten
|
||||||
|
if (rvsWs && rvsWs.readyState === WebSocket.OPEN && text) {
|
||||||
|
rvsWs.send(JSON.stringify({
|
||||||
|
type: "chat",
|
||||||
|
payload: { text, sender: "aria" },
|
||||||
|
timestamp: Date.now(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user