Skip to content

Architecture

Cristiano Carvalho edited this page Sep 4, 2026 · 9 revisions

Aludel is arranged as a disciplined workshop: LiveView at the surface, contexts as the hands of the craft, and behaviour-based interfaces where the system meets outside forces.

System Overview

flowchart LR
    UI[LiveView UI]
    C[Contexts]
    I[Interfaces]
    S[Storage]
    X[External Services]
    DB[(PostgreSQL)]

    UI --> C
    C --> I
    C --> DB
    C --> S
    I --> X
    S --> X
Loading

Context Boundaries

Context Responsibility
Projects Typed project containers for prompts and suites
Prompts Prompt records, immutable versions, evolution metrics, Pareto analysis, and suggestions
Runs Prompt execution across one or more providers
Evals Test suites, assertions, and evaluation orchestration
Datasets Reusable ordered single-turn and multi-turn evaluation examples
Providers Provider configuration and model selection
Stats Rolling quality, latency, cost, stability, and regression metrics
Execution Shared boundary for native provider calls and host-app callbacks

Interface Layer

The interface layer keeps provider-specific logic out of the contexts, so new integrations can be introduced like new metals in the crucible, without recasting the rest of the system.

LLM Client

Aludel.LLM.call(provider, prompt, documents: documents)

Current implementations:

  • Aludel.Interfaces.LLM.Providers.OpenAI
  • Aludel.Interfaces.LLM.Providers.Anthropic
  • Aludel.Interfaces.LLM.Providers.Google
  • Aludel.Interfaces.LLM.Providers.Ollama
  • Aludel.Interfaces.LLM.Providers.XAI
  • Aludel.Interfaces.LLM.Providers.Groq
  • Aludel.Interfaces.LLM.Providers.OpenRouter

Each provider adapter normalizes output into a common result shape with:

  • output
  • input_tokens
  • output_tokens
  • latency_ms
  • cost_usd
  • metadata
  • normalized execution artifacts

Execution Boundary

Aludel.Execution.execute(%{
  kind: :run | :suite,
  prompt_version: prompt_version,
  variables: variables,
  provider: provider,
  documents: documents,
  metadata: metadata
})

Aludel.Execution selects between:

  • native mode, which renders the prompt and calls the configured provider adapter directly
  • callback mode, which delegates execution to a host-app module implementing Aludel.Executor

Callback responses share the same output shape as native responses, but metrics such as tokens, latency, and cost remain optional so host workflows can return only what they know.

Document Converter Behaviour

Aludel.DocumentConverter.pdf_to_image(document)

Current implementation:

  • ImageMagick for PDF-to-PNG conversion when a provider does not accept native PDFs

Document Storage

Uploaded suite documents move through Aludel.Storage, which selects an adapter and persists file contents outside the relational row.

Current backends:

  • Aludel.Interfaces.Storage.Adapters.Local
  • Aludel.Interfaces.Storage.Adapters.AWS
  • Aludel.Interfaces.Storage.Adapters.GCS

Primary Flows

Prompt Execution

This is the main path from intent to result: a prompt is shaped in the UI, handed to the execution boundary, then either sent to a provider adapter directly or dispatched into the host app callback before the normalized result comes back with enough telemetry to judge its worth.

sequenceDiagram
    participant U as User
    participant LV as LiveView
    participant X as Aludel.Execution
    participant M as Native LLM or App Callback
    participant DB as PostgreSQL

    U->>LV: Submit prompt variables and providers
    LV->>X: execute/1 for each provider
    X->>DB: mark run as running, create pending results
    X->>M: native provider call or callback executor
    M-->>X: Normalized result with optional metrics and metadata
    X->>DB: Persist per-provider completion or error
    X-->>LV: Broadcast status updates over PubSub
Loading

Suite Execution

Suite execution repeats that same fire under controlled conditions, so prompts can be tested as instruments rather than admired as artifacts.

flowchart TD
    A[LiveView starts suite run]
    B[Evals.execute_suite/3]
    C[Iterate test cases]
    D[Load and prepare document attachments]
    E[Execute prompt via provider adapters]
    F[Validate assertions]
    G[Aggregate pass fail cost and latency]
    H[Persist suite_run]

    A --> B --> C --> D --> E --> F --> C
    C -->|all test cases processed| G --> H
Loading

Dataset Population

Dataset entries are copied into a suite transactionally and in position order. Each copied test case keeps source_dataset_entry_id, and a uniqueness constraint makes repeated population idempotent for that suite.

Prompt Optimization

Evolution metrics feed suite-scoped Pareto analysis and failure reflection. Reflection gathers bounded failed-result evidence, calls the selected provider, validates variable preservation, and persists a pending suggestion. Only explicit acceptance creates a new prompt version.

Deployment Modes

  • Standalone: self-contained Phoenix application under standalone/
  • Embedded: packaged into a host application and mounted with aludel_dashboard/2 while sharing repo and config

Extension Points

  • Add an LLM provider by implementing Aludel.Interfaces.LLM.Behaviour
  • Add a document converter by implementing Aludel.Interfaces.DocumentConverter.Behaviour
  • Add a storage backend by implementing the put/4, get/2, and delete/2 adapter callbacks used by Aludel.Storage
  • Add a host-app execution path by implementing Aludel.Executor
  • Add an evaluation metric by implementing Aludel.Evals.Metric and registering its type

See Data Model for entity relationships and storage details.

Clone this wiki locally