fix: improve cross-device evidence, request diagnostics and prompt efficiency

This commit is contained in:
chenmingxuan committed 2026-10-17 14:55:45 +08:00
1 parent 621f30e437
commit a66803651a
60 files changed
+3097 -160

No files matched your search

+56 -9
View File
@@ -40,9 +40,9 @@ def text_output(text):
@pytest.fixture
def transport_model(monkeypatch):
import langchain_openai
from langchain_openai import ChatOpenAI
import openai
original = langchain_openai.ChatOpenAI
requests = []
outputs = []
@@ -52,16 +52,16 @@ def transport_model(monkeypatch):
200, json=response_body(outputs.pop(0) if outputs else text_output("OK"))
)
client = httpx.AsyncClient(transport=httpx.MockTransport(handle))
monkeypatch.setattr(
langchain_openai,
"ChatOpenAI",
lambda **kwargs: original(**kwargs, http_async_client=client),
openai,
"DefaultAsyncHttpxClient",
lambda **kwargs: httpx.AsyncClient(transport=httpx.MockTransport(handle), **kwargs),
)
monkeypatch.setattr(settings, "OPENAI_API_KEY", SecretStr("test-secret"))
monkeypatch.setattr(settings, "OPENAI_BASE_URL", "https://responses.example/v1")
monkeypatch.delenv("ARTEMIS_FAKE_LLM", raising=False)
model = ModelFactory.create_model(ModelEndpoint(model_name="test-model", timeout_seconds=23))
assert isinstance(model, ChatOpenAI)
return model, requests, outputs
@@ -284,7 +284,10 @@ def test_video_text_fallback_extracts_responses_blocks():
@pytest.mark.asyncio
async def test_wrapper_structured_output_uses_responses_function_call(transport_model):
@pytest.mark.parametrize("mode", ["parsed", "raw", "pipeline"])
async def test_wrapper_structured_output_uses_responses_function_call(
transport_model, monkeypatch, mode
):
class Verdict(BaseModel):
ok: bool
@@ -302,9 +305,53 @@ async def test_wrapper_structured_output_uses_responses_function_call(transport_
]
)
wrapper = RobustChatModelWrapper(model, endpoint=ModelEndpoint(model_name="test-model"))
result = await wrapper.with_structured_output(Verdict).ainvoke("Check")
assert result.ok is True
metered = []
monkeypatch.setattr(
"artemis.services.llm.record_llm_usage",
lambda engine, response, **kw: metered.append(response),
)
structured = wrapper.with_structured_output(Verdict, include_raw=mode == "raw")
if mode == "pipeline":
from langchain_core.runnables import RunnableLambda
result = await (structured | RunnableLambda(lambda value: value.ok)).ainvoke("Check")
assert result is True
else:
result = await structured.complete("Check")
assert (result["parsed"] if mode == "raw" else result).ok is True
if mode == "raw":
assert result["parsing_error"] is None
assert result["raw"].tool_calls
payload = json.loads(requests[0].content)
assert requests[0].url.path == "/v1/responses"
assert payload["tools"][0]["name"] == "Verdict"
assert payload.get("text", {}).get("format", {}).get("type") != "json_schema"
from artemis.llm.usage import usage_from_message
assert len(metered) == 1
assert usage_from_message(metered[0])["total_tokens"] == 13
@pytest.mark.asyncio
async def test_cache_key_is_stable_for_exploration_but_separates_roles(
transport_model, monkeypatch
):
from types import SimpleNamespace
model, requests, _ = transport_model
engine = SimpleNamespace(current_session_id="run-1")
ctx = SimpleNamespace(data_engine=engine, exploration_id="exploration-1")
monkeypatch.setattr("artemis.services.llm.record_llm_usage", lambda *a, **k: None)
wrapper = RobustChatModelWrapper(
model, ctx, endpoint=ModelEndpoint(model_name="test-model"), role="operator"
)
await wrapper.ainvoke([HumanMessage(content="first")])
engine.current_session_id = "resumed-run-2"
await wrapper.ainvoke([HumanMessage(content="first"), HumanMessage(content="next")])
wrapper.role = "checker"
await wrapper.ainvoke([HumanMessage(content="verify")])
payloads = [json.loads(r.content) for r in requests]
assert payloads[0]["prompt_cache_key"] == payloads[1]["prompt_cache_key"]
assert payloads[1]["prompt_cache_key"] != payloads[2]["prompt_cache_key"]
assert "exploration-1" not in payloads[0]["prompt_cache_key"]
assert payloads[1]["input"][:1] == payloads[0]["input"]