Skip to content

Commit 20cfb15

Browse files
committed
Refactor: Modernize Memory Vault UI and enhance stability
This commit introduces a significant UI overhaul for the Memory Vault screens, focusing on a cleaner, more modern, and consistent design. It also enhances stability by improving vault initialization and adding a tool-calling bypass. ### UI Modernization The `VaultDataExplorer`, `VaultStatsOverview`, and `VaultManagement` screens have been completely redesigned with a cohesive and modern aesthetic: - **Consistent Components:** Replaced custom layouts with standardized `Surface`-based cards, chips, and components for a unified look. - **Improved Layout:** Adopted a more spacious and organized layout using consistent padding, arrangement, and typography (`ManropeFontFamily`). - **`VaultDashboard`:** Replaced the navigation drawer with a top-level `ActionToggleGroup` for quicker switching between Explorer, Manage, Logs, and Debug tabs. - **`VaultDataExplorer`:** - Redesigned data cards (`DataCard`) to be more compact and informative. - Simplified filter chips, now including item counts directly. - Removed the top search bar for a cleaner browsing experience. - Updated the detail sheet with a more organized and modern layout. - **`VaultStatsOverview` & `VaultManagement`:** - Refactored all stat cards (`StorageCard`, `QuickStats`, `ContentBreakdown`) to be more visually appealing and data-dense. - Redesigned the management tools ("Defragment", "Backup", etc.) into cleaner `ToolCard` components, with a dedicated "Danger Zone" for destructive actions. - Simplified chat list items for better readability. ### Features & Enhancements - **Tool-Calling Bypass:** - Added a new "Bypass Model Check" option in Settings. - When enabled, this allows any loaded model to attempt tool-calling, which is useful for models not explicitly marked as supporting it. A warning card accompanies this setting. - **LaTeX Rendering Improvements:** - Significantly expanded LaTeX support in Markdown rendering to parse and display tables from `tabular`, `table`, and `array` environments. - Added extensive support for over 500 AMS-LaTeX symbols, negated relations, and various font commands (`\mathfrak`, `\mathscr`, `\mathsf`, `\mathtt`). - Improved parsing of multi-line math blocks and various LaTeX commands (`\overbrace`, `\cancel`, `\boxed`, etc.). ### Stability and Bug Fixes - **Robust Vault Initialization:** - Refactored `VaultHelper` and `ChatManager` to ensure the vault is properly initialized before any operations are performed. - Introduced `VaultHelper.awaitReady()` to prevent race conditions and crashes if the UI tries to access the vault before it's ready. - **Navigation Fix:** Correctly passed the `onNavigateBack` handler to `VaultDashboard` to ensure proper back navigation.
1 parent 9a617b1 commit 20cfb15

File tree

16 files changed

+1933
-1582
lines changed

16 files changed

+1933
-1582
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ android {
2222
applicationId = "com.dark.tool_neuron"
2323
minSdk = 31
2424
targetSdk = 36
25-
versionCode = 23
26-
versionName = "1.2.1"
25+
versionCode = 24
26+
versionName = "1.2.2"
2727
ndk {
2828
abiFilters += listOf("arm64-v8a", "x86_64")
2929
}

app/src/main/java/com/dark/tool_neuron/activity/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ fun AppNavigation(
240240
}
241241

242242
composable(Screen.VaultManager.route) {
243-
VaultDashboard()
243+
VaultDashboard(onNavigateBack = { navController.popBackStack() })
244244
}
245245
}
246246
}

app/src/main/java/com/dark/tool_neuron/data/AppSettingsDataStore.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class AppSettingsDataStore(private val context: Context) {
1717
private val STREAMING_ENABLED = booleanPreferencesKey("streaming_enabled")
1818
private val CHAT_MEMORY_ENABLED = booleanPreferencesKey("chat_memory_enabled")
1919
private val TOOL_CALLING_ENABLED = booleanPreferencesKey("tool_calling_enabled")
20+
private val TOOL_CALLING_BYPASS_ENABLED = booleanPreferencesKey("tool_calling_bypass_enabled")
2021
private val IMAGE_BLUR_ENABLED = booleanPreferencesKey("image_blur_enabled")
2122
private val LOAD_TTS_ON_START = booleanPreferencesKey("load_tts_on_start")
2223
}
@@ -33,6 +34,10 @@ class AppSettingsDataStore(private val context: Context) {
3334
prefs[TOOL_CALLING_ENABLED] ?: true
3435
}
3536

37+
val toolCallingBypassEnabled: Flow<Boolean> = context.appSettingsDataStore.data.map { prefs ->
38+
prefs[TOOL_CALLING_BYPASS_ENABLED] ?: false
39+
}
40+
3641
val imageBlurEnabled: Flow<Boolean> = context.appSettingsDataStore.data.map { prefs ->
3742
prefs[IMAGE_BLUR_ENABLED] ?: true
3843
}
@@ -54,6 +59,10 @@ class AppSettingsDataStore(private val context: Context) {
5459
context.appSettingsDataStore.edit { it[TOOL_CALLING_ENABLED] = enabled }
5560
}
5661

