fix(kernel,server,tui,inference): generic resource gauge + F-002/F-003/F-004

- generic SystemResourceProbe: owner-agnostic /proc/meminfo system RAM
  overlaid on the vendor GPU probe, wired on both managed and static paths
  so the VRAM/GPU/RAM gauge renders with an external llama-server (was dormant)
- F-002: classify provider 4xx (e.g. llama.cpp 400) as terminal, not retryable
  (except 408/429); stops retrying deterministic request failures to exhaustion
- F-003: FileSystemPromptLoader expands leading ~ / ~/ to user home
- F-004: map InferenceFailedEvent + RetryAttemptedEvent to new
  ServerMessage.InferenceFailed / RetryAttempted, decoded+rendered in tui-go;
  ArtifactContentStoredEvent explicitly mapped to null (internal, no warn)
- tests: tilde expansion, SystemResourceProbe (static/managed/fail-soft)
This commit is contained in:
2026-06-10 11:07:08 +04:00
parent a92b5a3531
commit ee24b7786a
14 changed files with 254 additions and 24 deletions
@@ -8,12 +8,21 @@ class FileSystemPromptLoader(
private val configDir: Path = Path.of(System.getProperty("user.home"), ".config", "correx", "prompts"),
) : PromptLoader {
override fun load(path: String): String {
val local = Path.of(path)
val expanded = expandTilde(path)
val local = Path.of(expanded)
if (local.exists()) return local.readText()
val fromConfig = configDir.resolve(path)
val fromConfig = configDir.resolve(expanded)
if (fromConfig.exists()) return fromConfig.readText()
throw PromptNotFoundException("Prompt not found: $path (searched: $local, $fromConfig)")
}
// Expand a leading `~` / `~/...` to the user home so a config-supplied home path resolves
// instead of being concatenated literally onto [configDir] (F-003).
private fun expandTilde(path: String): String = when {
path == "~" -> System.getProperty("user.home")
path.startsWith("~/") -> System.getProperty("user.home") + path.substring(1)
else -> path
}
}
@@ -33,6 +33,19 @@ class FileSystemPromptLoaderTest {
assertContains(ex.message!!, configDir.toString())
}
@Test
fun `expands leading tilde to user home (F-003)`() {
val home = System.getProperty("user.home")
val rel = "correx-tilde-${System.nanoTime()}.md"
val file = java.nio.file.Path.of(home, rel).also { it.writeText("home prompt") }
try {
val loader = FileSystemPromptLoader(configDir = Files.createTempDirectory("unused"))
assertEquals("home prompt", loader.load("~/$rel"))
} finally {
Files.deleteIfExists(file)
}
}
@Test
fun `local path takes precedence over configDir`() {
val localFile = Files.createTempFile("prompt", ".md").also { it.writeText("local") }