Compare commits

...
Author SHA1 Message Date
Bailey Dixon f2b92b2755 Merge pull request #274 from Codename-11/fix/android-1.5.3-voice-transcript-keys
release(android): Android 1.5.3 duplicate-key hotfix
2026-07-31 19:03:40 -04:00
Bailey Dixon 8651656899 release(android): android-v1.5.3 2026-07-31 18:50:21 -04:00
Bailey Dixon b458d83fcc fix(android): stabilize voice transcript keys 2026-07-31 18:27:59 -04:00
Bailey Dixon aa26f7c9b6 Merge pull request #265 from Codename-11/dev
release(android): android-v1.5.2
2026-07-28 17:58:37 -04:00
Bailey Dixon 325b8e5670 Merge pull request #257 from Codename-11/dev
release(android): promote android-v1.5.1
2026-07-26 16:11:49 -04:00
Bailey Dixon e9da59cf40 Merge pull request #254 from Codename-11/dev
fix(android): repair immutable release dispatch
2026-07-25 18:30:53 -04:00
Bailey Dixon c9a03c9ed7 Merge pull request #252 from Codename-11/dev
release(android): android-v1.5.0
2026-07-25 18:26:34 -04:00
Bailey Dixon 68f8b58a0b Merge pull request #232 from Codename-11/dev
release(android): android-v1.4.9
2026-07-19 21:27:28 -04:00
11 changed files with 80 additions and 25 deletions
+6
View File
@@ -10,6 +10,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
- **Windows-trusted certificates work in the desktop CLI.** The packaged Windows binary and newer Node runtimes add the Windows certificate store without dropping bundled or operator-supplied roots, while TLS verification and Relay certificate pinning remain enforced.
## [Android 1.5.3] - 2026-07-31
### Fixed
- **Voice transcripts retain stable rows after chat-history reconciliation.** Focus mode uses the same stable Compose identity as the main conversation, preventing duplicate-key crashes when live rows adopt persisted server IDs.
## [Android 1.5.2] - 2026-07-28
### Fixed
+11
View File
@@ -1,5 +1,16 @@
# Hermes-Relay — Dev Log
## 2026-07-30 — Voice transcript identity alignment
Android voice Focus mode now keys transcript rows with the same stable UI
identity as the main Chat list. A live row may adopt its persisted server
message ID during history reconciliation while retaining its original Compose
identity; using the mutable domain ID in the voice overlay could otherwise
collide during that transition and close the app.
Focused JVM coverage recreates two visible rows with a shared reconciled server
ID and verifies distinct stable transcript keys.
## 2026-07-27 — Android replayed-message identity reconciliation
Android history reconciliation now collapses reconnect/rejoin replays of the
+6 -10
View File
@@ -1,10 +1,10 @@
# Hermes-Relay-Android v1.5.2
# Hermes-Relay-Android v1.5.3
**Release Date:** July 28, 2026
**Release Date:** July 31, 2026
## Download
> Installing on your phone? Download `hermes-relay-1.5.2-sideload-release.apk` and tap it for the full feature set, or install the conservative build from [Google Play](https://play.google.com/store/apps/details?id=com.axiomlabs.hermesrelay).
> Installing on your phone? Download `hermes-relay-1.5.3-sideload-release.apk` and tap it for the full feature set, or install the conservative build from [Google Play](https://play.google.com/store/apps/details?id=com.axiomlabs.hermesrelay).
The `.aab` file is a Play Console upload bundle and cannot be installed by tapping it on a phone.
@@ -12,17 +12,13 @@ Verify the download against `SHA256SUMS.txt`. See the [sideload guide](https://h
## Summary
This patch restores reliable dashboard sign-in for self-hosted OIDC and Nous Portal connections, including private-LAN and Tailscale routes, and prevents replayed chat events from destabilizing the conversation list.
This patch prevents Voice Focus from closing when live chat rows receive their persisted server identities during history reconciliation.
## Fixed
- Self-hosted OIDC returns through the dashboard cookie flow instead of a desktop-only loopback callback.
- Nous Portal authentication opens in the system browser so provider security challenges can complete.
- Native PKCE uses standards-compatible unpadded Base64URL and preserves the dashboard's canonical HTTPS callback origin while keeping tokens scoped to the active route.
- Full-screen in-app sign-in remains available for compatible dashboard providers.
- Replayed upstream chat events are coalesced before rendering, preventing duplicate message keys.
- Voice Focus now uses the same stable row identity as the main conversation, preventing duplicate-key crashes while live messages reconcile with persisted history.
## Install / Verify
- App version: **1.5.2** (versionCode **35**).
- App version: **1.5.3** (versionCode **36**).
- Standard Chat and Vanilla Hermes voice continue to work against unmodified upstream Hermes.
@@ -1 +1 @@
Dashboard sign-in now completes reliably for self-hosted OIDC and Nous Portal, including private-LAN and Tailscale routes. Nous opens securely in the system browser, while compatible providers retain full-screen in-app sign-in. Replayed chat updates no longer duplicate conversation rows.
Voice Focus now keeps transcript rows stable while live messages reconcile with persisted chat history, preventing the duplicate-key crash that could close the app.
@@ -1 +1 @@
Hermes 仪表板登录现在可为自托管 OIDC 和 Nous Portal 可靠完成认证,并支持私有局域网与 Tailscale 路由。Nous 会在系统浏览器中安全打开,兼容的提供商仍可使用应用内全屏登录。重放的聊天更新不再产生重复会话行。
语音专注模式现在会在实时消息与已保存的聊天记录同步时保持稳定的列表标识,避免重复键导致应用关闭。
+13
View File
@@ -1,5 +1,18 @@
{
"versions": [
{
"version": "1.5.3",
"title": "Voice stays open",
"date": "2026-07-31",
"sections": [
{
"header": "Stable voice transcripts",
"bullets": [
"Voice Focus keeps stable transcript rows while live messages reconcile with persisted chat history, preventing duplicate-key crashes that could close the app."
]
}
]
},
{
"version": "1.5.2",
"title": "Sign in without detours",
+3 -5
View File
@@ -1,6 +1,4 @@
v1.5.2 - Sign in without detours
v1.5.3 - Voice stays open
* Complete self-hosted OIDC sign-in through the dashboard callback.
* Open Nous Portal securely in the system browser.
* Sign in over private-LAN and Tailscale dashboard routes.
* Keep replayed chat updates from duplicating conversation rows.
* Prevent Voice Focus from closing while live messages reconcile with chat history.
* Keep transcript rows stable when they receive persisted server identities.
@@ -402,7 +402,12 @@ fun VoiceModeOverlay(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(10.dp),
) {
items(visibleTranscriptMessages, key = { it.id }) { msg ->
// Match ChatScreen's identity contract. A history
// reconcile can adopt the same authoritative server
// id into a live row while Compose still holds the
// pre-reconcile row for a frame. uiKey remains stable
// and unique across that transition.
items(visibleTranscriptMessages, key = ::voiceTranscriptItemKey) { msg ->
CompactTranscriptRow(
message = msg,
showThinking = showThinking,
@@ -729,6 +734,8 @@ internal fun pendingVoiceTranscriptText(
return if (alreadyRendered) null else transcribed
}
internal fun voiceTranscriptItemKey(message: ChatMessage): String = message.uiKey
@Composable
private fun InteractionMode.label(): String = when (this) {
InteractionMode.TapToTalk -> stringResource(R.string.voice_overlay_tap_to_talk)
@@ -20,6 +20,32 @@ import org.junit.Test
class VoiceModeOverlayStateTest {
@Test
fun transcriptKeys_remainDistinctWhenRowsShareReconciledServerId() {
val serverId = "7c4af8b7-1bb2-4830-a4e5-0332d5ddcd1f"
val messages = listOf(
ChatMessage(
id = serverId,
uiKey = "persisted-assistant-row",
role = MessageRole.ASSISTANT,
content = "Earlier snapshot",
timestamp = 1L,
),
ChatMessage(
id = serverId,
uiKey = "live-assistant-row",
role = MessageRole.ASSISTANT,
content = "Reconciled live snapshot",
timestamp = 2L,
),
)
assertEquals(
listOf("persisted-assistant-row", "live-assistant-row"),
messages.map(::voiceTranscriptItemKey),
)
}
@Test
fun providerTranscript_isTranscribingAfterMicrophoneCaptureStops() {
assertEquals(VoiceState.Transcribing, realtimeTranscriptState(micCaptureActive = false))
+3 -5
View File
@@ -85,12 +85,10 @@ This app is a community project and is not affiliated with or endorsed by NousRe
Paste into Play Console → **What's new** (≤500 characters):
```
v1.5.2 - Sign in without detours
v1.5.3 - Voice stays open
* Reliable self-hosted OIDC and Nous Portal sign-in.
* Secure system-browser flow for Nous provider challenges.
* Private-LAN and Tailscale dashboard route support.
* Replayed chat updates no longer duplicate rows.
* Prevent Voice Focus from closing during chat-history reconciliation.
* Keep live transcript rows stable when persisted identities arrive.
```
## Category
+2 -2
View File
@@ -1,6 +1,6 @@
[versions]
appVersionName = "1.5.2"
appVersionCode = "35"
appVersionName = "1.5.3"
appVersionCode = "36"
agp = "9.3.1"
kotlin = "2.4.10"
compose-bom = "2026.06.01"