Compare commits
4
Commits
v0.1.3.7
...
0fcbf5e3ed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fcbf5e3ed | ||
|
|
3cf6308b79 | ||
|
|
7e5a4da659 | ||
|
|
d27fcaf342 |
@@ -357,6 +357,9 @@ Erreichbar unter `http://<VM-IP>:3001`. Teilt das Netzwerk mit der Bridge.
|
||||
- **Play-Button**: Jede ARIA-Nachricht kann nochmal vorgelesen werden (aus Cache wenn vorhanden, sonst neu rendern)
|
||||
- **Chat-Suche**: Lupe in der Statusleiste filtert Nachrichten live
|
||||
- **Mülltonne pro Bubble** (mit Confirm): gezielt eine Nachricht loeschen — geht nicht nur aus der UI weg, sondern auch aus `chat_backup.jsonl`, Brain-Conversation-Window und allen anderen Clients (RVS-Broadcast). Wichtig damit ARIA den Turn auch beim naechsten Prompt nicht mehr im Kontext hat
|
||||
- **🗂️ Notizen-Inbox + Memory-Editor**: Neben der Lupe oeffnet `🗂️` ein Vollbild-Modal mit allen Memory/Trigger/Skill-Spezial-Bubbles aus dem Chat plus dem vollen DB-Browser. Tap auf eine Memory oeffnet ein **Detail/Edit-Modal**: Felder editieren, Anhaenge hoch-/runterladen + loeschen, Memory komplett loeschen. Identischer Editor auch in Settings → 🧠 Gedaechtnis. Spezial-Bubbles werden aus dem Chat-Stream gefiltert (keine ewig-unten-haengenden Notiz-Bubbles mehr)
|
||||
- **Bubble-Header dynamic**: „ARIA hat etwas gemerkt" / „Notiz geaendert" (gelb) / „Notiz geloescht" (rot) — je nach action im memory_saved-Event
|
||||
- **App-Crash-Reporting**: ungefangene JS-Errors + React-Render-Fehler landen automatisch in `/shared/logs/app.log` via RVS — kein ADB noetig, Logs holen via `tools/fetch-app-logs.sh` oder Diagnostic GET `/api/app-log`. ErrorBoundary verhindert White-Screen, zeigt stattdessen Error-Box im Modal mit Stack-Trace + Schliessen-Button
|
||||
- **Mehrere Anhaenge**: Bilder + Dateien sammeln, Text hinzufuegen, dann zusammen senden
|
||||
- **Paste-Support**: Bilder aus Zwischenablage einfuegen (Diagnostic)
|
||||
- **Anhaenge**: Bridge speichert in Shared Volume, ARIA kann darauf zugreifen, Re-Download ueber RVS
|
||||
@@ -871,6 +874,8 @@ docker exec aria-brain curl localhost:8080/memory/stats
|
||||
- [x] **Proxy Tool-Use durchreichen**: claude-max-api-proxy patcht via eigene Adapter (`proxy-patches/`) den `tools`/`tool_calls`-Roundtrip — Claude Code rief vorher ihre internen Tools (Bash, sleep) statt der ARIA-Brain-Tools (trigger_timer, skill_*, ...). Jetzt funktioniert Tool-Use End-to-End.
|
||||
- [x] **Single Source of Truth — Qdrant**: `memory_save`-Tool fuer ARIA, Claude-Code-Auto-Memory abgeklemmt (tmpfs ueber `~/.claude/projects` im Proxy-Container), `brain-import/` zum reinen Drop-Folder degradiert, Cold-Memory mit Score-Threshold (0.30) gegen Embedder-Noise/Crosstalk, Diagnostic-Gehirn-UI mit Wortlich-/Semantisch-Suche, Advanced Search (AND/OR mit + Button), Memory-Druckansicht, Muelltonne pro Chat-Bubble. DB ist jetzt durchgaengig die einzige Wissensquelle, kein paralleles File-Memory mehr.
|
||||
- [x] **Memory-Anhaenge mit Vision-Pipeline**: Pro Memory koennen Bilder/PDFs/beliebige Dateien angehaengt werden (unter `/shared/memory-attachments/<id>/`, max 20 MB). Diagnostic-UI mit Thumbnail-Vorschau + Lightbox, App `memory_saved`-Bubble mit Tap-to-Load via RVS, System-Prompt zeigt Anhang-Pfade. **ARIA sieht Bilder echt** via Claude Code's eingebautes multi-modales `Read`-Tool — kein Proxy-Patch noetig. `memory_save` hat `attach_paths`-Parameter sodass ARIA ein User-Foto im selben Tool-Call lesen, Infos extrahieren (Kennzeichen, Marken, Texte) und als Memory + Anhang persistieren kann. Bilder bleiben am Memory haengen — bei spaeteren Detail-Fragen liest ARIA das Bild einfach nochmal.
|
||||
- [x] **Memory-Editor in der App** (5 Etappen): Notizen-Inbox-Button neben der Lupe oeffnet ein Modal mit allen Spezial-Bubbles aus dem aktuellen Chat plus dem vollen DB-Browser. Tap auf eine Memory → Detail-Modal mit Anhang-Vorschau, Stift-Icon wechselt in Edit-Mode (Felder editieren + Anhaenge hoch-/runterladen + loeschen). Identischer Editor unter Settings → 🧠 Gedaechtnis. Bubble-Header dynamic je nach Aktion (created/updated/deleted). RVS-Brain-Proxy als Fundament (`brain_request`/`brain_response`) damit die App beliebige Brain-HTTP-Endpoints adressieren kann. `memory_search` + `memory_update` als ARIA-Tools damit sie aktiv die DB pruefen und Eintraege patchen kann statt zu fragmentieren.
|
||||
- [x] **App-Crash-Reporting via RVS**: ErrorBoundary + global JS-Error-Handler + Promise-Rejection-Tracker schicken Crashes als `app_log`-Event durch RVS. Bridge sammelt in `/shared/logs/app.log`, Diagnostic GET `/api/app-log`. `tools/fetch-app-logs.sh` holt die Logs auf die Dev-Maschine (gitignored `.aria-debug/`). Damit kann Stefan unterwegs ohne ADB debuggen — der erste Bug (URLSearchParams in Hermes) wurde so in 5 Minuten gefunden.
|
||||
- [x] Sprachmodell-Setting wieder funktional (brainModel in runtime.json statt aria-core)
|
||||
- [x] App-Chat-Sync: kompletter Server-Sync bei Reconnect (Server = Source of Truth) + chat_cleared Live-Update. Lokal-only Bubbles (Skill-Notifications, laufende Voice ohne STT) bleiben erhalten.
|
||||
- [x] App: Chat-Suche mit Next/Prev Navigation statt Filter
|
||||
|
||||
@@ -79,8 +79,8 @@ android {
|
||||
applicationId "com.ariacockpit"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 10307
|
||||
versionName "0.1.3.7"
|
||||
versionCode 10309
|
||||
versionName "0.1.3.9"
|
||||
// Fallback fuer Libraries mit Product Flavors
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "aria-cockpit",
|
||||
"version": "0.1.3.7",
|
||||
"version": "0.1.3.9",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
|
||||
@@ -169,6 +169,12 @@ export const MemoryBrowser: React.FC<Props> = ({ restrictToIds, title, flatStyle
|
||||
data={filtered}
|
||||
keyExtractor={m => m.id}
|
||||
renderItem={renderItem}
|
||||
// nestedScrollEnabled: notwendig damit die FlatList auf Android
|
||||
// scrollt wenn sie in einer aeusseren ScrollView haengt (Settings-
|
||||
// Screen ist ScrollView). Ohne das frisst der aeussere ScrollView
|
||||
// alle Gesten und die innere Liste ist tot.
|
||||
nestedScrollEnabled={true}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
ListEmptyComponent={
|
||||
<Text style={{color:'#555570',textAlign:'center',padding:20,fontStyle:'italic'}}>
|
||||
{items.length === 0 ? '(keine Memories in der DB)' : '(keine Treffer für diese Filter)'}
|
||||
|
||||
@@ -1375,17 +1375,30 @@ const ChatScreen: React.FC = () => {
|
||||
<TouchableOpacity
|
||||
key={`${item.id}-att-${idx}`}
|
||||
style={styles.memoryAttachmentRow}
|
||||
onPress={() => {
|
||||
onPress={async () => {
|
||||
if (!a.path) return;
|
||||
if (a.localUri) {
|
||||
if (isImage) setFullscreenImage(a.localUri);
|
||||
else openFileWithIntent(a.localUri.replace(/^file:\/\//, ''), a.mime || '');
|
||||
} else {
|
||||
// Datei via Bridge nachladen — file_response hat den
|
||||
// memorySaved-Match-Path und cached + zeigt direkt
|
||||
autoOpenPaths.current.add(a.path);
|
||||
rvs.send('file_request' as any, { serverPath: a.path, requestId: `memAtt_${item.id}_${idx}` });
|
||||
const localPath = a.localUri.replace(/^file:\/\//, '');
|
||||
const exists = await RNFS.exists(localPath).catch(() => false);
|
||||
if (exists) {
|
||||
if (isImage) setFullscreenImage(a.localUri);
|
||||
else openFileWithIntent(localPath, a.mime || '');
|
||||
return;
|
||||
}
|
||||
// Cache weg → localUri leeren + neu laden
|
||||
setMessages(prev => prev.map(mm => mm.id === item.id && mm.memorySaved
|
||||
? { ...mm, memorySaved: { ...mm.memorySaved,
|
||||
attachments: mm.memorySaved.attachments?.map(x =>
|
||||
x.path === a.path ? { ...x, localUri: undefined } : x) } }
|
||||
: mm));
|
||||
if (Platform.OS === 'android') {
|
||||
ToastAndroid.show('Cache leer — lade nach...', ToastAndroid.SHORT);
|
||||
}
|
||||
}
|
||||
// Datei via Bridge nachladen — file_response hat den
|
||||
// memorySaved-Match-Path und cached + zeigt direkt
|
||||
autoOpenPaths.current.add(a.path);
|
||||
rvs.send('file_request' as any, { serverPath: a.path, requestId: `memAtt_${item.id}_${idx}` });
|
||||
}}
|
||||
>
|
||||
<Text style={styles.memoryAttachmentIcon}>{icon}</Text>
|
||||
@@ -1489,17 +1502,32 @@ const ChatScreen: React.FC = () => {
|
||||
) : (
|
||||
<TouchableOpacity
|
||||
style={styles.attachmentFile}
|
||||
onPress={() => {
|
||||
// Lokal vorhanden \u2192 direkt mit System-Intent oeffnen
|
||||
onPress={async () => {
|
||||
// Lokal vorhanden? Cache koennte geleert worden sein \u2014
|
||||
// Datei-Existenz pruefen bevor wir den Intent feuern.
|
||||
if (att.uri) {
|
||||
openFileWithIntent(att.uri.replace(/^file:\/\//, ''), att.mimeType || '');
|
||||
return;
|
||||
const localPath = att.uri.replace(/^file:\/\//, '');
|
||||
const exists = await RNFS.exists(localPath).catch(() => false);
|
||||
if (exists) {
|
||||
openFileWithIntent(localPath, att.mimeType || '');
|
||||
return;
|
||||
}
|
||||
// Cache weg \u2192 uri im State leeren damit UI "tippen zum Laden" zeigt
|
||||
setMessages(prev => prev.map(m => m.id === item.id
|
||||
? { ...m, attachments: m.attachments?.map(a =>
|
||||
a.serverPath === att.serverPath ? { ...a, uri: undefined } : a) }
|
||||
: m));
|
||||
if (Platform.OS === 'android') {
|
||||
ToastAndroid.show('Cache leer \u2014 lade nach...', ToastAndroid.SHORT);
|
||||
}
|
||||
}
|
||||
// Sonst: file_request \u2192 bei file_response wird die Datei
|
||||
// gespeichert UND geoeffnet (autoOpenPaths-Tracking).
|
||||
// Re-Download via file_request \u2192 bei file_response wird die
|
||||
// Datei gespeichert UND geoeffnet (autoOpenPaths-Tracking).
|
||||
if (att.serverPath) {
|
||||
autoOpenPaths.current.add(att.serverPath);
|
||||
rvs.send('file_request' as any, { serverPath: att.serverPath, requestId: item.id });
|
||||
} else if (Platform.OS === 'android') {
|
||||
ToastAndroid.show('Datei kann nicht nachgeladen werden (kein serverPath)', ToastAndroid.LONG);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -868,7 +868,7 @@ const SettingsScreen: React.FC = () => {
|
||||
})()}
|
||||
</View>
|
||||
</Modal>
|
||||
<ScrollView style={styles.container} contentContainerStyle={styles.content}>
|
||||
<ScrollView style={styles.container} contentContainerStyle={styles.content} nestedScrollEnabled={true}>
|
||||
|
||||
{currentSection === null && (
|
||||
<>
|
||||
|
||||
@@ -297,6 +297,17 @@ Skills mit Tool-Use.
|
||||
- [x] **Gehirn-Kategorien standardmaessig eingeklappt**: Beim ersten Aufruf alle Type-Sections collapsed, Stefan klappt gezielt auf was er sehen will. State persistiert in localStorage
|
||||
- [x] **Klappbare Type-Header + Category-AutoSuggest + Info-Modal**: Type-Header (▼/▶) klappbar, Category-Feld im Neu/Edit-Modal mit `<datalist>`-Vorschlaegen aller existierenden Categories, ℹ-Button-Modal erklaert welche Types FEST im System-Prompt vs. Cold Memory sind
|
||||
|
||||
### App-Memory-Editor + Crash-Reporting
|
||||
|
||||
- [x] **Bubble-Header dynamic** (created/updated/deleted): Die `🧠`-Bubble zeigt jetzt was passiert ist — "ARIA hat etwas gemerkt" / "Notiz geändert" / "Notiz gelöscht" (rot bei delete). Brain-Tools schicken `action`-Feld im memory_saved-Event mit
|
||||
- [x] **Tap auf Memory-Bubble → Detail-Modal**: Komponente `MemoryDetailModal` zeigt alle Felder (Titel, Type, Category, Tags, voller Content, Anhang-Vorschau mit Thumbnails). Stift-Icon wechselt in Edit-Mode mit Form-Feldern + 📌 Pinned-Toggle. **Anhänge hoch-/runterladen + löschen** im Modal (DocumentPicker, multipart-Upload via RVS-Brain-Proxy). Memory komplett löschen mit Confirm
|
||||
- [x] **Notizen-Inbox-Button (`🗂️`)** neben der Lupe in der Status-Leiste: Vollbild-Modal mit zwei Sections — „Aus diesem Chat" (kompakte Liste der Spezial-Bubbles aus dem aktuellen Verlauf, klickbar) + „Alle Memories aus der DB" mit dem `MemoryBrowser`. Spezial-Bubbles (memorySaved/triggerCreated/skillCreated) werden im Chat-Stream gefiltert (statt unten zu kleben)
|
||||
- [x] **Memory-Editor in App-Settings**: neue Sektion 🧠 „Gedächtnis" in den App-Einstellungen. Komplette CRUD-UI mit Wortlich-Suche, Type-Dropdown, Pinned/Cold-Filter, „+ Neu" anlegen. Selbe `MemoryBrowser`-Komponente wie in der Inbox
|
||||
- [x] **RVS-Brain-Proxy als Fundament**: Bridge implementiert generischen `brain_request` / `brain_response`-Channel — die App kann beliebige Brain-HTTP-Endpoints via RVS adressieren (GET/POST/PATCH/DELETE, JSON+Base64-Body, base64-encoded Binär-Antworten). `services/brainApi.ts` als Promise-basierter Client mit Request-ID-Routing, Timeout, automatischem Listener-Setup
|
||||
- [x] **App-Crash-Reporting via RVS**: ErrorBoundary-Komponente fängt React-Render-Fehler, `installGlobalCrashReporter` haengt sich an `ErrorUtils.setGlobalHandler` + `HermesInternal.enablePromiseRejectionTracker`. Crashes wandern als `app_log`-Event durch RVS, Bridge schreibt JSONL in `/shared/logs/app.log`. Diagnostic-Server liefert GET `/api/app-log[?limit=N]` + POST `/api/app-log/clear`. **`tools/fetch-app-logs.sh`** holt die Logs auf die Dev-Maschine (über `ARIA_DIAG_URL` aus `.claude/aria-vm.env`), speichert in `.aria-debug/` (gitignored), zeigt Stack-Trace kompakt auf stdout
|
||||
- [x] **`memory_search` + `memory_update` Tools**: ARIA kann die DB jetzt aktiv durchsuchen (Volltext/Semantic) und existierende Einträge per ID patchen statt fragmentierende neue anzulegen. Tool-Description sagt explizit „Memory ist Truth über Conversation-Window" — wenn der User korrigiert hat, gilt das was im Memory steht. Wichtig nach Diagnostic-Edits damit ARIA die neue Wahrheit sieht statt aus dem Window zu raten
|
||||
- [x] **App-Bugfixes**: (a) URLSearchParams crasht in Hermes — durch Mini-Query-Builder ersetzt (`brainApi._qs()`). (b) Cache leer + Datei-Tap → Auto-Re-Download via file_request statt Toast-Sackgasse, plus State-Cleanup (uri/localUri auf undefined). (c) Memory-Liste in Settings scrollt jetzt (nestedScrollEnabled auf FlatList + äußere ScrollView). (d) Modal-im-Modal auf Android gefixt — MemoryBrowser nimmt optionalen `onOpenMemory`-Callback, kein verschachteltes DetailModal mehr. (e) Alert.prompt (iOS-only) durch eigenes Text-Input-Modal ersetzt fuer „Neue Memory anlegen"
|
||||
|
||||
### Memory-Anhaenge mit Vision (Stufe A-E + attach_paths)
|
||||
|
||||
- [x] **Anhaenge an Memory-Eintraege** — Bilder/PDFs/beliebige Dateien koennen an jede Memory gehaengt werden, liegen physisch unter `/shared/memory-attachments/<memory-id>/`. Cleanup beim Memory-Delete automatisch. Limit 20 MB pro Datei
|
||||
|
||||
Reference in New Issue
Block a user