Skip to main content

A self-hosted, provider-agnostic voice assistant that delivers structured executive briefings via voice or text from 10 LLM providers.

Project description

Àkàndé logo

Àkàndé

A self-hosted, provider-agnostic voice assistant that delivers structured executive briefings from any of ten LLM providers — including fully private local inference via Ollama and LM Studio.

CI Regression PyPI Python versions License OpenSSF Scorecard


Contents

Getting started

Surface

Operational


Install

Prerequisites

Dependency Why Ubuntu / Debian macOS
Python 3.10+ Runtime sudo apt install python3.12 python3.12-venv brew install python@3.12
portaudio (optional) Microphone capture ([mic] extra) sudo apt install portaudio19-dev brew install portaudio
ffmpeg Audio decoding sudo apt install ffmpeg brew install ffmpeg

From PyPI

# Core install — provider SDKs and mic capture are optional extras.
pip install akande

# Full kit: every provider + microphone + MCP.
pip install "akande[all,mic,mcp]"

From source

git clone https://github.com/sebastienrousseau/akande
cd akande
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"        # bundles every test-relevant extra

Extras index

Extra Pulls in Enables
mic pyaudio Microphone capture (requires PortAudio system headers)
anthropic / google / mistral / cohere / huggingface / groq the matching SDK The corresponding LLM_PROVIDER value
offline-tts pyttsx4 Offline TTS fallback
tts-local kokoro-onnx Local Kokoro-82M TTS (AKANDE_TTS=kokoro)
watermark audioseal, torch AudioSeal voice watermarking (Article 50 §2)
redact presidio-analyzer Higher-recall PII redaction in the cache
memory mem0ai Long-term memory façade
mcp mcp Run / consume Model Context Protocol servers
redis redis Distributed rate limiter for the web server
all every provider SDK + pyttsx4 Provider-agnostic deployments
dev testing + lint + audit + every provider SDK + mcp Local development

Quick Start

# 1. Install the core + the mic extra.
pip install "akande[mic]"

# 2. Point at a provider.
export LLM_PROVIDER=openai
export OPENAI_API_KEY=sk-your-key-here

# 3. Launch the TUI.
akande

The TUI accepts spoken or typed questions and renders the briefing as it streams in. PDF and CSV artefacts are written to a date-keyed output directory on every answered question.

Use as a library

"""Ask Àkàndé a question programmatically."""
import asyncio

from akande.akande import Akande
from akande.providers import get_provider


async def main() -> None:
    # 1. Pick any of the ten configured providers by name.
    provider = get_provider("openai")             # honours $OPENAI_API_KEY
    akande = Akande(openai_service=provider)

    # 2. Ask a question.  The four-section briefing comes back as plain text.
    question = "What is quantitative easing?"
    response = await akande.openai_service.generate_response(
        user_prompt=question,
        system_prompt="You are an executive briefing assistant.",
        model="gpt-4o-mini",
    )

    # 3. Print the structured briefing.  `choices[0].message.content` follows
    # the OpenAI-shaped response envelope used by every provider.
    print(response.choices[0].message.content)


if __name__ == "__main__":
    asyncio.run(main())

Provider configuration

Set LLM_PROVIDER in your environment (or .env file). Each provider reads its own credentials from environment variables.

Provider LLM_PROVIDER Required env vars Install Default model
OpenAI openai OPENAI_API_KEY (included) gpt-3.5-turbo¹
Anthropic anthropic ANTHROPIC_API_KEY pip install akande[anthropic] claude-3-haiku-20240307
Google Gemini google GOOGLE_API_KEY pip install akande[google] gemini-pro
Mistral mistral MISTRAL_API_KEY pip install akande[mistral] mistral-small-latest
Cohere cohere COHERE_API_KEY pip install akande[cohere] command-r
Hugging Face huggingface HUGGINGFACE_API_KEY pip install akande[huggingface] mistralai/Mistral-7B-Instruct-v0.2
Groq groq GROQ_API_KEY pip install akande[groq] llama3-8b-8192
Azure OpenAI azure_openai AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT (included) gpt-35-turbo
Ollama ollama OLLAMA_HOST (optional) (included) llama3
LM Studio lmstudio LMSTUDIO_HOST (optional) (included) local-model

