from src.agent_loop import ( _streamed_tool_markup_complete, _streamed_tool_markup_starts, _strip_incomplete_tool_markup_tail, ) from src.tool_parsing import strip_tool_blocks def test_dsml_tool_markup_is_complete_only_after_closing_tag(): start = "<||DSML||tool_calls><||DSML||invoke name=\"host_shell\">" assert not _streamed_tool_markup_complete(start) assert _streamed_tool_markup_complete(start + "") def test_dsml_tool_markup_strips_to_empty_visible_text(): markup = ( "<||DSML||tool_calls>" "<||DSML||invoke name=\"host_shell\">" "<||DSML||parameter name=\"command\" string=\"true\">pwd" "" "" "" ) assert strip_tool_blocks(markup, skip_fenced=True) == "" def test_chunk_split_tool_call_prefix_is_buffered_and_not_persisted(): assert _streamed_tool_markup_starts('I will search" assert _streamed_tool_markup_starts(' <') assert _streamed_tool_markup_starts('x <') assert _streamed_tool_markup_starts('{"name":"host_shell","arguments":{"command":"pwd"}}', "", " done", ] for c in chunks: yield "data: " + json.dumps({"delta": c}) + "\n\n" yield "data: [DONE]\n\n" monkeypatch.setattr(al, "get_setting", lambda k, d=None: d, raising=False) monkeypatch.setattr(al, "get_mcp_manager", lambda: None, raising=False) monkeypatch.setattr(al, "estimate_tokens", lambda *a, **k: 10, raising=False) monkeypatch.setattr(al, "stream_llm_with_fallback", fake_stream, raising=False) deltas = [] async for chunk in al.stream_agent_loop( "http://local.test/v1", "qwen3.6-35b-a3b-heretic", [{"role": "user", "content": "run command"}], max_rounds=1, owner="test_user", ): for line in chunk.split("\n"): line = line.strip() if line.startswith("data: ") and line[6:] != "[DONE]": try: payload = json.loads(line[6:]) if "delta" in payload: deltas.append(payload["delta"]) except Exception: pass assert "".join(deltas) == "Sure. done"