Skip to main content
v1

Configuration Deep Guide

Table mapping in application.yml (ConvEngine + CCF Core)

Use this when your physical table names differ from defaults. ConvEngine reads convengine.tables.*; CCF Core reads ccf.core.tables.*.

application.yml table mappings
YAML
ccf:
core:
tables:
PAGE_COMMON_QUERY: ZP_PAGE_COMMON_QUERY
SECTION_INFO: ZP_SECTION_INFO
CONTAINER_INFO: ZP_CONTAINER_INFO
CONTAINER_FIELD_INFO: ZP_CONTAINER_FIELD_INFO
CONTAINER_QUERY_INFO: ZP_CONTAINER_QUERY_INFO
convengine:
tables:
AUDIT: CE_AUDIT
CONFIG: CE_CONFIG
CONTAINER_CONFIG: CE_CONTAINER_CONFIG
CONVERSATION: CE_CONVERSATION
INTENT: CE_INTENT
INTENT_CLASSIFIER: CE_INTENT_CLASSIFIER
LLM_CALL_LOG: CE_LLM_CALL_LOG
MCP_DB_TOOL: CE_MCP_DB_TOOL
MCP_TOOL: CE_MCP_TOOL
OUTPUT_SCHEMA: CE_OUTPUT_SCHEMA
POLICY: CE_POLICY
PROMPT_TEMPLATE: CE_PROMPT_TEMPLATE
RESPONSE: CE_RESPONSE
RULE: CE_RULE
Important

If you override table names, keep mappings consistent across environments and apply the same naming strategy in JPA config.

ConvEngine does not ship default application.yml values; consumers must provide convengine.* properties.

Complete application.yml reference (demo + full ConvEngine options)

This is a complete starter reference combining convengine-demo style settings and all configurable convengine.* properties currently present in the framework.

Complete application.yml reference
YAML
server:
port: 8080

spring:
application:
name: convengine

datasource:
url: jdbc:postgresql://localhost:5432/convengine
username: convengine_user
password: convengine_pwd
driver-class-name: org.postgresql.Driver

jpa:
open-in-view: false
hibernate:
ddl-auto: none
naming:
# Use the physical strategy your app needs (demo uses CCF strategy)
physical-strategy: com.github.salilvnair.ccf.config.hibernate.CcfPhysicalNamingStrategy
show-sql: true
properties:
hibernate:
format_sql: true
jdbc:
lob:
non_contextual_creation: true

logging:
level:
root: INFO
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE

convengine:
# Demo app-only block (optional, not framework-required)
demo:
stream-mode: SSE # SSE | STOMP | BOTH
step-hook:
enabled: true

# Framework flags
experimental:
enabled: false

# Dynamic table mapping for CE_* entities
tables:
AUDIT: CE_AUDIT
CONFIG: CE_CONFIG
CONTAINER_CONFIG: CE_CONTAINER_CONFIG
CONVERSATION: CE_CONVERSATION
INTENT: CE_INTENT
INTENT_CLASSIFIER: CE_INTENT_CLASSIFIER
LLM_CALL_LOG: CE_LLM_CALL_LOG
MCP_DB_TOOL: CE_MCP_DB_TOOL
MCP_TOOL: CE_MCP_TOOL
OUTPUT_SCHEMA: CE_OUTPUT_SCHEMA
POLICY: CE_POLICY
PROMPT_TEMPLATE: CE_PROMPT_TEMPLATE
RESPONSE: CE_RESPONSE
RULE: CE_RULE


transport:
sse:
enabled: true
emitter-timeout-ms: 1800000

stomp:
enabled: false
endpoint: /ws-convengine
app-destination-prefix: /app
topic-prefix: /topic
audit-destination-base: /topic/convengine/audit
allowed-origin-pattern: "*"
sock-js: true
broker:
mode: SIMPLE # SIMPLE | RELAY
relay-destination-prefixes: /topic,/queue
relay-host: localhost
relay-port: 61613
client-login: ""
client-passcode: ""
system-login: ""
system-passcode: ""
virtual-host: ""
system-heartbeat-send-interval-ms: 10000
system-heartbeat-receive-interval-ms: 10000

audit:
enabled: true
persist-meta: true
level: ALL # ALL | STANDARD | ERROR_ONLY | NONE
include-stages: []
exclude-stages: []

persistence:
mode: IMMEDIATE # IMMEDIATE | DEFERRED_BULK
jdbc-batch-size: 200
max-buffered-events: 5000
flush-stages: ENGINE_KNOWN_FAILURE,ENGINE_UNKNOWN_FAILURE
final-step-names: PipelineEndGuardStep
flush-on-stop-outcome: true

dispatch:
async-enabled: false
worker-threads: 2
queue-capacity: 2000
rejection-policy: CALLER_RUNS # CALLER_RUNS | DROP_NEWEST | DROP_OLDEST | ABORT
keep-alive-seconds: 60

