N turns séquentiels reçus line-by-line (NDJSON). On ne sait pas à l'avance combien de turns. Chaque turn = 1 assistant event avec content[] pouvant contenir text + tool_use.

TURN 1
text "Maintenant j'ai tout ce qu'il faut. On y va :"
Edit cli_protocol.py__init__
TURN 2
text "Maintenant le __anext__ — drain le prefetch :"
Edit cli_protocol.py__anext__
TURN 3
text "Maintenant send_and_read_stream :"
Edit cli_protocol.pysend_and_read_stream
TURN N
text "Propre. 48 tests passés, 0 échec."
← Pas de tool_use dans ce turn
RESULT
result is_error: false
duration_ms: 14 230
total_cost: $0.0041

⚑ Le pool actuel extrait uniquement les blocs type=="text" et appelle le callback Telegram. Les blocs tool_use sont dans content[] mais filtrés et ignorés.

Référence pour s'inspirer. Même pattern de données, affichages très différents.

Claude Code — Terminal
permission prompt • pas de diff inline
Maintenant le __anext__ :
✎ Edit cli_protocol.py
Allow edit to cli_protocol.py?
▶ Yes ○ Yes, don't ask ○ No
✎ Edit cli_protocol.py
 Applied

Tool label + fichier visible. Diff montré dans VS Code seulement (pas dans le terminal).

🤖
Aider
streaming live • auto-commit
Maintenant le __anext__ :
cli_protocol.py
-   while True:
-       data = await...
+   while self._prefetch:
+       yield self._prefetch...
Applied edit to cli_protocol.py ✓
git commit: refactor __anext__

Diff search/replace en couleurs + confirmation "Applied edit" + auto-commit à chaque edit.

Cursor
diff inline éditeur • Apply button
cli_protocol.py
chat
42 async def __anext__(self):
43- while True:
43+ while self._prefetch_buf:
44- data = await self._read()
44+ yield self._prefetch_buf.pop(0)
45 return StopAsyncIteration

Diff rouge/vert inline dans l'éditeur. Accept/reject par ligne. "Apply" dans le chat.

Chaque variante sur 3 scénarios : Tab A = 3 edits | Tab B = 12 edits même fichier | Tab C = 80 tools, 6 fichiers + bash + reads.

01 / Text only — Actuel
Seuls les blocs text envoyés. Les tool_use ignorés silencieusement.
Tronqué Confus 0 change requis
5 msgs
immédiat
3 intros sans suite
L
Lyra
en ligne
LyraMaintenant j'ai tout ce qu'il faut. On y va :
21:34
LyraMaintenant le __anext__ — drain le prefetch :
21:34
LyraMaintenant send_and_read_stream :
21:35
LyraPropre. 48 tests passés, 0 échec.
21:35
13 msgs
immédiat
12 intros tronquées
L
Lyra
en ligne
LyraMaintenant __init__ :
21:34
LyraMaintenant __anext__ :
21:34
LyraMaintenant send_and_read_stream :
21:34
LyraMaintenant _prefetch_intermediates :
21:34
LyraJe mets à jour les types :
21:35
LyraMaintenant les tests :
21:35
… 6 autres bulles tronquées …
LyraPropre. 48 tests passés, 0 échec.
21:37
~25 msgs
immédiat
spam total
L
Lyra
en ligne
LyraJe commence par lire les fichiers existants :
21:30
LyraJe lis les tests :
21:30
LyraMaintenant cli_protocol.py :
21:31
… 20 bulles tronquées supplémentaires …
LyraJe lance les tests :
21:35
LyraPropre. 48 tests passés, 0 échec.
21:36
Complexité impl. S API Telegram: N msgs
02 / Résumé inline
Texte intro + résumé edit dans la même bulle. Fusionner text + tool_use du même turn.
+Contexte Verbeux à 12+ M — parse tool_use
4 msgs
immédiat
contexte complet
L
Lyra
en ligne
LyraMaintenant j'ai tout ce qu'il faut. On y va :
✏️ cli_protocol.py__init__
21:34
LyraMaintenant le __anext__ :
✏️ cli_protocol.py__anext__
21:34
LyraMaintenant send_and_read_stream :
✏️ cli_protocol.pysend_and_read_stream
21:35
LyraPropre. 48 tests passés, 0 échec.
21:35
13 msgs
immédiat
lourd à lire
L
Lyra
en ligne
LyraMaintenant __init__ :
✏️ cli_protocol.py__init__
21:34
LyraMaintenant __anext__ :
✏️ cli_protocol.py__anext__
21:34
LyraMaintenant les types :
✏️ cli_protocol.pyStreamingIterator
21:34
… 9 bulles supplémentaires identiques …
LyraPropre. 48 tests passés, 0 échec.
21:37
~25 msgs
immédiat
scroll infini
L
Lyra
en ligne
LyraJe lis les fichiers :
🔍 cli_protocol.pyRead
21:30
LyraJe commence par __init__ :
✏️ cli_protocol.py__init__
21:31
… 22 bulles supplémentaires … scroll sans fin …
LyraJe lance les tests :
bashpytest -x
21:35
LyraPropre. 48 tests passés, 0 échec.
21:36
Complexité impl. M API Telegram: N sendMessage
03A / Message live édité ⭐
1 message envoyé au 1er tool, édité à chaque nouveau turn. Message final = résultat complet.
Feedback live Scale bien Rate-limit 30/min M — editMessage
1 msg
+N edits
feedback immédiat
L
Lyra
en ligne
Lyra travaille…
1 msg
+12 edits
throttle 1 edit/2s
L
Lyra
en ligne
Lyracli_protocol.py — 12 edits
__init__
__anext__
send_and_read_stream
_prefetch_intermediates
StreamingIterator.__aiter__
_drain_buffer
… 6 autres edits …
Propre. 48 tests, 0 échec.
21:37
1 msg
groupé par fichier
throttle obligatoire
L
Lyra
en ligne
Lyra✅ Session — 6 fichiers, 80 edits
📄cli_protocol.py ×23
📄tests/test_cli.py ×31
📄pyproject.toml ×3
📄3 autres fichiers ×23
5 bash · 8 reads · 2 greps
Propre. 48 tests, 0 échec.
21:36
Complexité impl. M API: 1 send + N editMessage (throttled)
03B / Message différé
Silence jusqu'au RESULT event final, puis 1 message synthétique riche.
Propre Silence total Anxiogène à 80 tools M — accumuler turns
1 msg
~15s attente
très propre
L
Lyra
en ligne
15 secondes de silence…
Lyra3 edits cli_protocol.py
__init__prefetch: list[bytes]
__anext__drain prefetch avant stdout
send_and_read_streamawait _prefetch
Propre. 48 tests, 0 échec.
21:35
1 msg
~45s attente
ok mais long
L
Lyra
en ligne
45 secondes de silence…
Lyra12 edits cli_protocol.py
__init__(prefetch param)
__anext__(drain buffer)
_prefetch_intermediates
… 9 autres edits …
Propre. 48 tests, 0 échec.
21:37
1 msg
3+ minutes silence
Lyra morte ?
L
Lyra
3 min 12 sec de silence total ⚠️
Lyra✅ Session — 6 fichiers, 80 edits
📄cli_protocol.py×23
📄tests/test_cli.py×31
📄3 autres fichiers×26
5 bash · 8 reads
Propre. 48 tests, 0 échec.
21:36
Complexité impl. M API: 1 sendMessage uniquement