Orazaka
Pages of the documentation

The core engine & its pipeline

The stateless orchestration core and the request pipeline every interaction flows through.

Deep-dive into the orazaka-core module — the stateless, Spring AI-powered orchestration library.


1. Architectural Position

orazaka-core is the central orchestration library. It is strictly stateless, web-agnostic, database-agnostic, and security-context-agnostic. It wraps Spring AI (2.0, ADR-030) under a single entry facade: AiClient.

Architecture · orazaka-core

Orazaka AI Orchestration Engine

Repository
orazaka-ai-engine
Role
domain
Owner
orazaka

Uses

  • krizaka-security
  • orazaka-persistence-app-api

Used by

  • orazaka-business
  • orazaka-conversation-service
  • orazaka-interceptors
  • orazaka-job-service
  • orazaka-persistence-bridge
  • orazaka-tools

Select a module to see what it depends on and what depends on it: every arrow points toward the core, never away from it.


2. The AiClient Facade & Request Records

All AI operations invoke the unified AiClient:

java
public interface AiClient {
    ChatResponse chat(ChatRequest request);
    Flux<ChatResponse> stream(ChatRequest request);
    AudioResponse audio(AudioRequest request);
    ImageResponse image(ImageRequest request);
    VideoResponse video(VideoRequest request);
}

Request payloads are immutable Java records enforcing compact constructor validation boundaries (ERR-106, ERR-116).


3. Dynamic Pipeline Orchestrator

The orchestrator executes a sequence of PromptContextInterceptor beans. It is never bypassed: orazaka.core.orchestration.enabled=false (ORCHESTRATION_ENABLED) refuses every engine turn (PipelineDisabledException → 503) instead of calling the model without its controls (ADR-062).

Routing Modes (orazaka.core.orchestration.routing.mode)

  • DETERMINISTIC: Database-driven order configured in pipeline_interceptor_config.
  • AGENTIC: LLM-driven runtime intent classification.

Kill-Switch

If orazaka.security.disable-ai=true, any interceptor returning isAiDependent() == true raises a SecurityException.

The interceptor chain

A turn goes through the core chain first — in the order of the code, never bypassable — then through the configured interceptors in their database order (pipeline_interceptor_config). The chain below is read from both; Interceptor Registry lists every row with its class.

Interceptor pipeline — text version

Core chain: always, in the order of the code

  1. 1SafetyInterceptor · validation
    Stops a turn that carries crisis content and answers it with the pack's fixed, reviewed text.
  2. 2ScopeGuardInterceptor · governance
    Refuses a turn that strays into the domain its pack declared out of bounds (ADR-051).
  3. 3UserContextResolver · context
    Extracts user profile attributes and RBAC security configurations from the Spring Security context and enriches the `PromptContext`'s user metadata.
  4. 4SystemContextInjector · context
    Single atomic service responsible for both resolving system/environment state and injecting it into the timeline.
  5. 5RagInterceptor · enrichment
    RAG (Retrieval-Augmented Generation) interceptor — enriches the prompt with relevant knowledge base context retrieved via `KnowledgeService`.

Configured chain: in the database order

  1. 1UserContextResolver · context · core
    Extracts user profile attributes and RBAC security configurations from the Spring Security context and enriches the `PromptContext`'s user metadata.
  2. 2SystemContextInjector · context · core
    Single atomic service responsible for both resolving system/environment state and injecting it into the timeline.
  3. 3RagInterceptor · enrichment · core
    RAG (Retrieval-Augmented Generation) interceptor — enriches the prompt with relevant knowledge base context retrieved via `KnowledgeService`.
  4. 4EntitlementInterceptor · governance · dynamic
    Gates the synchronous chat path on what the actor may do and can afford (ADR-033 §6.2).
  5. 5McpInterceptor · enrichment · dynamic
    MCP (Model Context Protocol) interceptor — enriches the prompt with external context resolved via the `McpOrchestrator`.
  6. 6BrandContextInterceptor · enrichment · dynamic
    Injects an installed Studio's brand kit into the prompt (ADR-034 §9.1).
  7. 7MemoryInterceptor · enrichment · dynamic
    Conversation memory interceptor — injects historical messages before inference and persists new messages after completion.
  8. 8RefinerInterceptor · reformulation · dynamic
    Resolves fuzzy user questions against compiled context matrices and reformulates them into clear, explicit instructions using an LLM call.
  9. 9RouterInterceptor · reformulation · dynamic
    Analyzes user intent and selects the optimal AI provider using an LLM classification call with temperature 0.0 for determinism.
  10. 9ToolInterceptor · tooling · dynamic
    Tool execution interceptor — analyzes prompt content to selectively attach relevant `ToolCallback` definitions to the chat options.
  11. 10MediaInterceptor · · dynamic(not built yet)
  12. 11UserContextInterceptor · context · dynamic
    ContextInterceptor that dynamically injects onboarding profile details (ai_behavior, primary_industry) as structural system prompt constraints right before executing model inference or streaming.

4. Engine Topology

One engine serves every modality. AbstractEngine is sealed and permits a single subclass, Engine (ADR-003): chat, streaming, image and speech are methods of the same class, each wired to its Spring AI model (ChatModel, TextToSpeechModel, image and video through their outbound ports), so a pattern match over engines is always exhaustive. Model choice is not a subclass: it is routing (DeterministicRouterEngine, SemanticRoutingEngine) over the model catalogue in the database.


5. Outbound Ports & Lifecycle Policies

  • Interface-Driven Boundaries: Outbound ports (e.g. ChatGeneratorClient, VideoGeneratorClient) live as public interfaces in domain.ports.outbound. Implementations reside in infrastructure packs as package-private beans.
  • Resource Recovery: Streams and SSE channels must register completion/timeout hooks (onCompletion, .doFinally()) to dispose subscriptions (Disposable.dispose()) and prevent memory leaks.
  • Hikari Database Connection Eviction:

    yaml
    hikari:
      maximum-pool-size: 10
      minimum-idle: 2
      idle-timeout: 30000            # Evict idle connections in 30s
      max-lifetime: 60000            # Recycle before DB timeout
      connection-timeout: 5000       # Fail fast in 5s

6. Model Catalog & Chat Configuration

  • Database Model Catalog: Image, video, and speech models reside in the orazaka_models table. Cached via Caffeine TTL.
  • Chat Model Resolution Cascade:

    1. ORAZAKA_OLLAMA_MODEL environment variable (highest priority)
    2. spring.ai.ollama.chat.options.model YAML value
    3. Auto-detected default (first non-embedding model from Ollama tags catalog)

Edit this page on GitHub