Skip to content
This repository was archived by the owner on Mar 19, 2026. It is now read-only.

Commit 80fca97

Browse files
authored
Merge pull request #355 from PrefectHQ/system-messages
Add compilation flag for removing all system messages
2 parents af51a90 + 1cc4986 commit 80fca97

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

src/controlflow/events/message_compiler.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,25 @@ def convert_system_messages(
113113
messages: list[BaseMessage], rules: LLMRules
114114
) -> list[BaseMessage]:
115115
"""
116-
Converts system messages to human messages if the LLM doesnt support system messages.
116+
Converts system messages to human messages if the LLM doesnt support system
117+
messages, either at all or in the first position.
117118
"""
118-
if not messages or not rules.require_system_message_first:
119-
return messages
120-
121119
new_messages = []
122-
for message in messages:
120+
for i, message in enumerate(messages):
123121
if isinstance(message, SystemMessage):
124-
new_messages.append(
125-
HumanMessage(
126-
content=f"ORCHESTRATOR: {message.content}", name=message.name
122+
# If system messages are not supported OR if they must be first and
123+
# this is not the first message, THEN convert the message to a human message
124+
if not rules.allow_system_messages or (
125+
i > 0 and rules.require_system_message_first
126+
):
127+
new_messages.append(
128+
HumanMessage(
129+
content=f"ORCHESTRATOR: {message.content}", name=message.name
130+
)
127131
)
128-
)
132+
else:
133+
# If the system message is allowed, add it as-is
134+
new_messages.append(message)
129135
else:
130136
new_messages.append(message)
131137
return new_messages
@@ -249,7 +255,9 @@ def compile_to_messages(self, agent: "Agent") -> list[BaseMessage]:
249255
messages = break_up_consecutive_ai_messages(messages, rules=context.llm_rules)
250256
messages = format_message_name(messages, rules=context.llm_rules)
251257

258+
messages = system_prompt + messages
259+
252260
# this should go last
253261
messages = convert_system_messages(messages, rules=context.llm_rules)
254262

255-
return system_prompt + messages
263+
return messages

src/controlflow/llm/rules.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class LLMRules(ControlFlowModel):
2222
# require at least one non-system message
2323
require_at_least_one_message: bool = False
2424

25+
# system messages are supported as a role
26+
allow_system_messages: bool = True
27+
2528
# system messages can only be provided as the very first message in a thread
2629
require_system_message_first: bool = False
2730

tests/test_run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_min_failed(self):
9393
task2 = Task("Task 2")
9494
task3 = Task("Task 3")
9595

96-
with instructions("fail tasks 1 and 3"):
96+
with instructions("fail tasks 1 and 3. Don't work on task 2."):
9797
run_tasks(
9898
[task1, task2, task3],
9999
run_until=AnyFailed(min_failed=2),
@@ -157,7 +157,7 @@ async def test_min_failed(self):
157157
task2 = Task("Task 2")
158158
task3 = Task("Task 3")
159159

160-
with instructions("fail tasks 1 and 3"):
160+
with instructions("fail tasks 1 and 3. Don't work on task 2."):
161161
await run_tasks_async(
162162
[task1, task2, task3],
163163
run_until=AnyFailed(min_failed=2),

0 commit comments

Comments
 (0)