5.1 KiB
Conversation State Machine
Purpose
The conversation state machine enforces the safe order of an AI Operator call. The assistant cannot answer business questions, search a knowledge base, or execute business tools until both language and region are selected in code.
States
CALL_STARTED
-> GREETING
-> LANGUAGE_SELECTION
-> REGION_SELECTION
-> READY_TO_HELP
-> QUESTION_ANSWERING
-> READY_TO_HELP
-> CLOSING
-> ENDED
HANDOFF can be entered from any non-ended state. CLOSING and ENDED can also be entered from any non-ended state. ENDED is immutable.
Transition Table
| From | Event | To | Requirement |
|---|---|---|---|
| CALL_STARTED | call.started | GREETING | call session exists |
| GREETING | greeting.played | LANGUAGE_SELECTION | bilingual greeting prepared |
| LANGUAGE_SELECTION | language.selected | REGION_SELECTION | language is ru or kk |
| REGION_SELECTION | region.selected | READY_TO_HELP | normalized region code is selected |
| READY_TO_HELP | question.received | QUESTION_ANSWERING | language and region selected |
| QUESTION_ANSWERING | answer.completed | READY_TO_HELP | answer flow completed |
| any non-ended | handoff.requested | HANDOFF | none |
| any non-ended | closing.requested | CLOSING | none |
| any non-ended | call.ended | ENDED | none |
Invalid transitions return errors and do not mutate state. Denied actions are recorded in session history.
Tool Permission Matrix
| State | Allowed Tools |
|---|---|
| CALL_STARTED | none |
| GREETING | none |
| LANGUAGE_SELECTION | set_language, request_human_handoff, end_call |
| REGION_SELECTION | set_region, set_language, request_human_handoff, end_call |
| READY_TO_HELP | search_knowledge_base, set_language, set_region, request_human_handoff, end_call |
| QUESTION_ANSWERING | search_knowledge_base, request_human_handoff, end_call, set_language, set_region |
| HANDOFF | end_call |
| CLOSING | end_call |
| ENDED | none |
Hard Guardrail
search_knowledge_base is denied unless all of these are true:
- language is
ruorkk; - region status is
selected; - region code is not empty;
- state is
READY_TO_HELPorQUESTION_ANSWERING.
This is enforced in Go code by internal/dialogue/policy, independently of prompts.
Messages
The message catalog has bilingual initial greeting plus Russian and Kazakh fragments for language, region, ready, denial, handoff, and closing states.
Initial greeting:
Здравствуйте! Это AI-оператор. Выберите язык обслуживания: русский или қазақша.
Сәлеметсіз бе! Бұл AI-оператор. Қызмет көрсету тілін таңдаңыз: қазақша немесе русский.
Prompt Fragments
internal/dialogue/prompt builds state-aware prompt fragments that include current state, language, region, next action, and forbidden actions. Prompt fragments are secondary; policy enforcement remains in Go code.
CLI Usage
./bin/ai-operator doctor --env /etc/ai-operator/ai-operator.env --check-dialogue
./bin/ai-operator dialogue-self-test --env /etc/ai-operator/ai-operator.env
./bin/ai-operator dialogue-self-test --env /etc/ai-operator/ai-operator.env --json
The self-test runs without Asterisk calls, OpenAI, database, or external services.
Integration
For the test route only, Call Manager creates a Dialogue Orchestrator session before starting the voice provider. The provider receives a state-aware system prompt. On hangup, Call Manager ends and cleans the dialogue session.
Production Kazakhtelecom routes remain disabled.
Not Implemented Yet
- language detection from speech;
- region resolver;
- Knowledge Base/RAG;
- final agent prompt;
- real business tools;
- production route switch.
TZ-07 Language Detector
Language selection is now handled by internal/dialogue/language. The state machine still stores strict ru or kk, while detector input can be natural text such as русский, қазақша, russian, or kazakh.
TZ-08 Region Resolver Update
TZ-08 adds an offline Kazakhstan Region Resolver with 20 enabled regions, stable region_code values, Almaty city/region clarification, false-positive protection, and explicit region-change policy. Production routing remains disabled; OpenAI, PostgreSQL, and Knowledge Base/RAG are still not used at this stage.
TZ-09 Knowledge Base Update
TZ-09 adds PostgreSQL + pgvector, KGA JSONL ingestion, fake embeddings, hybrid KB search, cross-language fallback for KK queries, citations, and search_knowledge_base integration behind the existing language/region guardrail. OpenAI is not called automatically and production routing remains disabled.
TZ-10 Agent Integration
The state machine remains the hard gate for business answers. Agent prompt instructions are secondary; search_knowledge_base is still denied before language and region are selected. ToolCall results now flow back to the VoiceProvider.
TZ-11 Handoff
request_human_handoff moves active conversations to HANDOFF. Repeated handoff requests are idempotent. ENDED remains immutable.