Move turn completion instructions to system_instruction
Turn completion instructions were being injected as a system message in the LLM context, which caused warning spam when system_instruction was also set, did not persist across full context updates, and broke LLMs that do not support consecutive system messages. Instead, compose the turn completion instructions into the LLM service system_instruction field. This is managed via _base_system_instruction which stores the original value for restoration when turn completion is disabled.
This commit is contained in:
@@ -565,9 +565,6 @@ class LLMUserAggregator(LLMContextAggregator):
|
||||
)
|
||||
)
|
||||
|
||||
# Auto-inject turn completion instructions into context
|
||||
self._context.add_message({"role": "system", "content": config.completion_instructions})
|
||||
|
||||
async def _stop(self, frame: EndFrame):
|
||||
await self._maybe_emit_user_turn_stopped(on_session_end=True)
|
||||
await self._cleanup()
|
||||
@@ -636,9 +633,6 @@ class LLMUserAggregator(LLMContextAggregator):
|
||||
|
||||
async def _handle_llm_messages_update(self, frame: LLMMessagesUpdateFrame):
|
||||
self.set_messages(frame.messages)
|
||||
if self._params.filter_incomplete_user_turns:
|
||||
config = self._params.user_turn_completion_config or UserTurnCompletionConfig()
|
||||
self._context.add_message({"role": "system", "content": config.completion_instructions})
|
||||
if frame.run_llm:
|
||||
await self.push_context_frame()
|
||||
|
||||
|
||||
@@ -212,6 +212,7 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService):
|
||||
self._run_in_parallel = run_in_parallel
|
||||
self._function_call_timeout_secs = function_call_timeout_secs
|
||||
self._filter_incomplete_user_turns: bool = False
|
||||
self._base_system_instruction: Optional[str] = None
|
||||
self._start_callbacks = {}
|
||||
self._adapter = self.adapter_class()
|
||||
self._functions: Dict[Optional[str], FunctionCallRegistryItem] = {}
|
||||
@@ -326,6 +327,19 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService):
|
||||
await self._cancel_sequential_runner_task()
|
||||
await self._cancel_summary_task()
|
||||
|
||||
def _compose_system_instruction(self):
|
||||
"""Compose system_instruction by appending turn completion instructions.
|
||||
|
||||
Combines the base system instruction with turn completion instructions
|
||||
and writes the result to ``self._settings.system_instruction``.
|
||||
"""
|
||||
base = self._base_system_instruction
|
||||
completion_instructions = self._user_turn_completion_config.completion_instructions
|
||||
if base:
|
||||
self._settings.system_instruction = f"{base}\n\n{completion_instructions}"
|
||||
else:
|
||||
self._settings.system_instruction = completion_instructions
|
||||
|
||||
async def _update_settings(self, delta: LLMSettings) -> dict[str, Any]:
|
||||
"""Apply a settings delta, handling turn-completion fields.
|
||||
|
||||
@@ -345,9 +359,28 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService):
|
||||
f"{self}: Incomplete turn filtering "
|
||||
f"{'enabled' if self._filter_incomplete_user_turns else 'disabled'}"
|
||||
)
|
||||
if self._filter_incomplete_user_turns:
|
||||
# Save the current system_instruction before composing
|
||||
self._base_system_instruction = self._settings.system_instruction
|
||||
self._compose_system_instruction()
|
||||
else:
|
||||
# Restore original system_instruction
|
||||
self._settings.system_instruction = self._base_system_instruction
|
||||
self._base_system_instruction = None
|
||||
|
||||
if "user_turn_completion_config" in changed and self._filter_incomplete_user_turns:
|
||||
self.set_user_turn_completion_config(self._settings.user_turn_completion_config)
|
||||
self._compose_system_instruction()
|
||||
|
||||
if (
|
||||
"system_instruction" in changed
|
||||
and self._filter_incomplete_user_turns
|
||||
and "filter_incomplete_user_turns" not in changed
|
||||
):
|
||||
# system_instruction changed while turn completion is active.
|
||||
# Treat the new value as the new base and recompose.
|
||||
self._base_system_instruction = self._settings.system_instruction
|
||||
self._compose_system_instruction()
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user