Building, testing, running
The engine is a Poetry package at services/engine, targeting Python 3.14, with code
under src/. A scaffold exists: structure, interfaces, and the API are in place, but each
engine’s run method raises NotImplementedError (surfaced as HTTP 501) until that
engine is built.
From services/engine:
- Install dependencies:
poetry install - Run the API and MCP server:
poetry run optival-engine— serveshttp://localhost:8000; OpenAPI docs at/docs; MCP at/mcp - Run the full test suite:
poetry run pytest - Run a single test:
poetry run pytest tests/test_smoke.py::test_health - Lint and type-check:
poetry run ruff check .andpoetry run mypy src
To run in containers, services/docker-compose.yml is the single entry point for the
platform: from services, docker compose up --build builds and starts the engine on a
shared optival network.
Architecture
The code lives in services/engine/src as four modules: core plus one per engine —
audit, diagnosis, generation.
The core module provides everything the engines share. Its library part —
contracts (typed models engines exchange), meta (the YAML meta schema), providers
(the provider interface), and config — holds no business logic; it provides capability.
Its shell part (core/app.py, core/schemas.py) is the composition root: it assembles
each engine’s HTTP router into one FastAPI app, defines the end-to-end /pipeline, and
mounts the MCP server.
The LLM layer composes three libraries: DSPy for typed signatures and modules, LiteLLM beneath it for unified multi-provider access, and Pydantic for the type system and YAML meta schema. Each engine owns one domain responsibility and depends only on the core’s library — never on another engine’s internals.
The provider interface
The provider interface abstracts over two heterogeneous access modes. Most providers are LLM APIs reached through DSPy/LiteLLM. But Google AI Overviews has no LLM API — it appears inside Google Search results and is captured by SERP scraping or browser automation. The interface hides which a provider is, and the audit engine treats both uniformly. The active provider set is configurable per run.
Local providers exercise the pipeline without paid API calls; their answers have no relationship to how real consumer engines cite brands, so local runs validate plumbing, never measurement.
The YAML meta
The generation engine emits the meta as a schema-governed YAML document — an
engine-neutral optimization spec, not the on-page format. The artifacts it describes have
canonical web formats (llms.txt is markdown, schema markup is JSON-LD, titles and
descriptions are HTML tags); serializing each field into its canonical form happens at
render time, which is the v1 content engine’s job. In v0 the deliverable is the YAML meta
itself.
API & MCP
_data/api.yml. Once a
service populates that file, this section fills in automatically — no website change
required.