Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
"""Regression test: the MoA aggregator's one-shot synthesis call
|
||||
(``aggregate_moa_context``, used by the ``/moa <prompt>`` command) must get
|
||||
the same Anthropic-style prompt-caching decoration as the acting-aggregator
|
||||
turn (``MoAChatCompletions.create``) and the advisor fan-out
|
||||
(``_run_reference``).
|
||||
|
||||
22c5048d9 ("fix(moa): restore prompt caching for the aggregator and
|
||||
advisors") fixed the other two MoA call paths but never touched
|
||||
``aggregate_moa_context`` — a third, independent call path with its own
|
||||
``call_llm(task="moa_aggregator", ...)`` invocation. Without this fix, every
|
||||
``/moa <prompt>`` one-shot call re-bills its full input (system-less prompt
|
||||
containing all joined reference outputs) with zero cache_control breakpoints,
|
||||
even when the resolved aggregator slot is a cache-honoring route.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def _response(content="synthesized guidance"):
|
||||
message = SimpleNamespace(content=content, tool_calls=[])
|
||||
choice = SimpleNamespace(message=message, finish_reason="stop")
|
||||
return SimpleNamespace(choices=[choice], usage=None, model="fake")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def captured_calls(monkeypatch):
|
||||
calls = []
|
||||
|
||||
def fake_call_llm(**kwargs):
|
||||
calls.append(kwargs)
|
||||
return _response()
|
||||
|
||||
monkeypatch.setattr("agent.moa_loop.call_llm", fake_call_llm)
|
||||
monkeypatch.setattr(
|
||||
"agent.moa_loop._run_references_parallel",
|
||||
lambda *a, **k: [("advisor-a", "advice from a", None)],
|
||||
)
|
||||
return calls
|
||||
|
||||
|
||||
def _aggregator_kwargs(calls):
|
||||
return next(c for c in calls if c.get("task") == "moa_aggregator")
|
||||
|
||||
|
||||
def test_aggregator_synthesis_gets_cache_control_on_native_anthropic_route(
|
||||
captured_calls, monkeypatch
|
||||
):
|
||||
"""A cache-honoring aggregator slot (native Anthropic) must get
|
||||
cache_control breakpoints on its synthesis call."""
|
||||
from agent import moa_loop
|
||||
|
||||
monkeypatch.setattr(
|
||||
moa_loop,
|
||||
"_slot_runtime",
|
||||
lambda slot: {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-opus-4.8",
|
||||
"base_url": "",
|
||||
"api_mode": "anthropic_messages",
|
||||
},
|
||||
)
|
||||
|
||||
moa_loop.aggregate_moa_context(
|
||||
user_prompt="what should I do next?",
|
||||
api_messages=[{"role": "user", "content": "help me plan"}],
|
||||
reference_models=[{"provider": "openrouter", "model": "openai/gpt-5.5"}],
|
||||
aggregator={"provider": "anthropic", "model": "claude-opus-4.8"},
|
||||
)
|
||||
|
||||
agg_kwargs = _aggregator_kwargs(captured_calls)
|
||||
synth_message = agg_kwargs["messages"][0]
|
||||
assert synth_message["role"] == "user"
|
||||
content = synth_message["content"]
|
||||
# Native Anthropic layout places cache_control on inner content blocks,
|
||||
# so a cached message's content is a list of blocks rather than a bare
|
||||
# string once decorated.
|
||||
assert isinstance(content, list), "expected native cache_control block layout"
|
||||
assert any(
|
||||
isinstance(block, dict) and "cache_control" in block for block in content
|
||||
), "aggregator synthesis message must carry a cache_control breakpoint"
|
||||
|
||||
|
||||
def test_aggregator_synthesis_untouched_on_non_caching_route(
|
||||
captured_calls, monkeypatch
|
||||
):
|
||||
"""A non-cache-honoring aggregator slot (plain OpenAI) must not be
|
||||
decorated — proves the guard doesn't over-fire."""
|
||||
from agent import moa_loop
|
||||
|
||||
monkeypatch.setattr(
|
||||
moa_loop,
|
||||
"_slot_runtime",
|
||||
lambda slot: {
|
||||
"provider": "openai",
|
||||
"model": "gpt-5.5",
|
||||
"base_url": "",
|
||||
"api_mode": "chat_completions",
|
||||
},
|
||||
)
|
||||
|
||||
moa_loop.aggregate_moa_context(
|
||||
user_prompt="what should I do next?",
|
||||
api_messages=[{"role": "user", "content": "help me plan"}],
|
||||
reference_models=[{"provider": "openrouter", "model": "openai/gpt-5.5"}],
|
||||
aggregator={"provider": "openai", "model": "gpt-5.5"},
|
||||
)
|
||||
|
||||
agg_kwargs = _aggregator_kwargs(captured_calls)
|
||||
synth_message = agg_kwargs["messages"][0]
|
||||
assert isinstance(synth_message["content"], str), "must stay undecorated (plain string content)"
|
||||
|
||||
|
||||
def test_prepared_aggregator_plans_tools_without_decorating_prepared_state(monkeypatch):
|
||||
from agent import moa_loop
|
||||
|
||||
calls = []
|
||||
monkeypatch.setattr(moa_loop, "call_llm", lambda **kwargs: calls.append(kwargs) or _response())
|
||||
monkeypatch.setattr(
|
||||
moa_loop,
|
||||
"_slot_runtime",
|
||||
lambda slot: {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-4-6",
|
||||
"base_url": "https://api.anthropic.com",
|
||||
"api_mode": "anthropic_messages",
|
||||
},
|
||||
)
|
||||
completions = moa_loop.MoAChatCompletions.__new__(moa_loop.MoAChatCompletions)
|
||||
completions._pending_trace = None
|
||||
prepared = {
|
||||
"messages": [
|
||||
{"role": "system", "content": "system"},
|
||||
{"role": "user", "content": "lookup"},
|
||||
{"role": "assistant", "content": "", "tool_calls": [{"id": "lookup", "function": {"name": "lookup", "arguments": "{}"}}]},
|
||||
{"role": "tool", "tool_call_id": "lookup", "content": "result"},
|
||||
],
|
||||
"guidance": None,
|
||||
"aggregator": {"provider": "anthropic", "model": "claude-sonnet-4-6"},
|
||||
"aggregator_temperature": None,
|
||||
}
|
||||
canonical_prepared = copy.deepcopy(prepared)
|
||||
tools = [{"type": "function", "function": {"name": "lookup", "parameters": {"type": "object", "properties": {}}}}]
|
||||
|
||||
completions._call_prepared_aggregator(prepared, {"tools": tools})
|
||||
|
||||
assert "cache_control" in calls[0]["tools"][-1]
|
||||
assert "cache_control" not in tools[-1]
|
||||
assert prepared == canonical_prepared
|
||||
Reference in New Issue
Block a user