fix(backend/copilot): set transcript_content on baseline restore, fix relative import in transcript.py

- _restore_cli_session_for_turn now sets result.transcript_content when loading
  baseline content into the TranscriptBuilder, preventing the _seed_transcript
  guard in stream_chat_completion_sdk from overwriting the builder with a full
  DB reconstruction (which would duplicate entries since load_previous appends).
- Change transcript.py TYPE_CHECKING and runtime ChatMessage import from
  absolute (backend.copilot.model) to relative (.model) to match service.py's
  import style and eliminate Pyright type-identity collisions.
- Unpack _load_prior_transcript tuple return in mode_switch_context_test.py
  and assert dl is not None.
- Add assert result.transcript_content != "" in service_helpers_test.py.
This commit is contained in:
Zamil Majdy
2026-04-16 14:04:32 +07:00
parent d91cfb5d84
commit 0c3a15832b
4 changed files with 14 additions and 4 deletions

View File

@@ -277,7 +277,7 @@ class TestSdkToFastModeSwitch:
"backend.copilot.baseline.service.download_transcript",
new=AsyncMock(return_value=restore),
):
covers = await _load_prior_transcript(
covers, dl = await _load_prior_transcript(
user_id="user-1",
session_id="session-1",
session_messages=[
@@ -290,6 +290,7 @@ class TestSdkToFastModeSwitch:
# CLI session is valid and covers the prefix.
assert covers is True
assert dl is not None
assert baseline_builder.entry_count == 2
@pytest.mark.asyncio
@@ -332,7 +333,7 @@ class TestSdkToFastModeSwitch:
"backend.copilot.baseline.service.download_transcript",
new=AsyncMock(return_value=restore),
):
covers = await _load_prior_transcript(
covers, dl = await _load_prior_transcript(
user_id="user-1",
session_id="session-1",
session_messages=session_messages,
@@ -341,5 +342,6 @@ class TestSdkToFastModeSwitch:
# With gap filling, covers is True and gap messages are appended.
assert covers is True
assert dl is not None
# 2 from transcript + 7 gap messages (positions 2..8, excluding last user turn)
assert baseline_builder.entry_count == 9

View File

@@ -2538,6 +2538,9 @@ async def _restore_cli_session_for_turn(
)
# Load baseline transcript content into builder so the upload path has accurate state.
# Also sets result.transcript_content so the _seed_transcript guard in the caller
# (``not transcript_content``) does not overwrite this builder state with a DB
# reconstruction — which would duplicate entries since load_previous appends.
if result.baseline_download is not None:
try:
raw_for_builder = result.baseline_download.content
@@ -2546,6 +2549,7 @@ async def _restore_cli_session_for_turn(
stripped = strip_for_upload(raw_for_builder)
if validate_transcript(stripped):
transcript_builder.load_previous(stripped, log_prefix=log_prefix)
result.transcript_content = stripped
except Exception as _load_err:
logger.debug(
"%s Could not load baseline transcript into builder: %s",

View File

@@ -859,6 +859,10 @@ class TestRestoreCliSessionModeCheck:
assert result.context_messages[0].role == "user"
assert result.context_messages[1].role == "assistant"
assert "TRANSCRIPT_ASSISTANT" in (result.context_messages[1].content or "")
# transcript_content must be non-empty so the _seed_transcript guard in
# stream_chat_completion_sdk skips DB reconstruction (which would duplicate
# builder entries since load_previous appends).
assert result.transcript_content != ""
@pytest.mark.asyncio
async def test_baseline_mode_gap_present_context_includes_gap(self, tmp_path):

View File

@@ -29,7 +29,7 @@ from backend.util.prompt import CompressResult, compress_context
from backend.util.workspace_storage import GCSWorkspaceStorage, get_workspace_storage
if TYPE_CHECKING:
from backend.copilot.model import ChatMessage
from .model import ChatMessage
logger = logging.getLogger(__name__)
@@ -858,7 +858,7 @@ def extract_context_messages(
A list of ``ChatMessage`` objects covering the prior conversation
context, suitable for injection as conversation history.
"""
from backend.copilot.model import ChatMessage as _ChatMessage # runtime import
from .model import ChatMessage as _ChatMessage # runtime import
prior = session_messages[:-1]