New Consumer Onboarding
This document provides the standard onboarding path for teams integrating ConvEngine into their application.
Start with the right baseline
Day-0 decisions
| Decision | Why it matters | Recommended default |
|---|---|---|
| Java baseline | ConvEngine compiles against Java 21. | Standardize on Java 21 in all environments. |
| Conversation concurrency | The framework does not enforce optimistic locking for `ce_conversation`. | Allow only one active turn per `conversationId`. |
| Transport | Streaming is optional but changes operational setup. | Start with SSE only; enable STOMP later if you truly need it. |
| Prompt contract discipline | Current v2 uses prompts for both text generation and turn behavior metadata. | Treat `ce_prompt_template` as a runtime contract. |
| MCP adoption | The current MCP model is powerful, but adds scale. | Start with one narrow intent-scoped tool flow before scaling out. |
Add the framework dependency
Use the current framework version from the repo: convengine:2.0.12
- pom.xml
- build.gradle.kts
<dependency>
<groupId>com.github.salilvnair</groupId>
<artifactId>convengine</artifactId>
<version>2.0.12</version>
</dependency>
implementation("com.github.salilvnair:convengine:2.0.12")
Enable the framework in your Spring Boot app
The minimal production-friendly baseline requires enabling the core engine, cache, and async features. You still need to provide one production-grade LlmClient bean and your own database connection details.
@SpringBootApplication
@EnableConvEngine(stream = true)
@EnableConvEngineCaching
@EnableConvEngineAsyncConversation
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Apply Schema and Seed Configuration (DDL/DML)
Before you test any conversation flow, create the ce_* tables and seed the control plane configurations. We provide snippets here representing the foundational ce_config as well as data examples referenced in the REST API examples.
- Core Base Seed
- FAQ Setup Example
- Zapper Demo (MCP + SQL)
-- Example subset of standard configuration properties
INSERT INTO ce_config(config_id, config_type, config_key, config_value, enabled) VALUES
(1, 'AgentIntentResolver', 'MIN_CONFIDENCE', '0.55', true),
(2, 'AgentIntentResolver', 'COLLISION_GAP_THRESHOLD', '0.2', true),
(8, 'McpPlanner', 'SYSTEM_PROMPT', 'You are an MCP planning agent inside ConvEngine...', true),
(11, 'DialogueActStep', 'SYSTEM_PROMPT', 'You are a dialogue-act classifier...', true),
(17, 'DialogueActStep', 'REGEX_AFFIRM', '^(\\s)*(yes|yep|yeah|ok|okay|sure|go ahead)(\\s)*$', true);
A simple informational (FAQ) setup. Informational intents do not require advanced MCP tooling or semantic schemas, just intent definitions and prompt responses.
-- Define the intent
INSERT INTO ce_intent (intent_code, description)
VALUES ('FAQ_BUSINESS_HOURS', 'User is asking about standard business operating hours');
-- Define simple regex classification (if bypass LLM desired)
INSERT INTO ce_intent_classifier (rule_type, pattern, intent_code, state_code, priority)
VALUES ('REGEX', '.*what are your hours.*', 'FAQ_BUSINESS_HOURS', 'COMPLETED', 10);
-- Define text response
INSERT INTO ce_prompt_template (intent_code, state_code, response_type, system_prompt, user_prompt, interaction_mode)
VALUES ('FAQ_BUSINESS_HOURS', 'COMPLETED', 'LLM',
'You are a helpful assistant. Provide business hours directly.',
'Our corporate hours are Monday–Friday from 9:00 AM to 5:00 PM CST.', 'FINAL');
This corresponds to the "disconnect request" schema utilized in multiple semantic and REST API documentation pages.
CREATE TABLE IF NOT EXISTS zp_disco_request (
request_id VARCHAR(64) PRIMARY KEY,
customer_name VARCHAR(200) NOT NULL,
customer_id VARCHAR(64) NOT NULL,
feeder_id VARCHAR(64) NOT NULL,
status INTEGER NOT NULL DEFAULT 0,
assigned_team VARCHAR(64),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS zp_disco_trans_data (
id BIGSERIAL PRIMARY KEY,
request_id VARCHAR(64) NOT NULL REFERENCES zp_disco_request(request_id) ON DELETE CASCADE,
action_id INTEGER NOT NULL,
status INTEGER NOT NULL,
logged_user_id VARCHAR(64) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
INSERT INTO zp_disco_request (
request_id, customer_name, customer_id, feeder_id, status, assigned_team, updated_at
) VALUES
('REQ-20260311-0001', 'UPS', 'CUST102', 'FD-IRV-1022', 700, 'TEAM1', NOW()),
('REQ-20260311-0002', 'UPS', 'CUST102', 'FD-COP-2210', 810, 'TEAM2', NOW()),
('REQ-20260311-0003', 'UPS', 'CUST102', 'FD-MISS-0077', 404, 'TEAM1', NOW());
Establish Core application.yml Baseline
Establish your runtime defaults. Use application.yml for system properties. A full breakdown of these fields is available in the Configuration component reference.
convengine:
flow:
dialogue-act:
resolute: REGEX_THEN_LLM
llm-threshold: 0.90
conversation-history:
max-turns: 20
interaction-policy:
execute-pending-on-affirm: true
reject-pending-on-negate: true
fill-pending-slot-on-non-new-request: true
transport:
sse:
enabled: true # Standard recommendation
stomp:
enabled: false # Switch to true only if websocket needed
audit:
enabled: true # Mandatory for ce_verbose & tracing
persist-meta: true
persistence:
mode: IMMEDIATE
mcp:
guardrail:
enabled: false
Configure Semantic Layer (If applicable)
If utilizing the Semantic Query module, provision the semantic model DB tables (ce_semantic_*) using your semantic SQL bootstrap scripts (for example, semantic_layer_yml_ddl.sql + semantic_layer_yml_dml.sql). This abstracts specific physical model knowledge from generic engine functionality. See Configuration for specifics.
semantic-query:
enabled: true
schema:
# Model physical connections
relationships:
- name: "Request to Action Log"
fromTable: "zp_disco_request"
fromColumn: "request_id"
toTable: "zp_disco_trans_data"
toColumn: "request_id"
entities:
- name: "DisconnectRequest"
primaryTable: "zp_disco_request"
synonyms: ["disco", "cancellation", "shut off"]
fields:
- name: "request_id"
type: "STRING"
physicalColumn: "request_id"
- name: "status"
type: "INTEGER"
physicalColumn: "status"
# Dictates strict known outcomes to constrain the AST planner
valueDefinitions:
- label: "completed"
value: "835"
- label: "cancelled"
value: "120"
intentRules:
- intent: "SEMANTIC_QUERY"
requiredFields: ["status"]
If a query does not work as expected, verify:
- Missing or Invalid Filters: Check
ce_semantic_entityto ensure synonyms align with the user request vocabulary. - Failures Memory Cache: Inspect physical table
ce_semantic_query_failures. The semantic engine stores failure embeddings here and consults them for subsequent queries to prevent repeated failing logic paths. Use the Cache APIs to refresh query-failures.
Seed one complete vertical slice first
Do not try to model your entire product on day one. Build one narrow, fully testable path:
- one intent
- one or two states
- one response path
- one optional schema
- zero or one tool
That first slice should prove that intent resolves correctly, state transitions are deterministic, a final response always exists, and audit/trace output is understandable. Utilize ce_verbose to provide observable progress.
Treat prompt templates as behavior contracts
ce_prompt_template is no longer just prompt text. In 2.0.9+, prompt rows also document how a state is expected to behave.
Relevant metadata includes interaction_mode and interaction_contract.
Recommended contract patterns:
- collection state:
interaction_mode=COLLECT,interaction_contract={"expects":["structured_input"]} - confirmation state:
interaction_mode=CONFIRM,interaction_contract={"allows":["affirm","edit","reset"]} - final state:
interaction_mode=FINAL
This is what allows CorrectionStep to safely do in-place confirm/edit/retry routing.
Validate with a pre-production checklist
Minimum readiness checklist
| Area | Must prove before rollout | Common failure if skipped |
|---|---|---|
| Single-turn path | One happy-path intent works end-to-end from `/message` to final payload. | Basic config is incomplete or inconsistent. |
| Multi-turn slot collection | Missing fields converge cleanly and stop asking once complete. | Infinite or unstable clarification loops. |
| Confirmation / correction routing | `AFFIRM`, `EDIT`, and `retry` do what the active prompt contract says. | Unexpected reclassification or incorrect continuation. |
| State coverage | Every reachable state has a valid response strategy. | Fallback or misleading output in production. |
| Concurrency guard | Parallel same-ID requests do not corrupt state. | Last-write-wins drift. |
| Trace usability | Your team can read audit + trace and explain a bad turn quickly. | Slow incident resolution. |
The right first milestone is not "all features enabled." It is one narrow, testable, traceable business flow that your team can explain end-to-end from input to persisted state to final response.