¹ Override per-call with the model argument or globally with OPENAI_DEFAULT_MODEL.

Install every provider SDK at once with pip install akande[all].


Profiles and modes

Àkàndé exposes two orthogonal sovereignty switches.

AKANDE_PROFILE selects the compliance posture:

Profile EU residency Audio watermark Audit signing Telemetry opt-in
local (default) off off off
eu enforced on on off
strict enforced on on off
internal on on on (opt-in only)

AKANDE_MODE selects the network posture:

Mode Provider gate Cache writes
online (default) any provider enabled
offline ollama or lmstudio only enabled
# EU-residency-aware cloud setup
export AKANDE_PROFILE=eu AKANDE_MODE=online

# Fully air-gapped local stack
export AKANDE_PROFILE=strict AKANDE_MODE=offline LLM_PROVIDER=ollama

Interaction modes

Mode How to launch What you get
TUI (default) akande Textual chat UI with streaming, voice toggle, history, export
Classic CLI akande --classic Numbered menu: voice, text, server, quit
Web server akande → start server (or library Akande.start_server()) CherryPy server at http://127.0.0.1:8080 with SSE briefing endpoint
MCP server akande mcp serve Expose Àkàndé as MCP tools (Claude Desktop, Cursor, Continue)
Library from akande.akande import Akande Programmatic embedding

Subcommands

akande --help                  # top-level help
akande --version               # installed version

# GDPR data subject controls (export / delete)
akande data export --user alice --output alice.json
akande data delete --user alice --yes

# Audit verification — Ed25519-signed briefing sidecars
akande verify-audit  path/to/briefing.audit.json
akande verify-pdf    path/to/briefing.pdf
akande verify-watermark path/to/briefing.mp3 --threshold 0.5

# Model Context Protocol
akande mcp serve                # stdio MCP server (Claude Desktop ready)
akande mcp serve --http         # streamable HTTP transport
akande mcp list                 # list configured upstream servers
akande mcp list <server>        # introspect a server's tools

# One-shot fully-offline bootstrap
akande install-local --model llama3.1 --env-path .env

# Skill management
akande skill list
akande skill enable web_search
akande skill consent web_search
akande skill revoke web_search

Skills

Skills are specialised handlers the router picks over a generic LLM call. Five ship in the box; third-party skills register via the akande.skills entry-point group.

Skill Match Consent required Offline-safe
briefing default no yes
web_search search, look up …, find … yes no
weather weather in …, forecast … no no
finance price of …, ticker … no no
policy (gate) always — enforces consent n/a yes
"""Register a third-party skill via the entry-point group."""
# pyproject.toml
# [project.entry-points."akande.skills"]
# my_skill = "my_package.skill:MySkill"

from akande.skills.base import Skill, SkillMeta, Intent, SkillContext, SkillResult


class MySkill(Skill):
    @property
    def meta(self) -> SkillMeta:
        return SkillMeta(
            name="my_skill",
            description="One-line description of what this skill does.",
            requires_consent=True,
        )

    def match(self, text: str) -> Intent | None:
        if text.lower().startswith("my-skill:"):
            return Intent(name="my_skill", raw_text=text)
        return None

    def handle(self, intent: Intent, ctx: SkillContext) -> SkillResult:
        return SkillResult(content=f"Handled: {intent.raw_text}")

Model Context Protocol

Àkàndé can serve and consume MCP. The server exposes the briefing, audit, and skill surface as MCP tools; the client introspects upstream servers configured in ~/.akande/mcp.json.

# Serve over stdio for Claude Desktop / Cursor / Continue.
akande mcp serve

# Or streamable HTTP for HTTP-only hosts.
akande mcp serve --http

Claude Desktop drop-in (claude_desktop_config.json):

{
  "mcpServers": {
    "akande": {
      "command": "akande",
      "args": ["mcp", "serve"]
    }
  }
}

Compliance

