Architecture overview
A blind user speaks a command. EchoGuide transcribes it, plans a sequence of interface actions, and performs those actions inside the apps already on the phone. It ships bilingual, Amharic and English.
Five components, five jobs
Section titled “Five components, five jobs”Each component has one input and one output, and no two overlap.
| Component | Input | Output | Runs on |
|---|---|---|---|
| Capture | Microphone | Audio buffer | Phone, Kotlin |
| Transcriber | Audio buffer | Text + confidence | Addis AI, proxied by the backend |
| Planner | Text + screen context | Structured action plan | Addis AI, proxied by the backend |
| Speech | Response text | Audio | Addis AI for Amharic, on-device for English |
| Executor | Action plan | Gestures in other apps | Phone, Kotlin accessibility service |
That separation is the system’s core asset. A transcription fault reproduces from an audio file alone — no phone, no screen state, no model reasoning in the loop.
Context
Section titled “Context”Who touches the system, and what crosses each boundary.
flowchart TD
accTitle: System context
accDescr: A blind user speaks to the mobile client. The client sends audio and screen context to the backend API, which stores data in Postgres and calls Addis AI for speech to text, planning and text to speech. The client performs gestures in the user's own apps. Support staff reach the API over HTTPS.
blind([Blind user]):::person
blind -->|speech| app
subgraph sys[EchoGuide]
app[Mobile client<br/>React Native + Kotlin]
api[Backend API<br/>modular monolith]:::core
db[(Postgres)]
app -->|audio, screen context| api
api --> db
end
app -->|gestures, reads view tree| other[The user's own apps]:::ext
api -->|audio, text, context| addis[Addis AI<br/>STT · LLM · TTS]:::ext
admin([Support staff]):::person -->|HTTPS| api
The phone holds no provider credential. The backend is the only component with API keys. That is also what makes per-user rate limiting and cost attribution possible.
The voice platform
Section titled “The voice platform”Addis AI supplies transcription, planning and speech synthesis. It is built for Amharic and Afaan Oromo, which is why it was chosen over a general-purpose provider.
| Service | Use here | Stated capability |
|---|---|---|
| Speech to text | Command transcription | 3% word error rate on Amharic |
| Text to speech | Spoken responses | 28 production voices, USD 0.032 per minute |
| Language model | Action planning | Addis-፩-አሌፍ |
| Realtime audio | Future pipeline | Speech in, speech out over one WebSocket — beta |
Three consequences follow.
The largest product risk collapses. A general speech model puts Amharic in its low-resource tail. A vendor specialising in Amharic turns that open question into a measurement. The 3% figure is the vendor’s, so it is still verified against a local corpus — see Testing and layout.
One vendor, not two. Transcription and planning share a provider, an account, a rate limit and an outage. The code is simpler and the risk is concentrated. An outage is total loss of function — see Failure and degradation.
No Kotlin SDK exists. The vendor ships JavaScript and Python SDKs plus a REST API. The Android pipeline calls the backend and the backend calls the vendor — which the security model requires anyway, since the phone must never hold a provider key.
The vendor endpoints are OpenAI-compatible, so an adapter written against that shape stays portable if the vendor is ever replaced.
Five drivers
Section titled “Five drivers”Five constraints force the design. Changing one invalidates large parts of it.
| # | Driver | Consequence |
|---|---|---|
| D1 | The executor drives other applications | Android AccessibilityService, which is Kotlin and cannot be JavaScript |
| D2 | Users cannot see the screen | Every state must be announceable; silence reads as a crash |
| D3 | Every command needs a network round trip | No offline mode until the planner runs locally |
| D4 | Audio is intimate by nature | Retention is opt-in; the default path persists nothing |
| D5 | Amharic is the primary language | Vendor chosen for Amharic; accuracy still verified locally |
D1 and D2 are permanent. D3 is expected to change. D4 is a commitment. D5 is why the design names a vendor rather than a category.
Quality targets
Section titled “Quality targets”Targets, not aspirations. Each is measurable.
| Attribute | Target | Measured how |
|---|---|---|
| Time to first audio | p50 under 3.5 s, p95 under 6 s | Client span, end of speech to first TTS byte |
| Time to acknowledgement | Under 400 ms | Spoken confirmation before the pipeline completes |
| Command success rate | Above 90% for English at launch | Executed plan matches intent, sampled by review |
| Transcription rejection rate | Below 8% | Confidence-gate rejections over total commands |
| API availability | 99.5% monthly | Synthetic probe against /health |
| Executor safety | Zero unintended destructive actions | Audit of executed plans against the allowlist |
| Cold start to listening | Under 2 s | First frame to wake word active |
| Crash-free sessions | Above 99.5% | Crash reporter |
Executor safety is the only target with no acceptable non-zero value. A misfire on a banking app does more damage than a week of downtime.
Reading order
Section titled “Reading order”Each page covers one part of the system. Start with the mobile client and read down, or jump to what you need.