rate-limit:
enabled: false
max-events: 200
window-ms: 1000
per-conversation: true
per-stage: true
max-tracked-buckets: 20000

# Example consumer-specific LLM block (optional, used by demo-style adapters)
# llm:
# provider: openai
# temperature: 0.3
# openai:
# api-key: ${OPENAI_API_KEY}
# model: gpt-4.1
# base-url: https://api.openai.com
# lmstudio:
# api-key: ${LMSTUDIO_API_KEY}
# model: openai/gpt-oss-20b
# base-url: http://localhost:1234

ccf:
core:
tables:
PAGE_COMMON_QUERY: ZP_PAGE_COMMON_QUERY
SECTION_INFO: ZP_SECTION_INFO
CONTAINER_INFO: ZP_CONTAINER_INFO
CONTAINER_FIELD_INFO: ZP_CONTAINER_FIELD_INFO
CONTAINER_QUERY_INFO: ZP_CONTAINER_QUERY_INFO
Stream enablement note

@EnableConvEngine(stream = true|false) is annotation-driven. It is not a YAML property; keep transport flags aligned with the annotation mode.

ce_prompt_template in detail

ce_prompt_template holds reusable prompt text for both schema extraction and derived response generation.

Use response_type to route templates:

  • SCHEMA_JSON for schema extraction prompts
  • TEXT for derived text response prompts
  • JSON for derived json response prompts
Example ce_prompt_template rows
SQL
-- Schema extraction template
INSERT INTO ce_prompt_template
(intent_code, state_code, response_type, system_prompt, user_prompt, enabled)
VALUES
('DISCONNECT_ELECTRICITY', 'COLLECTING', 'SCHEMA_JSON',
'Extract required fields strictly as JSON. No commentary.',
'User: {{user_input}}
Context: {{context}}
Schema: {{schema}}',
true);

-- Derived text response template
INSERT INTO ce_prompt_template
(intent_code, state_code, response_type, system_prompt, user_prompt, enabled)
VALUES
('REQUEST_TRACKER', 'IDLE', 'TEXT',
'You are a concise status assistant. Keep response under 3 lines.',
'User: {{user_input}}
Context: {{context}}
Session: {{session}}',
true);

ce_config in detail

ce_config stores runtime tunables keyed by component class.

Common keys:

  • AgentIntentResolver.MIN_CONFIDENCE
  • AgentIntentResolver.COLLISION_GAP_THRESHOLD
  • AgentIntentResolver.SYSTEM_PROMPT
  • AgentIntentResolver.USER_PROMPT
  • McpPlanner.SYSTEM_PROMPT
  • McpPlanner.USER_PROMPT
  • ResetResolvedIntentStep.RESET_INTENT_CODES
  • IntentResolutionStep.STICKY_INTENT
