mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-18 12:52:20 +02:00
drop invalid empty assistant placeholders at provider boundary
This commit is contained in:
@@ -3733,6 +3733,25 @@ def provider_request_messages(messages):
|
|||||||
return cleaned
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
|
def provider_wire_messages(messages):
|
||||||
|
"""Drop invalid placeholders only at the provider serialization boundary."""
|
||||||
|
cleaned = []
|
||||||
|
for item in provider_request_messages(messages):
|
||||||
|
item.pop('_harness_control', None)
|
||||||
|
# A reasoning-only/contentless model turn may be followed by a
|
||||||
|
# harness-owned completion recovery. Persisting that empty assistant
|
||||||
|
# placeholder makes strict OpenAI-compatible providers reject the next
|
||||||
|
# request because neither content nor tool_calls is present.
|
||||||
|
if (
|
||||||
|
item.get('role') == 'assistant'
|
||||||
|
and not item.get('content')
|
||||||
|
and not item.get('tool_calls')
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
cleaned.append(item)
|
||||||
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
def record_tool_execution(executions, tool_event):
|
def record_tool_execution(executions, tool_event):
|
||||||
"""Persist one latest browser preview while live events can show every step."""
|
"""Persist one latest browser preview while live events can show every step."""
|
||||||
if canonical(tool_event.get('tool', '')) == 'private_browser' and tool_event.get('screenshot'):
|
if canonical(tool_event.get('tool', '')) == 'private_browser' and tool_event.get('screenshot'):
|
||||||
@@ -3765,10 +3784,10 @@ async def preview_model_response(client, endpoint_url, headers, request, recover
|
|||||||
request['messages'], max(1, int(message_context * recovery.get('scale', 1))),
|
request['messages'], max(1, int(message_context * recovery.get('scale', 1))),
|
||||||
reserve_tokens=request['max_tokens'] + context_safety_margin(limit))
|
reserve_tokens=request['max_tokens'] + context_safety_margin(limit))
|
||||||
# Server-only provenance guides trimming, not the model's wire schema.
|
# Server-only provenance guides trimming, not the model's wire schema.
|
||||||
provider_request = {**request, 'messages': [
|
provider_request = {
|
||||||
{key: value for key, value in message.items() if key != '_harness_control'}
|
**request,
|
||||||
for message in request['messages']
|
'messages': provider_wire_messages(request['messages']),
|
||||||
]}
|
}
|
||||||
response_started = False
|
response_started = False
|
||||||
try:
|
try:
|
||||||
async with client.stream(
|
async with client.stream(
|
||||||
|
|||||||
@@ -85,6 +85,18 @@ def test_provider_request_messages_strips_internal_metadata_without_mutating_his
|
|||||||
assert history[0]['metadata']['trusted'] is False
|
assert history[0]['metadata']['trusted'] is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_provider_wire_messages_drops_empty_assistant_placeholder():
|
||||||
|
from src.clean_agent_preview import provider_wire_messages
|
||||||
|
|
||||||
|
history = [
|
||||||
|
{'role': 'assistant', 'content': None},
|
||||||
|
{'role': 'user', 'content': 'Completion check: create the artifact.'},
|
||||||
|
]
|
||||||
|
|
||||||
|
assert provider_request_messages(history) == history
|
||||||
|
assert provider_wire_messages(history) == [history[1]]
|
||||||
|
|
||||||
|
|
||||||
def test_private_browser_observations_do_not_advance_page_revision():
|
def test_private_browser_observations_do_not_advance_page_revision():
|
||||||
assert private_browser_state_transition({'action': 'snapshot'}, 'https://example.org') == (
|
assert private_browser_state_transition({'action': 'snapshot'}, 'https://example.org') == (
|
||||||
False, 'https://example.org')
|
False, 'https://example.org')
|
||||||
|
|||||||
Reference in New Issue
Block a user