Engine Application
Interaction Pipeline
A conversation is executed as a reactive pipeline: a Flux<Element> coming from the client is
transformed into a Flux<OutputElement> going back to it. The abstractions themselves —
Pipeline, Context, Input, PipelineComponent — live in
the common library; this page describes how the engine puts them
together.
Pipeline Setups
The setupName part of a pipeline key selects a
setup: a pair of a context service and an interaction manager, configured under
promethist.pipeline.setup.{name}.
| Setup | Context service | Interaction manager |
|---|---|---|
|
|
|
|
|
|
|
|
promethist.pipeline.allowedSetupNames can restrict which setups a deployment accepts; a key
naming an unconfigured setup fails the connection.
PipelineService
PipelineService is the single entry point for every transport — the WebSocket handler, the
Socket.IO service, the Twilio handler and the HTTP pipeline controller all go through it.
Building the Configuration
createConfiguration(key, headers, parameters, sessionId) normalizes query parameters and X-
headers into a PipelineConfiguration, with the query parameter taking precedence over the
header. The resulting object carries everything the conversation needs: session ID, device ref,
locales and time zone, audio encoding and sample rates, wire formats, feature flags and the
optional realtime configuration. The full parameter list is documented in
Pipeline Configuration.
Creating the Pipeline
createPipeline(configuration, authentication) returns an anonymous Pipeline implementation
over the full set of injected PipelineComponent beans. The base class sorts those components
into typed collections (extractors, element filters, action mappers, speech synthesizers,
interaction managers), so adding a component to the engine is a matter of declaring a bean — no
registration step.
The instance also resolves the conversation’s user from the authentication: a JWT token yields the
platform user (and copies the name and email claims onto the session), Basic and API key
identities resolve by name, and without an identity the user is derived from the speaker or the
device.
Session Windowing
process(configuration, authentication, elements) implements the multi-session state machine over
one connection:
-
If the configuration already carries a key, a synthetic
#ready:key=…&sessionId=…token is prepended, which starts the first session immediately. Otherwise the pipeline waits for the client to send that token. -
The element stream is split on every
#ready:key=token, so one physical connection can carry several consecutive sessions. -
Within a session, elements are taken until an
#exittoken. -
Each session window re-reads its key and session ID from the token, so a subsequent session on the same connection can address a different agent.
Three control tokens are intercepted mid-stream rather than passed on:
| Token | Effect |
|---|---|
|
Decodes the token and replaces the pipeline’s authentication for the remainder of the session. |
|
Replaces the accepted locales of the configuration. |
|
Handled by the transport layer: it completes the input stream, which ends the session gracefully. |
Session Lifecycle
For each session window the service resolves the device (creating a Device record for an unknown
deviceRef) and then the Session — either the existing document for a reused sessionId or a
new one in state OPEN.
A new document is written before any agent has been resolved, so it carries no user, agent or
project association yet. Those are filled in and saved by the context service once the agent’s
project has passed the permission and subscription check — see
Session Start. The rest of the session’s
state (turn count, emotional sets, summary, evaluation fields) accumulates only in memory and
reaches MongoDB on the next save, which is normally the one at session end; a #rating action is
the exception, saving the session mid-conversation so a disconnect cannot lose the rating.
Input then flows through ProcessorManager (audio and token normalization, see
Processors) into the pipeline manager chosen for the model (see Pipeline Managers), and the
output flows back to the transport.
How the session ends determines the cleanup:
| Outcome | Session state | Cleanup |
|---|---|---|
Input stream completed (client sent |
|
End-of-conversation evaluation runs, post-session webhooks execute, then the session is saved.
The evaluation output is appended to the output stream, so a still-connected client can receive
its results as an |
Error |
|
The session is saved in the disconnected state. |
Cancelled (client vanished) |
|
Same as above. This is why closing a socket without sending |
A watchdog guards against a pipeline that never completes: once the input stream has completed,
the output is force-closed after promethist.pipeline.sessionEndTimeoutMs.
Each turn is persisted through the pipeline’s saveContext, which stores the Turn with its
timing log and records the latency metrics described in
Observability.
Pipeline Managers
PipelineService prepares a conversation before any pipeline manager is involved. It builds the context, resolves
the interaction manager for it and opens the model session through
RealtimeSessionFactory. The interaction manager is the one registered for the setup (a
@PipelineSetup annotation) whose content classes contain the class of the context’s content — the
agent; failing that, the one that claims no particular content. Only then is the pipeline manager
chosen, from the model’s properties:
| Pipeline manager | Used when | Drives |
|---|---|---|
|
A conversation delimited into turns. It windows the element stream into turns, drives the interaction
and planning managers, and records usage when the conversation ends. Needs a
|
|
|
A conversation that is not delimited: the model speaks continuously and decides for itself when to
talk, so there are no turns, no planning and no response end. Needs a
|
An interaction manager that does not implement the contract of the chosen pipeline manager is rejected with an error.
The turn-based manager is the most intricate part of the engine, so it has its own pages:
-
Realtime Conversation Lifecycle — session start, turn windowing, planning and instruction injection, turn end and session end, the interaction manager hooks, and what a turnless conversation does instead.
-
Realtime Models — the
RealtimeModelcontract,RealtimeSession, the realtime element vocabulary and the individual providers.
Contexts
The context is the per-turn state handed to every component. The engine provides two context services:
| Service | Context |
|---|---|
Builds an |
|
Builds a |
Both extend ContextBase, which creates the Turn document, increments the session’s turn count
and records transcripts.