Example ce_config rows
SQL
INSERT INTO ce_config (config_type, config_key, config_value, enabled) VALUES
('AgentIntentResolver', 'MIN_CONFIDENCE', '0.60', true),
('AgentIntentResolver', 'COLLISION_GAP_THRESHOLD', '0.15', true),
('ResetResolvedIntentStep', 'RESET_INTENT_CODES', 'RESET_SESSION,START_OVER', true),
('IntentResolutionStep', 'STICKY_INTENT', 'true', true),
('McpPlanner', 'SYSTEM_PROMPT', 'You are an MCP planner. Prefer safe calls and minimal arguments.', true),
('McpPlanner', 'USER_PROMPT', 'User: {{user_input}}
Tools: {{mcp_tools}}
Context: {{context}}', true);

Implemented type/action values

FieldAllowed valuesNotes
ce_response.response_typeEXACT, DERIVEDEXACT bypasses LLM generation
ce_response.output_formatTEXT, JSONUsed by output format resolver
ce_rule.rule_typeEXACT, REGEX, JSON_PATHMust match installed rule type resolvers
ce_rule.phasePIPELINE_RULES, AGENT_POST_INTENTControls whether rule runs in RulesStep or AgentIntentResolver post-intent pass
ce_rule.state_codeNULL, ANY, specific state codeNULL/ANY apply across states; specific value scopes execution to that state
ce_rule.actionSET_INTENT, SET_STATE, SET_JSON, GET_CONTEXT, GET_SCHEMA_JSON, GET_SESSION, SET_TASKMust match installed action resolvers

ce_output_schema in detail

ce_output_schema defines extraction contract per intent/state. SchemaExtractionStep uses this JSON schema to detect missing fields and drive clarification flow.

ce_output_schema shape (DDL-style)
SQL
-- Core columns (simplified)
CREATE TABLE ce_output_schema (
schema_id BIGSERIAL PRIMARY KEY,
intent_code TEXT NOT NULL,
state_code TEXT NOT NULL,
schema_name TEXT,
schema_description TEXT,
json_schema JSONB NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Example ce_output_schema row
SQL
INSERT INTO ce_output_schema
(intent_code, state_code, schema_name, schema_description, json_schema, enabled)
VALUES
(
'DISCONNECT_ELECTRICITY',
'COLLECTING',
'disconnect_request',
'Required data to process electricity disconnect request.',
'{
"type":"object",
"required":["accountNumber","reason"],
"properties":{
"accountNumber":{"type":"string"},
"reason":{"type":"string","enum":["MOVE_OUT","TEMP_CLOSE","PERMANENT_CLOSE"]},
"requestedDate":{"type":"string","format":"date"}
}
}'::jsonb,
true
);

ce_response in detail

ce_response maps resolved intent/state to response strategy.

  • EXACT: static response body from DB.
  • DERIVED: runtime generated response (LLM), optionally using ce_prompt_template.
ce_response shape (DDL-style)
SQL
CREATE TABLE ce_response (
response_id BIGSERIAL PRIMARY KEY,
intent_code TEXT NOT NULL,
state_code TEXT NOT NULL,
response_type TEXT NOT NULL, -- EXACT | DERIVED
output_format TEXT NOT NULL, -- TEXT | JSON
response_text TEXT,
response_json JSONB,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Example ce_response rows
SQL
-- EXACT TEXT response
INSERT INTO ce_response
(intent_code, state_code, response_type, output_format, response_text, enabled)
VALUES
('FAQ', 'IDLE', 'EXACT', 'TEXT', 'Yes, you can move your connection using Zapper app.', true);

-- DERIVED JSON response
INSERT INTO ce_response
(intent_code, state_code, response_type, output_format, response_json, enabled)
VALUES
('REQUEST_TRACKER', 'IDLE', 'DERIVED', 'JSON', '{"template":"status-card"}'::jsonb, true);

ce_rule in detail

ce_rule is the conditional transition/action layer executed in RulesStep.

  • rule_type: EXACT, REGEX, JSON_PATH
  • phase: PIPELINE_RULES, AGENT_POST_INTENT
  • state_code: NULL (all states), ANY (all states), or specific state code
  • action: SET_INTENT, SET_STATE, SET_JSON, GET_CONTEXT, GET_SCHEMA_JSON, GET_SESSION, SET_TASK
ce_rule shape (DDL-style)
SQL
CREATE TABLE ce_rule (
rule_id BIGSERIAL PRIMARY KEY,
phase TEXT NOT NULL DEFAULT 'PIPELINE_RULES',
intent_code TEXT NULL,
state_code TEXT NULL,
rule_type TEXT NOT NULL,
match_pattern TEXT NOT NULL,
action TEXT NOT NULL,
action_value TEXT NULL,
priority INT NOT NULL DEFAULT 100,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
description TEXT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Example ce_rule rows
SQL
-- If user says reset keywords, set reset intent
INSERT INTO ce_rule
(phase, intent_code, state_code, rule_type, match_pattern, action, action_value, priority, enabled, description)
VALUES
('PIPELINE_RULES', 'FAQ', 'ANY', 'REGEX', '(?i)^(reset|restart)$', 'SET_INTENT', 'RESET_SESSION', 10, true, 'Reset intent switch');

-- Agent post-intent bootstrap
INSERT INTO ce_rule
(phase, intent_code, state_code, rule_type, match_pattern, action, action_value, priority, enabled, description)
VALUES
('AGENT_POST_INTENT', 'MAPPING_STUDIO', 'ANY', 'JSON_PATH',
'$[?(@.intent == ''MAPPING_STUDIO'' && (@.state == ''UNKNOWN'' || @.state == ''IDLE''))]',
'SET_STATE', 'COLLECT_INPUTS', 5, true, 'Bootstrap mapping state during post-intent pass');

ce_rule.phase execution semantics

Use phase to control where a rule executes.

Rule Phase Execution Matrix

phaseExecuted byWhen it runsTypical usage
PIPELINE_RULESRulesStepNormal pipeline pass after schema/auto-advanceBusiness transitions, context actions, SET_TASK in standard flow
AGENT_POST_INTENTAgentIntentResolver post-intent passImmediately after agent accepts intentBootstrap state from UNKNOWN/IDLE based on resolved intent

ce_rule.state_code execution semantics

Use state_code to reduce unnecessary rule evaluations:

Rule State Scope Matrix

state_code valueRuntime behavior
NULLRule is eligible in all states
ANYRule is eligible in all states
Specific state (for example COLLECT_INPUTS)Rule is eligible only when session.state matches (case-insensitive)
Phase-targeted bootstrap example
SQL
INSERT INTO ce_rule
(phase, intent_code, state_code, rule_type, match_pattern, action, action_value, priority, enabled, description)
VALUES
('AGENT_POST_INTENT', 'MAPPING_STUDIO', 'ANY', 'JSON_PATH',
'$[?(@.intent == ''MAPPING_STUDIO'' && (@.state == ''UNKNOWN'' || @.state == ''IDLE''))]',
'SET_STATE', 'COLLECT_INPUTS', 5, true,
'Bootstrap Mapping Studio state right after agent intent resolution');
Runtime metadata exposed during rule execution

EngineSession/inputParams include phase metadata:

  • postIntentRule / post_intent_rule
  • rule_phase
  • rule_execution_source
  • rule_execution_origin

Prompt variable guidance

Common variables used in templates:

  • {{user_input}}
  • {{context}}
  • {{session}}
  • {{schema}}
  • {{conversation_history}}
  • schema helpers: {{missing_fields}}, {{missing_field_options}}, {{schema_description}}
Prompt variable exposure

Prompt template extra now includes all keys present in inputParams, including runtime/system-derived keys written through session.putInputParam(...). Keep key naming and values controlled in consumer task/rule code.

Runtime transport/audit properties

application.yml (feature toggles)
YAML
convengine:
transport:
stomp:
enabled: true
broker:
mode: SIMPLE # SIMPLE | RELAY
relay-destination-prefixes: /topic,/queue
relay-host: localhost
relay-port: 61613
client-login: ""
client-passcode: ""
system-login: ""
system-passcode: ""
virtual-host: ""
system-heartbeat-send-interval-ms: 10000
system-heartbeat-receive-interval-ms: 10000

audit:
enabled: true
level: ALL # ALL | STANDARD | ERROR_ONLY | NONE
include-stages: []
exclude-stages: []
persistence:
mode: IMMEDIATE # IMMEDIATE | DEFERRED_BULK
jdbc-batch-size: 200
max-buffered-events: 5000
flush-stages: ENGINE_KNOWN_FAILURE,ENGINE_UNKNOWN_FAILURE
final-step-names: PipelineEndGuardStep
flush-on-stop-outcome: true
dispatch:
async-enabled: false
worker-threads: 2
queue-capacity: 2000
rejection-policy: CALLER_RUNS # CALLER_RUNS | DROP_NEWEST | DROP_OLDEST | ABORT
keep-alive-seconds: 60
rate-limit:
enabled: false
max-events: 200
window-ms: 1000
per-conversation: true
per-stage: true
max-tracked-buckets: 20000
Optional annotations
JAVA
@EnableConvEngine(stream = true)
@EnableConvEngineAsyncAuditDispatch
@EnableConvEngineStompBrokerRelay
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}

New 1.0.8+ runtime controls explained

  1. Async audit dispatch:
  • Moves transport fan-out off request thread when enabled.
  • Configure with convengine.audit.dispatch.* or @EnableConvEngineAsyncAuditDispatch.
  1. Backpressure policy:
  • Queue capacity + rejection policy control behavior under burst.
  • CALLER_RUNS is safest default; DROP_* favors latency; ABORT is strict.
  1. Stage-level audit controls:
  • level, include-stages, exclude-stages, and rate-limit reduce noisy audit traffic.
  1. Deferred bulk persistence:
  • convengine.audit.persistence.mode=DEFERRED_BULK buffers events and writes batch inserts.
  • Flushes on terminal step/error (configurable), plus request-end safety flush.
  1. STOMP broker mode:
  • SIMPLE (default): in-memory broker.
  • RELAY: external STOMP broker (RabbitMQ/other relay supporting STOMP).

RabbitMQ relay example

application-rabbitmq-relay.yml
YAML
convengine:
transport:
stomp:
enabled: true
endpoint: /ws-convengine
app-destination-prefix: /app
topic-prefix: /topic
audit-destination-base: /topic/convengine/audit
broker:
mode: RELAY
relay-destination-prefixes: /topic,/queue
relay-host: localhost
relay-port: 61613
client-login: guest
client-passcode: guest
system-login: guest
system-passcode: guest
virtual-host: /
system-heartbeat-send-interval-ms: 10000
system-heartbeat-receive-interval-ms: 10000

Redis example (via STOMP gateway/bridge)

Redis note

ConvEngine STOMP relay requires a STOMP-compatible broker endpoint. Redis alone is not a native STOMP broker; use a STOMP gateway/bridge in front of Redis.

application-redis-bridge-relay.yml
YAML
convengine:
transport:
stomp:
enabled: true
broker:
mode: RELAY
relay-destination-prefixes: /topic,/queue
relay-host: redis-stomp-bridge.local
relay-port: 61613
client-login: ""
client-passcode: ""
system-login: ""
system-passcode: ""
virtual-host: ""