2 Commits
Author SHA1 Message Date
6f7dcd4e57 fix(analyzer): escalate temperature on retries to self-recover malformed JSON (#81)
* fix(analyzer): escalate temperature on retries to self-recover bad JSON

Ollama is non-deterministic even at temperature 0 (no fixed seed, CUDA/batch
variance), so the analyzer occasionally emits non-schema JSON that fails parsing
(SC0011 -> null Scene). The retry loop reused the prompt unchanged at the same
temperature, so all internal retries reproduced the same failure -- only a fresh
manual re-run recovered.

Escalate the sampling temperature on retry attempts only (base -> +0.2 per
retry, capped at 1.0); the prompt is still byte-for-byte unchanged (§12.9) and
the first attempt keeps the configured temperature, so the happy path stays
deterministic while a malformed run can now self-recover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(analyzer): use pytest.approx for temperature assertions (SonarCloud S1244)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: kunail0804 <kunail0804@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 21:18:41 +02:00
c1e6afeb41 Implement the Ollama Analyzer backend (#15) (#59)
* feat(analyzer): add the Ollama Analyzer backend (#15)

Add compiler/analyzer/backend.py per MASTER_SPEC §12.3, §12.10.

- AnalyzerBackend Protocol keeps the LLM backend swappable with no downstream
  coupling; the module imports no downstream compiler stage.
- OllamaBackend talks to a local Ollama /api/generate endpoint using only the
  standard library (urllib). The HTTP call is an injectable transport, so the
  backend is fully unit-testable without a live Ollama.
- Sends the configured model, temperature (default 0.0), and the user prompt
  unmodified, applying the configured timeout. BackendResult exposes the response
  text, model name, and request duration for logging.
- Failure modes map to codes: connection failure -> BackendUnavailableError
  (SC0012, Fatal); timeout -> BackendTimeoutError (SC0013); HTTP error /
  unexpected response -> BackendResponseError (SC0018, new extension).

Adds SC0018 (Analyzer Unexpected Response) to the message-code registry.

Tests (no live Ollama): interface conformance, from_config, success with
telemetry + unmodified prompt, and timeout/connection/URLError/HTTP/malformed
response mapping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(analyzer): use pytest.approx and single throwing call in backend tests

Avoid float-equality on temperature (SonarCloud reliability) and construct the
backend outside pytest.raises so each block has a single throwing invocation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: kunail0804 <kunail0804@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 20:10:57 +02:00