Flatten system-prompt blocks for an OpenAI-compatible provider. Returns ``(system_text, volatile_tail_text)``. The ``__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__`` marker is always dropped (it is an Anthropic cache-only signal that would be unintelligible prose to other models). When ``
(
blocks: list[dict[str, Any]], *, relocate_request_scope: bool
)
| 417 | |
| 418 | |
| 419 | def _split_system_prompt_blocks( |
| 420 | blocks: list[dict[str, Any]], *, relocate_request_scope: bool |
| 421 | ) -> tuple[str, str]: |
| 422 | """Flatten system-prompt blocks for an OpenAI-compatible provider. |
| 423 | |
| 424 | Returns ``(system_text, volatile_tail_text)``. |
| 425 | |
| 426 | The ``__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__`` marker is always dropped (it is |
| 427 | an Anthropic cache-only signal that would be unintelligible prose to other |
| 428 | models). |
| 429 | |
| 430 | When ``relocate_request_scope`` is True (DeepSeek only), blocks tagged |
| 431 | ``_cache_scope == "request"`` — the env section, the auto-memory section |
| 432 | (which embeds the mutable ``MEMORY.md`` body), plan-mode / non-interactive |
| 433 | / tool-restriction sections — are routed into ``volatile_tail_text`` so the |
| 434 | caller can place them AFTER the conversation history. That keeps the |
| 435 | ``system + tools + history`` prefix byte-stable across turns, so DeepSeek's |
| 436 | automatic prefix cache covers it even when memory or the environment |
| 437 | changes mid-session. |
| 438 | |
| 439 | When False (every other provider), the tail is empty and all non-boundary |
| 440 | text is concatenated into ``system_text`` — byte-for-byte the prior |
| 441 | behaviour. |
| 442 | """ |
| 443 | from ..context_system.cache_boundary import SYSTEM_PROMPT_DYNAMIC_BOUNDARY |
| 444 | |
| 445 | stable: list[str] = [] |
| 446 | volatile: list[str] = [] |
| 447 | for blk in blocks: |
| 448 | if not isinstance(blk, dict): |
| 449 | continue |
| 450 | text = blk.get("text") |
| 451 | if not text or text == SYSTEM_PROMPT_DYNAMIC_BOUNDARY: |
| 452 | continue |
| 453 | if relocate_request_scope and blk.get("_cache_scope") == "request": |
| 454 | volatile.append(str(text)) |
| 455 | else: |
| 456 | stable.append(str(text)) |
| 457 | return "\n\n".join(stable), "\n\n".join(volatile) |
| 458 | |
| 459 | |
| 460 | def _append_session_context_tail( |