t-261010092931: typing «печатает…» весь тик LLM — без привязки к pending-инбоксу; чаты из всего TG-инбокса, фолбэк на чат харнеса; тест: всё seen/пустой инбокс/только портал/чат неизвестен (25 PASS)
This commit is contained in:
parent
58cc3785c6
commit
57a0f97318
2 changed files with 77 additions and 20 deletions
|
|
@ -481,19 +481,30 @@ def run_level_tick(level_cfg, seq: int, model: dict):
|
||||||
claimed = None
|
claimed = None
|
||||||
prompt = build_context(level_cfg, model, batch)
|
prompt = build_context(level_cfg, model, batch)
|
||||||
# Индикация «взял и работаю» (e-261002202857/73bbaf): пока LLM-тик гоняется,
|
# Индикация «взял и работаю» (e-261002202857/73bbaf): пока LLM-тик гоняется,
|
||||||
# фоновый поток держит sendChatAction typing в TG-чатах инбокса (обновление
|
# фоновый поток держит sendChatAction typing (обновление каждые ~2с) —
|
||||||
# каждые ~2с) — «печатает…» виден весь тик. Реакция 👀 на конкретные
|
# «печатает…» виден весь тик. Реакция 👀 на конкретные входящие — поллером
|
||||||
# входящие — поллером при приёме (MessageSeen) и по требованию cli.py tg-seen.
|
# при приёме (MessageSeen) и по требованию cli.py tg-seen.
|
||||||
# Останов потока — в finally в конце функции.
|
# t-261010092931: раньше поток поднимался ТОЛЬКО при непросмотренном
|
||||||
|
# pending-инбоксе — с пустым/просмотренным инбоксом индикатора не было весь
|
||||||
|
# тик. Теперь «печатает…» горит весь тик LLM независимо от pending и от
|
||||||
|
# claimed-задач: чаты берём из всего инбокса модели (seen/replied не важны),
|
||||||
|
# а при пустом инбоксе — последний живой TG-чат харнеса (_default_chat_id,
|
||||||
|
# личка Alex). typing — только TG-чаты: портал-каналу и TUI typing API
|
||||||
|
# недоступен. Останов потока — в finally в конце функции.
|
||||||
from . import tg_inbox
|
from . import tg_inbox
|
||||||
keepalive = None
|
keepalive = None
|
||||||
keep_stop = threading.Event()
|
keep_stop = threading.Event()
|
||||||
pending = [m for m in _pending_inbox(model) if not m.get("seen")]
|
tg_chat_ids = list({m.get("chat_id") for m in (model.get("inbox") or {}).values()
|
||||||
if pending:
|
|
||||||
# typing — только TG-чаты (портал-каналу typing API недоступен)
|
|
||||||
tg_chat_ids = list({m.get("chat_id") for m in pending
|
|
||||||
if m.get("chat_id")
|
if m.get("chat_id")
|
||||||
and not str(m.get("chat_id")).startswith("portal")})
|
and not str(m.get("chat_id")).startswith(("portal", "tui"))})
|
||||||
|
if not tg_chat_ids:
|
||||||
|
# пустой инбокс — показываем «печатает…» в чате харнеса, если он известен
|
||||||
|
try:
|
||||||
|
_dc = tg_inbox._default_chat_id()
|
||||||
|
except Exception:
|
||||||
|
_dc = None
|
||||||
|
if _dc is not None:
|
||||||
|
tg_chat_ids = [_dc]
|
||||||
if tg_chat_ids:
|
if tg_chat_ids:
|
||||||
keepalive = threading.Thread(
|
keepalive = threading.Thread(
|
||||||
target=tg_inbox.typing_keepalive,
|
target=tg_inbox.typing_keepalive,
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@
|
||||||
(нет ни реакции, ни второго события), TG-сбой — False без события;
|
(нет ни реакции, ни второго события), TG-сбой — False без события;
|
||||||
- receive_message сохраняет message_id (нативный, не хэш-фолбэк);
|
- receive_message сохраняет message_id (нативный, не хэш-фолбэк);
|
||||||
- typing_keepalive: держит sendChatAction typing и останавливается по Event;
|
- typing_keepalive: держит sendChatAction typing и останавливается по Event;
|
||||||
- run_level_tick: поднимает keepalive по TG-чатам неотвеченного инбокса,
|
- run_level_tick: поднимает keepalive по TG-чатам инбокса ВЕСЬ тик, без
|
||||||
исключает портал-чаты, гасит поток в finally (на любом исходе возврата).
|
привязки к pending/seen (t-261010092931), исключает портал-чаты, при
|
||||||
|
пустом инбоксе — фолбэк на чат харнеса; гасит поток в finally (любой исход).
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
@ -173,7 +174,9 @@ try:
|
||||||
check("tick: worker упал → finally всё равно гасит keepalive",
|
check("tick: worker упал → finally всё равно гасит keepalive",
|
||||||
ka_seen.get("stop") is not None and ka_seen.get("stop").is_set())
|
ka_seen.get("stop") is not None and ka_seen.get("stop").is_set())
|
||||||
|
|
||||||
# все сообщения уже seen → keepalive не поднимается вовсе
|
# t-261010092931: всё seen → «печатает…» всё равно горит весь тик
|
||||||
|
# (индикатор больше не зависит от pending: Alex видит «печатает…»
|
||||||
|
# всё время, пока LLM-тик работает)
|
||||||
ka_seen.clear()
|
ka_seen.clear()
|
||||||
model2 = dict(model)
|
model2 = dict(model)
|
||||||
model2["inbox"] = {
|
model2["inbox"] = {
|
||||||
|
|
@ -182,7 +185,50 @@ try:
|
||||||
}
|
}
|
||||||
_ir_module.run_llm_tick = staticmethod(_FakeRunner.run_llm_tick)
|
_ir_module.run_llm_tick = staticmethod(_FakeRunner.run_llm_tick)
|
||||||
run_level_tick(LEVELS["hour"], 4244, model2)
|
run_level_tick(LEVELS["hour"], 4244, model2)
|
||||||
check("tick: всё seen → keepalive не поднимается", ka_seen == {}, str(ka_seen))
|
check("tick: всё seen → keepalive всё равно поднят по TG-чату",
|
||||||
|
ka_seen.get("ids") == [42], str(ka_seen))
|
||||||
|
check("tick: всё seen → finally погасил keepalive",
|
||||||
|
ka_seen.get("stop") is not None and ka_seen.get("stop").is_set())
|
||||||
|
|
||||||
|
# t-261010092931: пустой инбокс → фолбэк на последний живой TG-чат
|
||||||
|
# (_default_chat_id, личка Alex): индикатор горит и без входящих
|
||||||
|
ka_seen.clear()
|
||||||
|
model3 = dict(model)
|
||||||
|
model3["inbox"] = {}
|
||||||
|
_orig_default_chat = tg_inbox._default_chat_id
|
||||||
|
tg_inbox._default_chat_id = lambda: 42
|
||||||
|
try:
|
||||||
|
_ir_module.run_llm_tick = staticmethod(_FakeRunner.run_llm_tick)
|
||||||
|
run_level_tick(LEVELS["hour"], 4245, model3)
|
||||||
|
finally:
|
||||||
|
tg_inbox._default_chat_id = _orig_default_chat
|
||||||
|
check("tick: пустой инбокс → keepalive по чату харнеса (фолбэк)",
|
||||||
|
ka_seen.get("ids") == [42], str(ka_seen))
|
||||||
|
check("tick: пустой инбокс → finally погасил keepalive",
|
||||||
|
ka_seen.get("stop") is not None and ka_seen.get("stop").is_set())
|
||||||
|
|
||||||
|
# инбокс без TG-чатов (только портал/tui) → тоже фолбэк на чат харнеса
|
||||||
|
ka_seen.clear()
|
||||||
|
model4 = dict(model)
|
||||||
|
model4["inbox"] = {"m-2": model["inbox"]["m-2"]}
|
||||||
|
tg_inbox._default_chat_id = lambda: 42
|
||||||
|
try:
|
||||||
|
_ir_module.run_llm_tick = staticmethod(_FakeRunner.run_llm_tick)
|
||||||
|
run_level_tick(LEVELS["hour"], 4246, model4)
|
||||||
|
finally:
|
||||||
|
tg_inbox._default_chat_id = _orig_default_chat
|
||||||
|
check("tick: только портал-чаты → keepalive по фолбэку, портал исключён",
|
||||||
|
ka_seen.get("ids") == [42], str(ka_seen))
|
||||||
|
|
||||||
|
# фолбэк недоступен (нет известного чата) → keepalive не поднимается
|
||||||
|
ka_seen.clear()
|
||||||
|
tg_inbox._default_chat_id = lambda: None
|
||||||
|
try:
|
||||||
|
_ir_module.run_llm_tick = staticmethod(_FakeRunner.run_llm_tick)
|
||||||
|
run_level_tick(LEVELS["hour"], 4247, model3)
|
||||||
|
finally:
|
||||||
|
tg_inbox._default_chat_id = _orig_default_chat
|
||||||
|
check("tick: чат неизвестен → keepalive не поднимается", ka_seen == {}, str(ka_seen))
|
||||||
finally:
|
finally:
|
||||||
scheduler.es = _orig_es
|
scheduler.es = _orig_es
|
||||||
tg_inbox.typing_keepalive = _orig_tg_typing_backup
|
tg_inbox.typing_keepalive = _orig_tg_typing_backup
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue