Download Code-agent-main/tests/test_local_provider.py from Yazhiniyan/YCode: direct link, hf CLI and curl.
- Browser
- Download file 6.47 kB
-
https://huggingface.co/Yazhiniyan/YCode/resolve/main/Code-agent-main/tests/test_local_provider.py
- Command line
-
hf download hf://Yazhiniyan/YCode/Code-agent-main/tests/test_local_provider.py
-
curl -L -o test_local_provider.py https://huggingface.co/Yazhiniyan/YCode/resolve/main/Code-agent-main/tests/test_local_provider.py
6.47 kB
| import pytest | |
| from ycode.config import Config | |
| from ycode.errors import ConfigError | |
| from ycode.llm import create_provider | |
| from ycode.llm.base import AssistantMessage, StopReason, StreamCallbacks, ToolResultBlock, ToolResultsMessage, UserMessage | |
| from ycode.llm.local import LocalProvider | |
| class FakeLM: | |
| num_params = 7_000_000 | |
| def __init__(self, answer="Use `sorted(items)`."): | |
| self.answer = answer | |
| self.calls = [] | |
| def chat(self, turns, *, max_new_tokens, temperature, on_text=None): | |
| self.calls.append(turns) | |
| if on_text: | |
| on_text(self.answer) | |
| return self.answer | |
| def test_local_provider_answers_without_tools(tmp_path): | |
| lm = FakeLM() | |
| provider = LocalProvider(tmp_path, lm=lm) | |
| streamed = [] | |
| response = provider.complete( | |
| system="ignored", | |
| messages=[ | |
| UserMessage("first question"), | |
| AssistantMessage("first answer", provider="local"), | |
| ToolResultsMessage([ToolResultBlock("x", "tool output")]), | |
| UserMessage("[Note: the user interrupted the previous request before it finished.]\n\nhow to sort?"), | |
| ], | |
| tools=[], | |
| callbacks=StreamCallbacks(on_text=streamed.append), | |
| ) | |
| assert response.stop_reason is StopReason.END_TURN | |
| assert response.message.text == lm.answer and response.message.tool_calls == [] | |
| assert "".join(streamed) == lm.answer | |
| assert lm.calls[0] == [("user", "first question"), ("assistant", "first answer"), ("user", "how to sort?")] | |
| assert provider.supports_tools is False | |
| assert "7.0M params" in provider.display_name | |
| def test_empty_answer_gets_placeholder(tmp_path): | |
| response = LocalProvider(tmp_path, lm=FakeLM("")).complete(system="", messages=[UserMessage("x")], tools=[]) | |
| assert "did not produce an answer" in response.message.text | |
| def test_missing_local_model_is_a_clear_error(tmp_path): | |
| pytest.importorskip("torch") | |
| with pytest.raises(ConfigError) as info: | |
| create_provider(Config(provider="local", local_model=str(tmp_path / "none"))) | |
| assert "No model found" in str(info.value) and "v4" in info.value.hint # lists the bundled models | |
| def test_no_api_key_needed_for_local(tmp_path, monkeypatch): | |
| import ycode.llm.local as local | |
| monkeypatch.setattr(local.LocalProvider, "_load", lambda self, device: FakeLM()) | |
| provider = create_provider(Config(provider="local", local_model=str(tmp_path))) | |
| assert isinstance(provider, LocalProvider) and provider.model_dir == tmp_path | |
| def test_config_validation_for_local(workspace): | |
| from ycode.config import load_config | |
| cfg = load_config(workspace, env={"YCODE_PROVIDER": "local", "YCODE_LOCAL_MODEL": "/models/mine"}) | |
| assert cfg.provider == "local" and cfg.local_model == "/models/mine" | |
| with pytest.raises(ConfigError): | |
| load_config(workspace, env={"YCODE_PROVIDER": "openai"}) | |
| def test_cli_local_flag_runs_task_without_api_key(workspace, monkeypatch, capsys): | |
| import ycode.llm.local as local | |
| from ycode import cli | |
| monkeypatch.setattr(local.LocalProvider, "_load", lambda self, device: FakeLM("def add(a, b): return a + b")) | |
| code = cli.main(["-C", str(workspace), "--local", str(workspace / "m"), "write add"]) | |
| out = capsys.readouterr().out | |
| assert code == 0 | |
| assert "answer-only mode" in out and "def add(a, b)" in out and "YCode-LM" in out | |
| def test_agent_sends_no_tools_to_local_provider(workspace, make_ctx, tmp_path): | |
| from ycode.agent.loop import Agent | |
| from ycode.tools import ToolRegistry, default_tools | |
| seen = {} | |
| class Recorder(LocalProvider): | |
| def complete(self, *, system, messages, tools, callbacks=None): | |
| seen["tools"] = tools | |
| return super().complete(system=system, messages=messages, tools=tools, callbacks=callbacks) | |
| agent = Agent(provider=Recorder(tmp_path, lm=FakeLM()), registry=ToolRegistry(default_tools()), | |
| tool_context=make_ctx(workspace), system_prompt="s") | |
| agent.run("hi") | |
| assert seen["tools"] == [] | |
| def test_resolve_local_model(tmp_path, monkeypatch, isolated_home): | |
| import ycode.config as config | |
| from ycode.config import DEFAULT_BUNDLED_MODEL, bundled_models, resolve_local_model | |
| monkeypatch.setenv("YCODE_MODELS_DIR", str(tmp_path / "bundled")) | |
| monkeypatch.setattr(config, "available_memory_gb", lambda: 16.0) | |
| for name in ("ycode-lm-v4", "ycode-lm-v5"): | |
| (tmp_path / "bundled" / name).mkdir(parents=True) | |
| (tmp_path / "bundled" / name / "model.pt").write_bytes(b"") | |
| assert bundled_models() == ["ycode-lm-v4", "ycode-lm-v5"] | |
| assert DEFAULT_BUNDLED_MODEL == "ycode-lm-v5" # v5 is the deployed default | |
| assert resolve_local_model("") == tmp_path / "bundled" / DEFAULT_BUNDLED_MODEL | |
| monkeypatch.setattr(config, "available_memory_gb", lambda: 2.0) # small machine: falls back to v4 | |
| assert resolve_local_model("") == tmp_path / "bundled" / "ycode-lm-v4" | |
| monkeypatch.setattr(config, "available_memory_gb", lambda: 16.0) | |
| assert resolve_local_model("v5") == tmp_path / "bundled" / "ycode-lm-v5" | |
| assert resolve_local_model("ycode-lm-v5") == tmp_path / "bundled" / "ycode-lm-v5" | |
| assert resolve_local_model(str(tmp_path / "mine")) == tmp_path / "mine" | |
| own = isolated_home / "models" / "ycode-lm" # a model you trained yourself wins over the bundled one | |
| own.mkdir(parents=True) | |
| (own / "model.pt").write_bytes(b"") | |
| assert resolve_local_model("") == own | |
| def test_repository_ships_the_default_model(): | |
| from ycode.config import DEFAULT_BUNDLED_MODEL, bundled_models | |
| assert DEFAULT_BUNDLED_MODEL in bundled_models() | |
| def test_claude_is_optional(monkeypatch): | |
| """Without the anthropic package, only an explicit --provider anthropic mentions Claude.""" | |
| import builtins as b | |
| import sys | |
| real_import = b.__import__ | |
| def no_anthropic(name, *args, **kwargs): | |
| if name == "anthropic" or name.startswith("anthropic."): | |
| raise ImportError("No module named 'anthropic'") | |
| return real_import(name, *args, **kwargs) | |
| monkeypatch.delitem(sys.modules, "ycode.llm.anthropic", raising=False) | |
| monkeypatch.delitem(sys.modules, "anthropic", raising=False) | |
| monkeypatch.setattr(b, "__import__", no_anthropic) | |
| with pytest.raises(ConfigError) as info: | |
| create_provider(Config(provider="anthropic")) | |
| assert "not installed" in str(info.value) and ".[claude]" in info.value.hint | |