Gate group speaker isolation to shared chat sessions only.

Per-user group sessions (user_in_chat) already isolate history; keep Sender tags and focus hints only when session_scope=chat (legacy shared __group__ transcripts).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-08-10 23:16:27 +08:00
parent e91e4fe773
commit 9bbac6c0b8
5 changed files with 50 additions and 21 deletions

View file

@ -1453,15 +1453,21 @@ def process_inbound_payload(payload: dict[str, Any]) -> dict[str, Any]:
)
if str(lang or "").startswith("zh"):
busy_text = (
"本会话还有请求在处理,你这条已排队,完成后会继续回答。"
if bool(getattr(inbound, "is_group", False))
"本群共享会话还有请求在处理,你这条已排队,完成后会继续回答。"
if (
bool(getattr(inbound, "is_group", False))
and str(group_policy.session_scope or "") == "chat"
)
else "还在处理上一条请求,这条会排队合并处理。"
)
else:
busy_text = (
"Still working on an earlier request in this chat; "
"Still working on an earlier request in this shared group chat; "
"your message is queued and will be answered next."
if bool(getattr(inbound, "is_group", False))
if (
bool(getattr(inbound, "is_group", False))
and str(group_policy.session_scope or "") == "chat"
)
else "Still working on your previous request; "
"I'll merge this follow-up next."
)

View file

@ -486,11 +486,18 @@ class OclawGateway:
@staticmethod
def _group_focus_system_hint(msg: StandardMessage, lang: str) -> str:
"""Only for shared group transcripts (legacy session_scope=chat / __group__)."""
md = msg.metadata if isinstance(msg.metadata, dict) else {}
if not bool(md.get("is_group")):
return ""
from runtime.orchestration.group_ingest import build_group_focus_instruction
from runtime.orchestration.group_ingest import (
build_group_focus_instruction,
normalize_group_session_scope,
)
scope = normalize_group_session_scope(md.get("group_session_scope"))
if scope != "chat":
return ""
return str(build_group_focus_instruction(lang=lang) or "").strip()
@staticmethod

View file

@ -590,11 +590,12 @@ def prepare_group_user_text_for_model(
account_id=account_id,
)
prefix_parts: list[str] = []
# Always tag the speaker in groups (shared or per-user) so history/quotes cannot 串话.
_ = session_scope # retained for call-site compatibility / future policy forks
prefix_parts.append(
build_group_sender_context(metadata=metadata, external_user_id=external_user_id, lang=lang)
)
# Shared group transcript only: tag speaker so multi-member history cannot 串话.
# Per-user group sessions (user_in_chat) already isolate by session — skip the prefix.
if normalize_group_session_scope(session_scope) == "chat":
prefix_parts.append(
build_group_sender_context(metadata=metadata, external_user_id=external_user_id, lang=lang)
)
quote = str(quoted_ctx or "").strip()
if quote:
prefix_parts.append(quote)
@ -605,14 +606,15 @@ def prepare_group_user_text_for_model(
def build_group_focus_instruction(*, lang: str = "en") -> str:
"""Isolation hint for *shared* group transcripts (session_scope=chat)."""
if str(lang or "").strip().lower().startswith("zh"):
return (
"[群聊规则:只回答当前发言人(见 [发言: …])的问题;"
"[群聊规则(共享会话):只回答当前发言人(见 [发言: …])的问题;"
"除非本条消息明确引用或承接前文,否则不要默认继承其他群成员的上下文;"
"若排队合并了多条跟进,按条分别回应并 @ 对应发言人。]"
)
return (
"[Group chat rule: answer only the current sender (see [Sender: …]). "
"[Shared group-chat rule: answer only the current sender (see [Sender: …]). "
"Do not assume context from other members unless this message explicitly quotes or references it. "
"If several follow-ups were merged while busy, answer each item and @ the matching sender.]"
)