Skip to main content

A next-generation, highly configurable, and user-friendly Command Line Interface for interacting with Large Language Models.

Project description

k-ai

k-ai is a terminal-first LLM chat system with persistent sessions, runtime transparency, live config mutation, internal tools, and a Python package API.

It is designed around one principle: the chat loop, the slash commands, and the programmatic API should all act on the same session/config/runtime model.

Core Model

                 ┌─────────────────────────────────────┐
                 │           Built-in Defaults         │
                 │   src/k_ai/defaults/defaults.d/     │
                 └─────────────────┬───────────────────┘
                                   │ merge
                 ┌─────────────────▼───────────────────┐
                 │          ConfigManager               │
                 │  override file + live edits + CLI    │
                 └─────────────────┬───────────────────┘
                                   │
        ┌──────────────────────────▼──────────────────────────┐
        │                    ChatSession                       │
        │  prompt loop · tools · digest · compaction · UI     │
        └───────────────┬───────────────────────┬─────────────┘
                        │                       │
            ┌───────────▼──────────┐   ┌───────▼────────┐
            │ SessionStore          │   │ MemoryStore     │
            │ ~/.k-ai/sessions/*.jsonl│  │ ~/.k-ai/MEMORY │
            └──────────────────────┘   └────────────────┘

Features

  • Persistent chat sessions with summary, themes, and session_type.
  • Rich runtime transparency: provider, model, auth mode, token source, context window, compaction threshold, limits.
  • Human-in-the-loop tool approvals with per-tool governance.
  • Full config management from chat, slash commands, or Python.
  • Sandboxed Python and shell tools.
  • QMD-backed history/document retrieval restricted to the k-ai session collection when appropriate.
  • Robust interruption handling for prompt input, generation, and tool execution.
  • Split default config fragments with cached loading for better maintainability and lower parse overhead.
  • Native SKILL.md runtime with project/global discovery, prompt injection, and an internal activate_skill tool.

Problem-First Docs

Long-form architecture docs now live in the standalone docs site:

They are written in the same spirit as tutos_live:

  • problem first
  • real examples
  • ASCII diagrams
  • request payload examples
  • session / memory / tool-governance workflows

Quick Start

git clone https://github.com/kpihx/k-ai.git
cd k-ai
make install
k-ai chat

Installation profiles:

Installer behavior highlights:

  • interactive by default, with explicit choices shown for each meaningful case
  • prefers uv when available
  • if uv is missing, proposes installing it
  • if uv is declined, falls back to an isolated k-ai bootstrap virtualenv instead of polluting the system Python
  • asks which live capability families should start enabled: exa, python, shell, qmd
  • can skip verification entirely via install/install.yaml when used inside controlled test harnesses
  • installs a managed runtime .gitignore in ~/.k-ai/
  • initializes a local git repo in ~/.k-ai/ and creates the first commit
  • can auto-commit runtime state on each interactive chat exit using the session digest as the commit subject

You can keep the default interactive install, explicitly target the default profile, or point to your own:

./scripts/install.sh
./scripts/install.sh -p
./scripts/install.sh -p defaults
./scripts/install.sh --path /path/to/my-install.yaml

Development:

uv sync --dev
uv run pytest -q
uv run k-ai chat

Skills runtime defaults:

  • project overlays: .k-ai/skills, .agents/skills
  • global skills: ~/.agents/skills
  • inspection commands: /skills, /skills show <name>, /skills reload, /skills active

Hooks runtime defaults:

  • project overlays: .k-ai/hooks, .agents/hooks
  • global hooks: ~/.agents/hooks
  • discovered config files per root: hooks.yaml, hooks.yml, hooks.json
  • supported events: SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, Stop
  • inspection commands: /hooks, /hooks reload

MCP runtime defaults:

  • config fragment: src/k_ai/defaults/defaults.d/60-mcp.yaml
  • first bundled server: filesystem via mcp-server-filesystem
  • transport foundation: official Python mcp SDK over stdio, streamable_http, and sse
  • roots: workspace root exposed by default to MCP servers that request them
  • protocol surfaces exposed: tools, resources, resource templates, prompts, roots
  • inspection/admin commands:
    • /mcp
    • /mcp tools
    • /mcp resources [server]
    • /mcp templates [server]
    • /mcp prompts [server]
    • /mcp probe <name> [command_or_package]
    • /mcp install <name> [package] [binary]
    • /mcp add-stdio <name> <command> [cwd]
    • /mcp add-http <name> <url> [streamable_http|sse]
    • /mcp enable|disable <name>
    • /mcp remove <name>
    • /mcp reload

The staged architecture roadmap for skills, hooks, filesystem editing, and MCP is tracked in VISION.md.

Published package identity:

  • PyPI distribution name: kpihx-ai
  • import module: k_ai
  • installed CLI command: k-ai

If you install from PyPI instead of from source:

uv tool install kpihx-ai
# or
pipx install kpihx-ai

Installation and Removal

Install:

make install
# or directly:
./scripts/install.sh
# or with an explicit install profile:
./scripts/install.sh -p defaults
./scripts/install.sh --path ./install/install.yaml

Purge runtime state:

make purge
# or directly:
./scripts/purge.sh --yes
# or for a custom runtime root:
./scripts/purge.sh --yes --runtime-dir /path/to/runtime

Make targets:

make install
make purge
make check
make test
make build
make publish
make push
make push-docs
make release

Runtime Store Versioning

The local runtime store ~/.k-ai/ is now treated as a narrow git repo.

Tracked:

  • config.yaml
  • MEMORY.json
  • sessions/index.json
  • sessions/*.jsonl

Ignored:

  • sandbox/
  • any other runtime-heavy or ephemeral artifact outside the tracked list

The installer copies the managed template from install/.gitignore.runtime, initializes ~/.k-ai/.git/, runs the first git add ., and creates the initial commit.

During normal interactive use, k-ai can also auto-commit runtime changes on chat exit. The generated commit subject uses the session digest, for example:

chat: Présentation détaillée de l'assistant k-ai

CLI Usage

Interactive chat

k-ai chat
k-ai chat --provider mistral
k-ai chat --provider openai --model gpt-4o
k-ai chat --config ~/.k-ai/config.yaml
k-ai chat --temperature 0.2 --max-tokens 4096

Config CLI

Show the full built-in default template:

k-ai config show

List built-in config fragments:

k-ai config sections

Show only selected built-in fragments:

k-ai config show --section ui
k-ai config show --section models --section governance

Export the full default config:

k-ai config get -o my-config.yaml

Export only one or several sections to build a minimal override file:

k-ai config get -o prompts.yaml --section ui
k-ai config get -o providers-and-tools.yaml --section models --section governance

Open the active config or one built-in fragment in your editor:

k-ai config edit all
k-ai config edit ui
k-ai config edit governance
/config edit governance

Editor resolution order:

  • config.editor
  • K_AI_EDITOR
  • VISUAL
  • EDITOR
  • nano

Tool proposal transparency:

  • cli.show_tool_rationale: true keeps a justification panel visible before each tool.
  • if the model emits no explanation, k-ai derives a fallback rationale from the tool description and main input.

OAuth note:

  • oauth.gemini is implemented through a Google token JSON file.
  • token_path should point to a persisted token containing at least access_token.
  • If the token is expired, refresh_token, client_id, and client_secret are used to refresh it automatically.

Run diagnostics:

k-ai doctor
k-ai doctor --reset config
k-ai doctor --reset all

Slash Commands

Session lifecycle:

  • /sessions [recent|oldest] [classic|meta]
  • /load <id> [last_n]
  • /extract <id> [offset] [limit]
  • /digest [id]
  • /compact
  • /delete <id>
  • /new [classic|meta]

Runtime/config:

  • /status
  • /tokens
  • /settings [prefix]
  • /set <key> <value>
  • /model [name]
  • /provider [name] [model]
  • /tools capabilities
  • /tools enable|disable <exa|python|shell|qmd|mcp>
  • /mcp [list|tools|resources|templates|prompts|reload|probe|install|add-stdio|add-http|enable|disable|remove]
  • /config show [key]
  • /config show section:<name> [section:<name> ...]
  • /config get [path] [section ...]
  • /config save [path]
  • /config sections
  • /config edit [all|models|ui|sessions|governance|skills|hooks|mcp]

Tools and memory:

  • live capability switching only applies to mutable families (exa, python, shell, qmd, mcp)
  • protected admin approval rules remain YAML-only by design
  • /tools show [ask|auto|default|session|global|protected]
  • /tools ask|auto <target> [session|global] [tool|category|risk]
  • /tools reset <target> [session|global] [tool|category|risk]
  • /memory list|add|remove
  • /qmd query|search|get|ls|status|update|embed|cleanup

Everything above can also be triggered by the model through internal tools when appropriate.

Config Layout

Built-in defaults are split into four fragments:

src/k_ai/defaults/defaults.d/
├── 00-models.yaml
├── 10-ui-prompts.yaml
├── 20-sessions-memory.yaml
└── 30-runtime-governance.yaml

Section names exposed in CLI:

  • models
  • ui
  • sessions
  • governance

Recommended override strategy:

1. Export only the sections you want to change.
2. Edit that smaller YAML file.
3. Pass it with --config or save it as ~/.k-ai/config.yaml.
4. Keep runtime-only experiments in chat via /set or the config tools.

Package Usage

Defaults only

from k_ai import ConfigManager, ChatSession
import asyncio

cm = ConfigManager()
session = ChatSession(cm)
asyncio.run(session.send("Bonjour"))

Custom override file

from k_ai import ConfigManager, ChatSession

cm = ConfigManager(override_path="~/.k-ai/config.yaml")
session = ChatSession(cm, provider="mistral")

You can also keep several smaller override files and choose one at startup:

cm = ConfigManager(override_path="~/profiles/k-ai-prompts.yaml")

Inline overrides

cm = ConfigManager(
    override_path="~/.k-ai/config.yaml",
    temperature=0.2,
    max_tokens=4096,
)

Export only one built-in section

from k_ai import ConfigManager

yaml_text = ConfigManager.get_default_yaml(sections=["ui"])
print(yaml_text)

List built-in sections

from k_ai import ConfigManager

for section in ConfigManager.list_default_sections():
    print(section["name"], section["file"])

Agentic programmatic call with tools

import asyncio
from k_ai import ConfigManager, ChatSession, ToolCall

cm = ConfigManager()
session = ChatSession(cm)

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {
            "type": "object",
            "properties": {"location": {"type": "string"}},
            "required": ["location"],
        },
    },
}]

async def executor(tc: ToolCall) -> str:
    if tc.function_name == "get_weather":
        return f"22°C in {tc.arguments['location']}"
    raise ValueError(tc.function_name)

result = asyncio.run(session.send_with_tools("Weather in Paris?", tools, executor))
print(result)

Runtime Transparency

The terminal runtime panel exposes:

  • current provider / model / auth mode
  • context usage and remaining capacity
  • compaction threshold
  • cumulative tokens
  • token source: provider or estimated
  • render mode
  • tool result display/history limits
  • config persistence path
  • current session id / type

This is UI-only telemetry; it does not consume model tokens.

Robustness Notes

  • Ctrl+C at prompt: first press cancels input, second press exits.
  • Ctrl+C during generation or tool execution: returns control to the prompt.
  • Boot greeting failures do not create a session.
  • Programmatic send() / send_with_tools() now rollback the whole turn on LLM failure instead of leaving partial persisted turns.
  • Digest/compaction/exit summarization are best-effort; if the provider fails, the session remains usable and the main conversation state is preserved.
  • Tool approval overrides are validated strictly against the built-in tool catalog, so malformed config fails fast instead of silently drifting.

Runtime State on Disk

~/.k-ai/
├── config.yaml
├── MEMORY.json
├── sandbox/
└── sessions/
    ├── index.json
    └── <session-id>.jsonl

License

MIT

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

kpihx_ai-0.2.0.tar.gz (138.0 kB view details)

Uploaded Source

Built Distribution

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

kpihx_ai-0.2.0-py3-none-any.whl (161.8 kB view details)

Uploaded Python 3

File details

Details for the file kpihx_ai-0.2.0.tar.gz.

File metadata

  • Download URL: kpihx_ai-0.2.0.tar.gz
  • Upload date:
  • Size: 138.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.10","id":"questing","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for kpihx_ai-0.2.0.tar.gz
Algorithm Hash digest
SHA256 662b96ed0a45c493075067b07516d534fbc591f8c5409f99952f97cc42d5cba9
MD5 7fc25b128bce1d2927434b4c426193a5
BLAKE2b-256 88e696c0933831195274ff825c11ddda57270182b7ee9301b7092132fb30b522

See more details on using hashes here.

File details

Details for the file kpihx_ai-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: kpihx_ai-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 161.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.10","id":"questing","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for kpihx_ai-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 05ccf37e6991015bf3394b49defaf2c17b9b05563a2d1c87f47baf277865df10
MD5 b33d1503fe087ebfb036e6ec03f8043f
BLAKE2b-256 c2d0430979eb22831255abdfa278ffeebcd715bfdf4f3b43f083f8140fd5f26f

See more details on using hashes here.

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