Capabilities
The Capability Model¶
Every app accesses the world through capabilities, never direct tools. A capability is a human verb — think, read, write, search, speak, listen, draw — with a chain of providers that try in order until one succeeds.
Human is always the final fallback. If every tool is offline, the system asks you.
7 Capabilities¶
| Capability | Purpose | Providers |
|---|---|---|
| think | LLM reasoning | ollama, openai, claude-cli, human |
| read | Read files | filesystem, human |
| write | Write files | filesystem, human |
| search | Find content | grep, human |
| speak | Text to speech | voice-api (kokoro, edge-tts, xtts) |
| listen | Speech to text | voice-api (whisper) |
| draw | Image generation | comfyui |
Provider Chains¶
Providers are tried in priority order. Plugins inject high-priority providers at startup (enhancer pattern).
think: ollama → openai → claude-cli → human
read: filesystem → human
write: filesystem → human
search: grep → human
speak: voice-api (kokoro → edge-tts → xtts)
listen: voice-api (whisper)
draw: comfyui
If a plugin is absent, its provider simply isn't in the chain. Apps never know which provider answered — they just call self.think() or self.search().
Domain Routing¶
The think capability supports domain-specific routing. Different domains can use different models:
# Uses the domain-specific provider chain for 'code'
result = await self.think("Analyze this", domain="code")
# Default chain
result = await self.think("Summarize this article")
Domains are configured in emptyos.toml under [capabilities.think.domains].