The core engine & its pipeline
The stateless orchestration core and the request pipeline every interaction flows through.
Deep-dive into the
orazaka-coremodule — 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.
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:
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.
Core chain: always, in the order of the code
- 1SafetyInterceptor · validation
Stops a turn that carries crisis content and answers it with the pack's fixed, reviewed text. - 2ScopeGuardInterceptor · governance
Refuses a turn that strays into the domain its pack declared out of bounds (ADR-051). - 3UserContextResolver · context
Extracts user profile attributes and RBAC security configurations from the Spring Security context and enriches the `PromptContext`'s user metadata. - 4SystemContextInjector · context
Single atomic service responsible for both resolving system/environment state and injecting it into the timeline. - 5RagInterceptor · enrichment
RAG (Retrieval-Augmented Generation) interceptor — enriches the prompt with relevant knowledge base context retrieved via `KnowledgeService`.
Configured chain: in the database order
- 1UserContextResolver · context · core
Extracts user profile attributes and RBAC security configurations from the Spring Security context and enriches the `PromptContext`'s user metadata. - 2SystemContextInjector · context · core
Single atomic service responsible for both resolving system/environment state and injecting it into the timeline. - 3RagInterceptor · enrichment · core
RAG (Retrieval-Augmented Generation) interceptor — enriches the prompt with relevant knowledge base context retrieved via `KnowledgeService`. - 4EntitlementInterceptor · governance · dynamic
Gates the synchronous chat path on what the actor may do and can afford (ADR-033 §6.2). - 5McpInterceptor · enrichment · dynamic
MCP (Model Context Protocol) interceptor — enriches the prompt with external context resolved via the `McpOrchestrator`. - 6BrandContextInterceptor · enrichment · dynamic
Injects an installed Studio's brand kit into the prompt (ADR-034 §9.1). - 7MemoryInterceptor · enrichment · dynamic
Conversation memory interceptor — injects historical messages before inference and persists new messages after completion. - 8RefinerInterceptor · reformulation · dynamic
Resolves fuzzy user questions against compiled context matrices and reformulates them into clear, explicit instructions using an LLM call. - 9RouterInterceptor · reformulation · dynamic
Analyzes user intent and selects the optimal AI provider using an LLM classification call with temperature 0.0 for determinism. - 9ToolInterceptor · tooling · dynamic
Tool execution interceptor — analyzes prompt content to selectively attach relevant `ToolCallback` definitions to the chat options. - 10MediaInterceptor · · dynamic(not built yet)
- 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 indomain.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_modelstable. Cached via Caffeine TTL. Chat Model Resolution Cascade:
ORAZAKA_OLLAMA_MODELenvironment variable (highest priority)spring.ai.ollama.chat.options.modelYAML value- Auto-detected default (first non-embedding model from Ollama tags catalog)