88 lines
3.5 KiB
Python
88 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Unit tests for the OpenCode built-in provider.
|
|
|
|
After review feedback: OPENCODE_MODELS reduced to 8 intersection models
|
|
(Zen ∩ Go), endpoint filtering removed for minimal diff.
|
|
"""
|
|
|
|
from pineagents.providers.provider_manager import (
|
|
OPENCODE_MODELS,
|
|
PROVIDER_OPENCODE,
|
|
ProviderManager,
|
|
)
|
|
from pineagents.providers.openai_provider import OpenAIProvider
|
|
|
|
|
|
class TestOpenCodeProvider:
|
|
"""Test the OpenCode provider with merged OpenCode Go models."""
|
|
|
|
def test_opencode_provider_is_openai_compatible(self):
|
|
"""PROVIDER_OPENCODE should be an OpenAIProvider."""
|
|
assert isinstance(PROVIDER_OPENCODE, OpenAIProvider)
|
|
|
|
def test_opencode_provider_key_attributes(self):
|
|
"""Provider-level attributes should be correctly set."""
|
|
assert PROVIDER_OPENCODE.id == "opencode"
|
|
assert PROVIDER_OPENCODE.api_key_prefix == ""
|
|
assert PROVIDER_OPENCODE.require_api_key is False
|
|
assert PROVIDER_OPENCODE.freeze_url is False
|
|
assert PROVIDER_OPENCODE.base_url == "https://opencode.ai/zen/v1"
|
|
assert (
|
|
PROVIDER_OPENCODE.base_url
|
|
== PROVIDER_OPENCODE.meta["base_url_options"][0]["value"]
|
|
)
|
|
|
|
def test_opencode_provider_meta_base_url_options(self):
|
|
"""meta should contain two base_url_options for endpoint switching."""
|
|
meta = PROVIDER_OPENCODE.meta
|
|
assert "base_url_options" in meta
|
|
urls = meta["base_url_options"]
|
|
assert len(urls) == 2
|
|
assert urls[0]["label"] == "OpenCode"
|
|
assert urls[0]["value"] == "https://opencode.ai/zen/v1"
|
|
assert urls[1]["label"] == "OpenCode Go"
|
|
assert urls[1]["value"] == "https://opencode.ai/zen/go/v1"
|
|
|
|
def test_opencode_models_non_empty_and_unique(self):
|
|
"""Models list is non-empty with unique IDs."""
|
|
assert len(OPENCODE_MODELS) > 0
|
|
model_ids = [m.id for m in OPENCODE_MODELS]
|
|
assert len(model_ids) == len(set(model_ids))
|
|
|
|
def test_opencode_models_have_required_fields(self):
|
|
"""Every model has required fields set."""
|
|
for m in OPENCODE_MODELS:
|
|
assert m.id, "Model must have an id"
|
|
assert m.name, "Model must have a name"
|
|
assert isinstance(m.supports_image, bool)
|
|
assert isinstance(m.supports_video, bool)
|
|
|
|
def test_opencode_models_probe_source(self):
|
|
"""All models should have probe_source='documentation'."""
|
|
for m in OPENCODE_MODELS:
|
|
assert m.probe_source == "documentation"
|
|
|
|
def test_opencode_models_all_free(self):
|
|
"""All OpenCode models should be marked as free."""
|
|
assert all(
|
|
m.is_free for m in OPENCODE_MODELS
|
|
), "All OPENCODE_MODELS should be free"
|
|
|
|
def test_opencode_registered_in_provider_manager(self):
|
|
"""opencode provider should be registerable via built-in init."""
|
|
mgr = ProviderManager()
|
|
assert PROVIDER_OPENCODE.id in mgr.builtin_providers
|
|
provider = mgr.builtin_providers[PROVIDER_OPENCODE.id]
|
|
assert provider.id == PROVIDER_OPENCODE.id
|
|
assert isinstance(provider, OpenAIProvider)
|
|
|
|
def test_get_info_returns_all_models(self):
|
|
"""get_info() should return all 8 intersection models."""
|
|
import asyncio
|
|
|
|
provider = PROVIDER_OPENCODE.model_copy()
|
|
info = asyncio.run(provider.get_info())
|
|
assert len(info.models) == len(OPENCODE_MODELS)
|
|
model_ids = {m.id for m in info.models}
|
|
assert model_ids == {m.id for m in OPENCODE_MODELS}
|