Auto-threading, history pagination, streaming toggle + tool/reasoning display settings

- Auto-threading (Telegram topic-mode workflow): message.send {auto_thread}
  mints a fresh AI-named thread (instant derived title, LLM upgrade via
  channel.renamed); channel.created {auto:true}; the app jumps into the new
  thread and relocates the optimistic pending bubble.
- history frame: paged full message history for initial channel open /
  scroll-up pagination (reconstructed from the outbox log).
- Streaming on/off: gateway side (display.platforms.android.streaming) plus a
  per-device app toggle (Settings → Streaming); reasoning/model/tokens carried
  on message frames.
- Context menu: long-press (touch) / right-click (desktop) thread affordances
  via a KMP rightClick expect/actual.
- Settings → Reasoning: auto-collapse long reasoning blocks (default on).
- Tool detail: the gateway now always supplies full tool data — it forces
  verbose tool progress (full args → tool.start.args) and captures each
  completed call via the post_tool_call hook (output/duration/ok → tool.end).
  The app reveals the full call + output on expand (Truncated) and
  auto-expands cards in Everything mode.
This commit is contained in:
ARIA committed 2026-08-20 16:26:52 +02:00
1 parent e678caafdc
commit efecf2732e
24 files changed
+1115 -81

No files matched your search

+47 -3
View File
@@ -68,6 +68,9 @@ TYPE_SEARCH_RESULTS = "search.results"
TYPE_SYNC = "sync"
TYPE_SYNC_DONE = "sync.done"
# Full message history (initial channel open / scroll-up pagination)
TYPE_HISTORY = "history"
# Media (M4)
TYPE_MEDIA_UPLOAD_START = "media.upload.start"
TYPE_MEDIA_UPLOAD_END = "media.upload.end"
@@ -430,9 +433,18 @@ def _channel_payload(entry: Dict[str, Any]) -> Dict[str, Any]:
return payload
def channel_created(entry: Dict[str, Any]) -> Frame:
"""Broadcast: a channel/thread was created."""
return Frame(type=TYPE_CHANNEL_CREATED, payload=_channel_payload(entry))
def channel_created(entry: Dict[str, Any], auto: bool = False) -> Frame:
"""Broadcast: a channel/thread was created.
``auto=True`` marks a thread the gateway minted itself for an incoming
message (auto-threading, docs/06 §6.3): the app jumps into it and the
name is an instant derived title, upgraded by the LLM via a follow-up
``channel.renamed``.
"""
payload = _channel_payload(entry)
if auto:
payload["auto"] = True
return Frame(type=TYPE_CHANNEL_CREATED, payload=payload)
def channel_renamed(entry: Dict[str, Any]) -> Frame:
@@ -484,6 +496,38 @@ def sync_done(cursor: int, *, id: Optional[int] = None) -> Frame:
return Frame(type=TYPE_SYNC_DONE, id=id, payload={"cursor": cursor})
# ---------------------------------------------------------------------------
# History frame (full message history for a chat/thread)
# ---------------------------------------------------------------------------
def history(
chat_id: str,
messages: List[Dict[str, Any]],
has_more: bool,
*,
thread_id: Optional[str] = None,
oldest_message_id: Optional[str] = None,
id: Optional[int] = None,
) -> Frame:
"""Response to a ``history`` request: a page of final messages for a
chat/thread, ordered oldest → newest. ``has_more`` signals older pages
exist; ``oldest_message_id`` is the ``before_message_id`` for the next
(older) page."""
payload: Dict[str, Any] = {
"messages": messages,
"has_more": has_more,
}
if oldest_message_id:
payload["oldest_message_id"] = oldest_message_id
return Frame(
type=TYPE_HISTORY,
id=id,
chat_id=chat_id,
thread_id=thread_id,
payload=payload,
)
# ---------------------------------------------------------------------------
# Push / notification frames (M5)
# ---------------------------------------------------------------------------