onProgressEvent freed .chunk text that handleLine also frees via defer —
double free corrupted the heap mid-turn; DebugAllocator caught it and
the reply tail was silently lost (delivered messages missing their final
characters while the CLI transcript held the full text).
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
The stream reader only handled lines terminated by newline. The letta
CLI final JSON line arrives without trailing newline at EOF, so the last
assistant message (or result line) sat in the line buffer and was
silently dropped — replies ended mid-sentence. Also: read errors no
longer silently end collection (logged), and stream completeness is
tracked via the result line with a warning when absent.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- 'matrix_harness send "text"' — one-shot unprompted messaging to the
pinned room (agent announcements/alerts)
- backlog no longer re-forwards read messages: last homeserver
origin_server_ts persisted to /tmp/matrix-harness.state, advanced on
every processed event; events at/below it are skipped
- 30-min staleness window retained as outer bound
- sync(): std.json walk of rooms.join.*.timeline (old string-window scraper
misattributed senders across events); Event gains ts
- startup backlog: peer messages from last 30min forwarded to agent as
context (reply suppressed); failures logged, never fatal (systemd
Restart=on-failure would otherwise re-forward every 3s)
- messages to agent prefixed [matrix HH:MMZ] with UTC event timestamp
- sendText: jsonEscape covers control chars (\u00XX), markdown -> HTML
formatted_body (bold/italic/code/fences) for Element rendering
- no startup banner in room; harness now runs as systemd user service
matrix-harness (unit + .matrix-env, untracked)
Reuses the fixed room when MATRIX_ROOM is set; only creates a fresh DM
when unset. All replies go to the pinned room.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- src/matrix.zig: minimal Matrix client (conduwuit @ matrix.chaosmith.systems)
via curl subprocess transport (native TLS swap later): login, createRoom
(trusted_private_chat, unencrypted — no olm), sendText, sync polling with
window-scan event extraction reusing letta.jsonStr
- src/matrix_harness.zig: standalone entrypoint (independent of tray daemon):
login -> DM with peer -> sync loop -> peer messages routed through letta
CLI (chaos-prime) -> replies sent back to the room
- build.zig: second exe matrix_harness; use_llvm fix promoted into build.zig
for both executables (native lld vs GCC16 .sframe relocations)
- calling/Element Call (livekit SFU already deployed on ass-host) layers on
top of this harness next
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Qt rich text collapses raw newlines to whitespace; convert before render.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- tray submenus: Agent (from letta agents list, radio-style) and
Conversation (from local backend storage, CLI has no listing surface)
- conversation entries show preview: summary or last-message text
- conversation menu refreshes on aboutToShow (KDE DBus menu syncs a
step behind eager mutation)
- CLI rule honored: --agent only with --conversation default; named
conversations imply the agent
- plain-text fallback parsing for non-stream-json output
- empty-reply debug: raw stream tail dump
- prefs: ~/.local/inferon/prefs.json, saved on pick, loaded at startup,
HOME-resolved paths (std.c.getenv), owned buffers (no alias double-free)
- leak fixes: agent name fallback, quit-path drains for menu entries
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- playback.zig: sentence queue + playback thread — agent reply chunks are
split on sentence boundaries and each sentence is synthesized+played as it
completes, so voice starts after the first sentence, not after the reply
- melo_server.py v2: WAV written to /dev/shm, raw s16le PCM + sample rate
streamed over stdout (WAV n rate header + bytes), file deleted immediately;
melo stdout chatter rerouted to stderr to keep the protocol clean
- melo.zig: speakRaw returns in-memory PCM; pw-play fed via stdin pipe
(no on-disk TTS files at all)
- whisper: --language auto
- fix: double-close of pw-play stdin panicked Threaded Io in debug
- fix: quit-path frees for transcript cache, bubble lists, sentence queue,
reply buffer (debug allocator leak panic)
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- processUtterance runs on a detached std.Thread; Qt event loop stays
responsive during whisper/letta/melo (icon repaints, menu works)
- setState marshals to main thread via threading.async with thread-id check
- rapid double-click race guarded: state claimed before spawn
- icon: QPainter-drawn antialiased circle (dark rim, transparent bg) —
bare pixmap.fill rendered blank on the KDE SNI host
- new qt libs: qbrush, qpainter, qrect, qt6zigthreading
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- melo_server.py subprocess (MeloTTS v3 EN-Newest, speed 1.3): line protocol
stdin->stdout, model loaded once, warmup before READY
- src/melo.zig: lifecycle ownership (spawn/kill with inferon), line protocol
client, reply sanitizer (newlines/markdown stripped before synthesis)
- SIGINT/SIGTERM handlers: async-signal-safe kill of whisper/melo/recorder,
default disposition restored + re-raise for truthful exit status
- processUtterance: transcribe->infer->speak chains automatically after
stop-click; mid-pipeline clicks are no-ops; back to idle after reply
- temp cleanup: recording WAV deleted after transcription, TTS WAV after
playback
- whisper: pid() export for signal handler
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>