Àkàndé ships the controls required by EU AI Act Article 50 (in force 2026-08-02) out of the box when AKANDE_PROFILE=eu (or strict):

  • AI disclosure — every briefing carries a machine-readable disclosure block (akande.disclosure)
  • AudioSeal watermark — synthesised audio is watermarked when the [watermark] extra is installed; absence is logged but never blocks
  • Ed25519-signed audit sidecars — every PDF + CSV is paired with a .audit.json signed at write time; akande verify-audit re-verifies
  • GDPR data export / deleteakande data export|delete against the SQLite conversation store
  • Consent log — voice-cloning prompts require explicit consent recorded in the audit chain

Troubleshooting

Problem Cause Fix
Could not find PyAudio PortAudio system headers missing Ubuntu: sudo apt install portaudio19-dev. macOS: brew install portaudio. Then pip install akande[mic].
ffmpeg not found ffmpeg not installed Ubuntu: sudo apt install ffmpeg. macOS: brew install ffmpeg.
Microphone not detected OS permissions Grant microphone access in system settings.
ModuleNotFoundError: No module named 'anthropic' Provider SDK not installed pip install akande[anthropic] (or the relevant provider extra).
Invalid or missing OPENAI_API_KEY Key not set or malformed Ensure your environment or .env contains a valid sk- prefixed key.
AKANDE_MODE=offline forbids provider openai Offline mode allows only local providers Set LLM_PROVIDER=ollama or LLM_PROVIDER=lmstudio, or switch back to AKANDE_MODE=online.

Trust

  • 785 tests + 95 % line coverage in CI on every push and pull request, on Python 3.10 / 3.11 / 3.12
  • Quality gates: ruff (lint + format), mypy (strict islands on the provider surface), bandit (SAST), pip-audit (vulnerable-deps scan) — all blocking
  • Fresh-install regression matrix (Ubuntu × 3.10/3.11/3.12 + macOS × 3.12) reproduces the user install path on every push
  • Security posture documented in SECURITY.md: CSP nonces, custom-header CSRF, per-IP rate limiting (in-memory or Redis), CSV-formula injection prevention, filename sanitisation, IP hashing in logs

Development

git clone https://github.com/sebastienrousseau/akande
cd akande
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

# Quality gates (mirror CI)
ruff check . && ruff format --check .
mypy akande
pytest -q                # uses the [pytest] cov gate (95 %)
bandit -r akande
pip-audit

# Fresh-install regression on this machine
./scripts/regression.sh

See CONTRIBUTING.md for the full development loop.


License

Dual-licensed under the Apache License, Version 2.0 and the MIT License. See LICENSE-APACHE and LICENSE-MIT for the full text. You may pick whichever fits your project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

akande-0.0.6.tar.gz (191.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

akande-0.0.6-py3-none-any.whl (162.9 kB view details)

Uploaded Python 3

File details

Details for the file akande-0.0.6.tar.gz.

File metadata

  • Download URL: akande-0.0.6.tar.gz
  • Upload date:
  • Size: 191.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for akande-0.0.6.tar.gz
Algorithm Hash digest
SHA256 d56bae8702a536c852012bb3661c47ffba9a24bd0b4b09bfb7b90460fbbd1136
MD5 3262b64a3919962a5f932f18cd823a8e
BLAKE2b-256 c712ebb1cd6fa72c35dc514f5718c6970eb19d143129d901821b2ef416600f90

See more details on using hashes here.

Provenance

The following attestation bundles were made for akande-0.0.6.tar.gz:

Publisher: publish.yml on sebastienrousseau/akande

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file akande-0.0.6-py3-none-any.whl.

File metadata

  • Download URL: akande-0.0.6-py3-none-any.whl
  • Upload date:
  • Size: 162.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for akande-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 04843c9aa10c5bf52f3754d2c327287057138501131dad6cb0ce8395aba6a24d
MD5 c62aae211bcff6350b75a0244c238c81
BLAKE2b-256 e5db733f355c9b01a4612bc109944d5375b60a19f659f7ea0bb3b425aa7ec282

See more details on using hashes here.

Provenance

The following attestation bundles were made for akande-0.0.6-py3-none-any.whl:

Publisher: publish.yml on sebastienrousseau/akande

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page