# CyberBrain26 v4.1 — Phase 5: Model Layer (Final)

**Date:** 2026-09-23  
**Version:** 4.1.0  
**Status:** ✅ COMPLETE — All mypy errors fixed, 244 tests passing

---

## Summary

Phase 5 Model Layer has been finalized. Three remaining mypy errors were fixed:
- `ollama_client.py:76` — mixed `yield`/`return` in `pull_model` (generator function with return statement)
- `llama_cpp_client.py:230` — missing `llama_cpp` library stub (optional dependency)
- `model_intelligence.py:100` — `ProviderTrust` passed where `ModelTrust` expected (enum mismatch)

The full test suite runs clean with **244 tests passing**.

---

## Changes Made

### 1. `ollama_client.py` — Fix `pull_model` generator/return conflict

**Error:** `Missing return statement [return]` at line 76.

**Root cause:** `pull_model` used both `yield` (making it a generator) and `return value`, which mypy treats as a generator function that must not return a value. When `stream=False`, the `return response.json()` was unreachable in the generator semantics.

**Fix:** Refactored to separate the streaming path into a dedicated `_pull_stream` helper:

```python
# Before
def pull_model(self, model_name, *, stream=False):
    response = self._request("POST", "/api/pull", json={"model": model_name}, stream=stream)
    if stream:
        for line in response.iter_lines():
            if line:
                yield json.loads(line)
    else:
        response.raise_for_status()
        return response.json()

# After
def pull_model(self, model_name, *, stream=False):
    response = self._request("POST", "/api/pull", json={"model": model_name}, stream=stream)
    if stream:
        return self._pull_stream(model_name, response)
    response.raise_for_status()
    return response.json()

def _pull_stream(self, model_name, response):
    for line in response.iter_lines():
        if line:
            yield json.loads(line)
```

### 2. `llama_cpp_client.py` — Fix missing `llama_cpp` import stub

**Error:** `Cannot find implementation or library stub for module named "llama_cpp" [import-not-found]`.

**Root cause:** `llama-cpp-python` is an optional dependency (not in `pyproject.toml` dependencies), so mypy cannot find a stub.

**Fix:** Added `# type: ignore[import-not-found]` to both `from llama_cpp import Llama` statements:

```python
from llama_cpp import Llama  # type: ignore[import-not-found]
```

### 3. `model_intelligence.py` — Fix `ProviderTrust` → `ModelTrust` enum mismatch

**Error:** `Argument "trust" to "ModelRecord" has incompatible type "ProviderTrust"; expected "ModelTrust" [arg-type]`.

**Root cause:** `_discover_provider_models` passed `provider.trust` (a `ProviderTrust` enum) directly to `ModelRecord.trust` (a `ModelTrust` enum). These are separate enums with identical values but different types.

**Fix:** Added a static mapping method `_map_provider_trust_to_model_trust` that converts `ProviderTrust` → `ModelTrust`:

```python
@staticmethod
def _map_provider_trust_to_model_trust(trust: ProviderTrust) -> ModelTrust:
    mapping = {
        ProviderTrust.OFFICIAL: ModelTrust.OFFICIAL,
        ProviderTrust.VERIFIED: ModelTrust.VERIFIED,
        ProviderTrust.COMMUNITY: ModelTrust.COMMUNITY,
        ProviderTrust.UNOFFICIAL: ModelTrust.UNOFFICIAL,
        ProviderTrust.UNKNOWN: ModelTrust.UNKNOWN,
    }
    return mapping.get(trust, ModelTrust.UNKNOWN)
```

Also added the missing `ProviderTrust` import to `model_intelligence.py`.

---

## Mypy Status

```
$ python3 -m mypy src/cyberbrain26/model_layer/
Success: no issues found in 8 source files
```

---

## Test Suite

```
$ python3 -m pytest tests/ -v
============================= 244 passed in 4.87s ==============================
```

All 244 tests pass across all test files:
- `test_model_layer.py` — Model registry, provider registry, model intelligence, model router, LiteLLM/Ollama/llama.cpp clients, model gateway
- `test_agents.py`, `test_security_*.py`, `test_ptah_bridge.py`, `test_task_dispatcher.py`, `test_control_plane.py`, `test_basic.py`

---

## Phase 5 Model Layer Architecture

| Component | File | Purpose |
|---|---|---|
| Model Registry | `model_registry.py` | Metadata store for all known models (ModelRecord, ModelRegistry) |
| Provider Registry | `provider_registry.py` | Metadata store for all known providers (ProviderRecord, ProviderRegistry) |
| Model Intelligence | `model_intelligence.py` | Discovery, validation, classification, scoring, deduplication |
| Model Router | `router.py` | Route selection by strategy (cost, local-first, performance, reliability, capability, round-robin) |
| LiteLLM Client | `litellm_client.py` | Unified LLM API client via LiteLLM |
| Ollama Client | `ollama_client.py` | Local model serving via Ollama API |
| Llama.cpp Client | `llama_cpp_client.py` | Local inference via llama.cpp server or library |
| Model Gateway | `control_plane/model_gateway/__init__.py` | High-level facade combining registry + router + clients |