62+
suspend fun updateToolCallingBypassEnabled(enabled: Boolean) {
63+
context.appSettingsDataStore.edit { it[TOOL_CALLING_BYPASS_ENABLED] = enabled }
64+
}
65+
5766
suspend fun updateImageBlurEnabled(enabled: Boolean) {
5867
context.appSettingsDataStore.edit { it[IMAGE_BLUR_ENABLED] = enabled }
5968
}

app/src/main/java/com/dark/tool_neuron/di/AppContainer.kt

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ object AppContainer {
2828
private val appScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
2929
private val chatManager = ChatManager()
3030
private var generationManager = GenerationManager()
31-
private var vaultInitialized = false
31+
32+
// Keep track of context for re-initialization if needed
33+
private lateinit var appContext: Context
3234

3335
fun init(context: Context, application: Application) {
36+
appContext = context.applicationContext
3437
database = AppDatabase.getDatabase(context)
3538

3639
modelRepository = ModelRepository(
@@ -50,22 +53,35 @@ object AppContainer {
5053
appScope.launch {
5154
try {
5255
VaultHelper.initialize(context)
53-
vaultInitialized = true
5456
} catch (e: Exception) {
5557
e.printStackTrace()
58+
// Retry once after a short delay
59+
kotlinx.coroutines.delay(500)
60+
try {
61+
VaultHelper.initialize(context)
62+
} catch (retryException: Exception) {
63+
retryException.printStackTrace()
64+
}
5665
}
5766
}
5867
}
5968

69+
/**
70+
* Re-initialize vault if needed (e.g., after configuration change or process death)
71+
* This can be called from Activities/Fragments to ensure vault is ready
72+
*/
73+
fun ensureVaultInitialized() {
74+
if (!VaultHelper.isInitialized() && ::appContext.isInitialized) {
75+
initVault(appContext)
76+
}
77+
}
78+
6079
fun shutdown() {
61-
if (vaultInitialized) {
62-
appScope.launch {
63-
try {
64-
VaultHelper.close()
65-
vaultInitialized = false
66-
} catch (e: Exception) {
67-
e.printStackTrace()
68-
}
80+
appScope.launch {
81+
try {
82+
VaultHelper.close()
83+
} catch (e: Exception) {
84+
e.printStackTrace()
6985
}
7086
}
7187
}
@@ -83,5 +99,10 @@ object AppContainer {
8399
fun getChatViewModelFactory(): ChatViewModelFactory = chatViewModelFactory
84100

85101

86-
fun isVaultReady(): Boolean = vaultInitialized
102+
fun isVaultReady(): Boolean = VaultHelper.isInitialized()
103+
104+
/**
105+
* Exposes the vault readiness StateFlow for UI observation
106+
*/
107+
val vaultReadyState = VaultHelper.isReady
87108
}

app/src/main/java/com/dark/tool_neuron/plugins/PluginManager.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,32 @@ object PluginManager {
8181
private val _isToolCallingModelLoaded = MutableStateFlow(false)
8282
val isToolCallingModelLoaded: StateFlow<Boolean> = _isToolCallingModelLoaded.asStateFlow()
8383

84+
// Bypass model check for tool calling
85+
private val _toolCallingBypassEnabled = MutableStateFlow(false)
86+
val toolCallingBypassEnabled: StateFlow<Boolean> = _toolCallingBypassEnabled.asStateFlow()
87+
88+
/**
89+
* Set whether to bypass the tool calling model check.
90+
* When enabled, tool calling is available for any loaded model.
91+
*/
92+
fun setToolCallingBypassEnabled(enabled: Boolean) {
93+
_toolCallingBypassEnabled.value = enabled
94+
Log.d(TAG, "Tool calling bypass: ${if (enabled) "enabled" else "disabled"}")
95+
}
96+
8497
/**
8598
* Update whether the loaded model supports tool calling.
8699
* Should be called when a model is loaded or unloaded.
87100
*/
88101
fun setToolCallingModelLoaded(modelName: String?) {
89-
_isToolCallingModelLoaded.value = modelName != null && (
102+
val modelSupportsToolCalling = modelName != null && (
90103
TOOL_CALLING_MODEL_IDS.any { modelName.contains(it, ignoreCase = true) } ||
91104
modelName.contains("Code", ignoreCase = true) ||
92105
modelName.contains("tool", ignoreCase = true) ||
93106
modelName.contains("qwen", ignoreCase = true)
94107
)
108+
// If bypass is enabled, always report as loaded when any model is present
109+
_isToolCallingModelLoaded.value = modelSupportsToolCalling || (_toolCallingBypassEnabled.value && modelName != null)
95110
}
96111

97112
/**

0 commit comments

Comments
 (0)