# AI Operator Go skeleton for an Asterisk-based AI call-center operator. Current status: skeleton only. The project does not accept live calls, does not connect to ARI events, does not create media channels, and does not call OpenAI. ## Build ```sh make build ``` ## Test ```sh make fmt make test ``` ## Doctor ```sh ./bin/ai-operator doctor --env /etc/ai-operator/ai-operator.env ``` The doctor command validates local-only ARI configuration and checks authenticated HTTP 200 plus unauthenticated HTTP 401. ## Dry Run ```sh ./bin/ai-operator run --env /etc/ai-operator/ai-operator.env --dry-run ``` ## Runtime Env The server env file is expected at: ```text /etc/ai-operator/ai-operator.env ``` Do not commit real secrets. Use `.env.example` as the only repository env template. ## Next Steps - TZ-02: Asterisk inbound routing preparation. - TZ-03: ARI Call Manager. - TZ-04: Media Gateway. - TZ-05: Voice Provider Adapter. ## ARI Observe-only ```sh ./bin/ai-operator run --env /etc/ai-operator/ai-operator.env --ari-events --observe-only ``` This registers ARI app `ai-operator` and reads events without answering or hanging up channels. ## ARI Test Call-control ```sh ./bin/ai-operator run --env /etc/ai-operator/ai-operator.env --ari-events --call-control --test-call-hangup-after 5s ``` Call-control is limited to the test route `Stasis(ai-operator,test)`. Media and OpenAI are not implemented in TZ-03. ## Media Self-test ```sh ./bin/ai-operator media-self-test --env /etc/ai-operator/ai-operator.env --duration 3s ``` This creates a temporary Asterisk externalMedia WebSocket channel, connects to `/media/{connection_id}`, waits for `MEDIA_START`, sends `GET_STATUS`, and cleans up. It does not make a real phone call and does not record audio. ## ARI Media Test Mode ```sh ./bin/ai-operator run --env /etc/ai-operator/ai-operator.env --ari-events --call-control --media --media-test-mode stats --test-call-hangup-after 10s ``` This is restricted to the test route `Stasis(ai-operator,test)`. Production Kazakhtelecom routes remain disabled. ## Voice Provider Default provider is `fake`. Live modes are explicit: `openai_realtime` or `pipeline_elevenlabs_streaming`. The ElevenLabs streaming pipeline requires `ELEVENLABS_API_KEY`, `ELEVENLABS_VOICE_ID_RU`, and `OPENAI_API_KEY`. ```sh ./bin/ai-operator voice-provider-self-test --env /etc/ai-operator/ai-operator.env --provider fake ./bin/ai-operator doctor --env /etc/ai-operator/ai-operator.env --check-openai-config ./bin/ai-operator pipeline-streaming-self-test --env /etc/ai-operator/ai-operator.env ``` Live ElevenLabs streaming test command: ```sh ./bin/ai-operator run --env /etc/ai-operator/ai-operator.env --ari-events --call-control --media --voice-provider pipeline_elevenlabs_streaming --media-test-mode stats --test-call-hangup-after 180s ``` ## Conversation State Machine TZ-06 adds a code-enforced conversation state machine. The current live behavior is natural dialogue: language can be inferred from caller speech, and global KB search is allowed without a selected region. Region is requested only for regional questions. ```bash ./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 ``` The state machine uses the fake provider by default and does not call OpenAI. ## Language Selection TZ-07 adds a language detector for Russian and Kazakh. It supports codes, Cyrillic/Latin phrases, ASR-like variants, ambiguity detection, and false-positive protection. ```bash ./bin/ai-operator doctor --env /etc/ai-operator/ai-operator.env --check-language ./bin/ai-operator language-self-test --env /etc/ai-operator/ai-operator.env ``` ## 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 Prompt and Tools Agent Prompt and Tools are implemented for safe test mode. The live operator is Жанна, AI-operator of QazAimaqGas. The prompt no longer uses IVR-style language/region selection: language is inferred from caller speech, global KB can be searched without region, and region is requested only for regional branch/address/contact questions. `search_knowledge_base` returns `answer_text`, citations, no-answer behavior, and cross-language fallback metadata. VoiceProvider ToolCall events are relayed through Dialogue Orchestrator and ToolResults are sent back to the provider. Offline validation: ```bash ./bin/ai-operator agent-self-test --env /etc/ai-operator/ai-operator.env ./bin/ai-operator natural-dialogue-self-test --env /etc/ai-operator/ai-operator.env ``` ## TZ-11 Human Handoff / Fallback Human Handoff / Fallback is implemented in safe default mode. `HANDOFF_MODE=disabled_stub` and `HANDOFF_ENABLED=false` record the handoff request and move the conversation to `HANDOFF` without real transfer. ARI redirect and dialplan continue actions exist behind config gates and are covered by tests. Safe validation: ```bash ./bin/ai-operator handoff-self-test --env /etc/ai-operator/ai-operator.env ./bin/ai-operator fallback-self-test --env /etc/ai-operator/ai-operator.env ``` ## TZ-12 Logging, Transcripts and Audit Audit logging now uses PostgreSQL tables from `migrations/003_audit_tables.sql`. Use `audit-health`, `audit-self-test`, `redaction-self-test`, `audit-show-call`, `audit-export-call`, `audit-prune --dry-run`, and `doctor --check-audit`. Raw transcripts/audio and secrets are not stored by default.