e-261015222515: память разговора в контексте тика — секция НЕДАВНИЙ РАЗГОВОР (отвеченные реплики + наш ответ тех же чатов, cap 12) рядом с батчем неотвеченных; мин-уровень больше не теряет нить после ReplySent; тест +6 PASS
This commit is contained in:
parent
2432b6f012
commit
0daf10135c
2 changed files with 53 additions and 0 deletions
|
|
@ -380,6 +380,7 @@ def build_context(level_cfg, model: dict, batch=None):
|
||||||
if m.get("reply_to_message_id") is not None else ""))
|
if m.get("reply_to_message_id") is not None else ""))
|
||||||
+ ": " + m.get('text','')[:1200])
|
+ ": " + m.get('text','')[:1200])
|
||||||
batch_ids = ",".join(ids)
|
batch_ids = ",".join(ids)
|
||||||
|
chat_ids = {m.get("chat_id") for m in inbox if m.get("chat_id") is not None}
|
||||||
# t-261013131228: если в батче есть reply на сообщение без текста —
|
# t-261013131228: если в батче есть reply на сообщение без текста —
|
||||||
# добавляем последние документы этого чата с caption, чтобы триаж
|
# добавляем последние документы этого чата с caption, чтобы триаж
|
||||||
# видел, о каком документе речь, даже если «голова» старше капа инбокса
|
# видел, о каком документе речь, даже если «голова» старше капа инбокса
|
||||||
|
|
@ -395,6 +396,29 @@ def build_context(level_cfg, model: dict, batch=None):
|
||||||
+ "; ".join(docs))
|
+ "; ".join(docs))
|
||||||
if docs_ctx:
|
if docs_ctx:
|
||||||
parts.append("КОНТЕКСТ ДОКУМЕНТОВ ЧАТА:\n" + "\n".join(docs_ctx.values()))
|
parts.append("КОНТЕКСТ ДОКУМЕНТОВ ЧАТА:\n" + "\n".join(docs_ctx.values()))
|
||||||
|
# t-261015222515: память разговора — рядом с батчем неотвеченных лежит
|
||||||
|
# нить недавнего диалога (отвеченные реплики + наши ответы) тех же
|
||||||
|
# чатов. Раньше после ReplySent входящее выпадало из контекста тика —
|
||||||
|
# минутный уровень отвечал без памяти о разговоре (Alex про SPA-договор:
|
||||||
|
# «только что же обсуждали»). Источник — та же проекция инбокса
|
||||||
|
# (reply_text из ReplySent), отдельный стор не нужен.
|
||||||
|
replied_hist = [m for m in (model.get("inbox") or {}).values()
|
||||||
|
if m.get("replied") and not m.get("ignored")
|
||||||
|
and m.get("chat_id") in chat_ids
|
||||||
|
and (m.get("text") or "").strip()]
|
||||||
|
if replied_hist:
|
||||||
|
replied_hist = sorted(replied_hist, key=lambda x: x.get("ts") or "")[-12:]
|
||||||
|
hist_lines = []
|
||||||
|
for m in replied_hist:
|
||||||
|
m_id = "m-" + str(m.get("update_id"))
|
||||||
|
who = m.get("username") or m.get("first_name") or m.get("user_id")
|
||||||
|
line = f"- [{m_id}] {who}: {(m.get('text') or '')[:600]}"
|
||||||
|
rt = (m.get("reply_text") or "").strip()
|
||||||
|
if rt:
|
||||||
|
line += f"\n └ наш ответ: {rt[:600]}"
|
||||||
|
hist_lines.append(line)
|
||||||
|
parts.append("НЕДАВНИЙ РАЗГОВОР (уже отвечено; это память тика — НЕ отвечай "
|
||||||
|
"на них снова, используй как контекст):\n" + "\n".join(hist_lines))
|
||||||
# t-260930064924: батч-триаж — ВСЕ неотвеченные обрабатываются ОДНИМ тиком.
|
# t-260930064924: батч-триаж — ВСЕ неотвеченные обрабатываются ОДНИМ тиком.
|
||||||
# Раньше мин-уровень отвечал по одному за тик (m-516173222..228 — 7 тиков
|
# Раньше мин-уровень отвечал по одному за тик (m-516173222..228 — 7 тиков
|
||||||
# подряд на один разговор). Теперь в контексте лежит ГОТОВАЯ команда
|
# подряд на один разговор). Теперь в контексте лежит ГОТОВАЯ команда
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,35 @@ check("build_context: ГОТОВАЯ команда со ВСЕМИ id",
|
||||||
f"cli.py tg-reply {ids_line} -c" in sec, sec[:400])
|
f"cli.py tg-reply {ids_line} -c" in sec, sec[:400])
|
||||||
check("build_context: инструкция «за ЭТОТ тик»", "именно в ЭТОМ тике" in sec)
|
check("build_context: инструкция «за ЭТОТ тик»", "именно в ЭТОМ тике" in sec)
|
||||||
|
|
||||||
|
# ── 1b. t-261015222515: память разговора — отвеченные реплики тех же чатов ──
|
||||||
|
# Сценарий эскалации: обсуждали SPA-договор, мин-тик ответил (ReplySent) —
|
||||||
|
# на следующем тике контекст ДОЛЖЕН помнить нить (текст + наш ответ),
|
||||||
|
# иначе триаж отвечает без памяти о разговоре (Alex: «только что же обсуждали»).
|
||||||
|
fake["inbox"]["m-70100"] = {
|
||||||
|
"update_id": 70100, "chat_id": 42, "text": "вот этот SPA-договор мы только что обсуждали",
|
||||||
|
"kind": "text", "replied": True, "ignored": False,
|
||||||
|
"reply_text": "да, это вторая версия без ЗП-обязательств",
|
||||||
|
"ts": "2026-09-30T06:55:00+00:00",
|
||||||
|
}
|
||||||
|
fake["inbox"]["m-70101"] = {
|
||||||
|
"update_id": 70101, "chat_id": 7, "text": "сообщение ДРУГОГО чата — не должно попасть",
|
||||||
|
"kind": "text", "replied": True, "ignored": False,
|
||||||
|
"ts": "2026-09-30T06:56:00+00:00",
|
||||||
|
}
|
||||||
|
ctx = build_context(LEVELS["min"], fake)
|
||||||
|
hist = re.search(r"НЕДАВНИЙ РАЗГОВОР.*?(?:\n\n|$)", ctx, re.S)
|
||||||
|
hsec = hist.group(0) if hist else ""
|
||||||
|
check("память: секция НЕДАВНИЙ РАЗГОВОР есть", bool(hist), ctx[:200])
|
||||||
|
check("память: отвеченное сообщение в контексте", "SPA-договор" in hsec, hsec[:200])
|
||||||
|
check("память: наш ответ виден", "без ЗП-обязательств" in hsec, hsec[:300])
|
||||||
|
check("память: чужой чат НЕ в памяти", "ДРУГОГО чата" not in hsec and "m-70101" not in hsec)
|
||||||
|
check("память: помечена «НЕ отвечай снова»", "НЕ отвечай" in hsec)
|
||||||
|
# без неотвеченных (нет батча) — секции нет: нечего контекстуализировать
|
||||||
|
only_replied = {"inbox": {"m-70100": dict(fake["inbox"]["m-70100"])},
|
||||||
|
"tasks": {}, "escalations": {}, "policy": {}}
|
||||||
|
check("память: без неотвеченных секции нет",
|
||||||
|
"НЕДАВНИЙ РАЗГОВОР" not in build_context(LEVELS["min"], only_replied))
|
||||||
|
|
||||||
# ── 2. send_batch_reply: одна отправка → ReplySent на каждое входящее ──
|
# ── 2. send_batch_reply: одна отправка → ReplySent на каждое входящее ──
|
||||||
# сценарий из постановки: 7 сообщений одного разговора об экономии тиков
|
# сценарий из постановки: 7 сообщений одного разговора об экономии тиков
|
||||||
for i, text in enumerate([
|
for i, text in enumerate([
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue