Files
ai-operator/docs/conversation-state-machine.md

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 ru or kk;
  • region status is selected;
  • region code is not empty;
  • state is READY_TO_HELP or QUESTION_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.