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].