Spaces:
Runtime error
Runtime error
feat(llm): local Ollama provider (ollama_local, no auth) + scenario-neutral agent directive + gpt-oss model toggle
78a6863 | """Build an :class:`LLMProvider` from a ``"name:model"`` spec string. | |
| Spec format: ``"<provider>:<model>"`` — e.g. ``"anthropic:claude-haiku-4-5"``, | |
| ``"openai:gpt-4o-mini"``, ``"gemini:gemini-2.0-flash"``, | |
| ``"ollama:qwen3.5:cloud"``, ``"fake:smoke"``. Only the FIRST ``:`` separates the | |
| provider name from the model id (model ids may themselves contain ``:``). | |
| Real providers are imported LAZILY (only when their spec is requested), so | |
| importing this module — or building a ``FakeProvider`` — never requires the | |
| heavy provider SDKs (openai / anthropic / google-genai / httpx) to be | |
| installed. This keeps the offline test suite dependency-free. | |
| """ | |
| from __future__ import annotations | |
| import importlib | |
| from proteus.providers.base import LLMProvider | |
| from proteus.providers.fake import FakeProvider | |
| # Provider name -> (module path, class name). Imported lazily in make_provider. | |
| _REGISTRY: dict[str, tuple[str, str]] = { | |
| "openai": ("proteus.providers.openai", "OpenAIProvider"), | |
| "anthropic": ("proteus.providers.anthropic_provider", "AnthropicProvider"), | |
| "gemini": ("proteus.providers.gemini", "GeminiProvider"), | |
| "ollama": ("proteus.providers.ollama_cloud", "OllamaCloudProvider"), | |
| "ollama_local": ("proteus.providers.ollama_local", "OllamaLocalProvider"), | |
| } | |
| # The canned action a CLI ``fake:`` provider replays each turn (offline smoke). | |
| _FAKE_DEFAULT_RESPONSE = "ACTION: stay" | |
| def available_providers() -> list[str]: | |
| """Return the sorted list of provider names accepted by :func:`make_provider`.""" | |
| return sorted([*_REGISTRY, "fake"]) | |
| def make_provider(spec: str) -> LLMProvider: | |
| """Build a provider from a ``"<name>:<model>"`` spec. | |
| Args: | |
| spec: ``"<provider>:<model>"``. ``fake:<anything>`` yields an offline | |
| :class:`FakeProvider`. Real providers are imported lazily. | |
| Returns: | |
| A concrete :class:`LLMProvider`. | |
| Raises: | |
| ValueError: If the spec has no ``:`` separator, or names an unknown | |
| provider. | |
| """ | |
| name, sep, model = spec.partition(":") | |
| if not sep: | |
| raise ValueError( | |
| f"Provider spec must be '<name>:<model>', got {spec!r}. " | |
| f"Available providers: {', '.join(available_providers())}." | |
| ) | |
| if name == "fake": | |
| return FakeProvider( | |
| responses=[_FAKE_DEFAULT_RESPONSE], model_name=model or "fake", | |
| ) | |
| if name not in _REGISTRY: | |
| raise ValueError( | |
| f"Unknown provider {name!r}. " | |
| f"Available providers: {', '.join(available_providers())}." | |
| ) | |
| module_path, cls_name = _REGISTRY[name] | |
| provider_cls = getattr(importlib.import_module(module_path), cls_name) | |
| return provider_cls(model=model) | |