@openlucaskaka/kagent
v0.1.11
Published
Codex-style LangGraph agent runtime for internal non-coding workflows.
Readme
kagent
kagent is a local-first LangGraph agent with two public command paths: an Ink terminal for an interactive TTY and a JSON-producing one-shot command for automation. Both paths use the same Python runtime, policy-gated local tools, structured observations, and bounded planning loop.
Install and run
npm install -g @openlucaskaka/kagent@latest
kagentRunning bare kagent in a TTY opens the Ink terminal UI. The npm package
prepares a private, managed Python environment and Ink starts
kagent.cli.stdio_runtime as a long-lived child. Requests and events cross that
boundary as one JSON object per line (JSONL); Python executes the LangGraph
runtime and local tools, while Ink owns input, approvals, activity, and the
transcript.
If Ink cannot start, the launcher prints a concise error and exits: no Python interactive fallback.
Pass a goal to use one-shot automation instead:
kagent "draft an internal rollout checklist"kagent "goal" runs through src/kagent/cli/main.py and writes the complete
runtime result as JSON. It does not open Ink. Deterministic checks can provide a
strict plan without provider credentials:
kagent "capture hello" \
--runtime-plan '{"actions":[],"final_answer":"captured hello"}'The same one-shot command provides provider configuration and introspection:
kagent --configure
kagent --version
kagent --list-tools
kagent --graphUse --max-iterations, --tag, and --metadata KEY=VALUE to bound and label a
run. --trace-dir PATH persists a local trace, --output PATH copies the JSON
result to a file, and --fail-on-agent-failure gives automation an exit status
for a failed run.
Provider setup
The Ink provider setup offers Qwen, DeepSeek, Ollama, and a custom
OpenAI-compatible provider, then collects Base URL, model, and API key. Run
kagent --configure to configure from a terminal without opening Ink.
The default provider file is ~/.kagent/config/provider.json. It is private to
the owner. Environment variables take precedence for temporary or automated
runs:
export KAGENT_LLM_PROVIDER=qwen
export KAGENT_LLM_BASE_URL=https://example.invalid/v1
export KAGENT_LLM_API_KEY=...
export KAGENT_LLM_MODEL=...Interactive behavior
Ink keeps the prompt responsive while a run is active. Ctrl-C or Escape requests cooperative cancellation. Submitting another instruction while work is in progress queues latest-wins steering for the next safe planner or tool boundary. Actions such as workspace changes, bounded shell commands, outbound fetches, opening URLs, and opening applications can pause for explicit approval; the prompt shows a user-facing target without exposing raw internal input.
The runtime emits safe runtime/presentation payloads for visible activity.
These payloads contain bounded, redacted fields such as title, detail,
content, and truncated; raw tool input remains inside the Python runtime.
The supported Ink commands are /help, /pwd, /cd PATH, /status,
/config, /tools, /memory, /compact-memory, /clear, and /reset.
Local state and workspace
By default, each Ink launch generates fresh owner-only session-memory and
pending-approval paths below ~/.kagent/state/. Explicit
KAGENT_SESSION_MEMORY_PATH and KAGENT_PENDING_APPROVAL_PATH values can reuse
paths across launches or be managed by an embedding client. A child restart
within the active Ink client keeps the active paths. Memory is compacted as it
grows and secrets are redacted before prompt reuse or persistence.
The default user data layout is:
~/.kagent/config/provider.json
~/.kagent/state/sessions/<session-id>.json
~/.kagent/state/pending-approvals/<session-id>.json
~/.kagent/state/patches/
~/.kagent/cache/npm-python/
~/.kagent/cache/npm-self-update.json
~/.kagent/.migration-v1-completeSet KAGENT_HOME to relocate this user-level config, state, cache, and migration
marker. Component-specific path variables remain higher-priority explicit
overrides. The project-local $PWD/.kagent boundary stays separate and contains
the active runtime workspace and project skills. Workspace file tools enforce
that local boundary and risky mutations remain approval-gated.
Managed runtime and updates
The npm launcher supports macOS and Linux (darwin and linux). It stores each
immutable Python runtime under ~/.kagent/cache/npm-python and prepares a new
one only when the dependency or ABI identity changes; ordinary package updates
reuse a matching runtime.
Stable releases follow the npm latest tag (stable/latest), while prereleases
follow next (beta/next). Interactive TTY startup checks the selected channel
at most once every 24 hours and asks before installing. Control this behavior
with KAGENT_UPDATE_CHANNEL, disable automatic checks with
KAGENT_NO_SELF_UPDATE=1, or run:
kagent update --check
kagent upgradeLocal tools, traces, and artifacts
The Python LangGraph runtime includes local tools for workspace files, versioned runtime assets, structured artifacts, task and decision helpers, approved bounded shell commands, approved outbound requests, and approved local browser or application actions. Tool schemas are validated before execution; shell and network actions use bounded input, time, output, and policy checks.
One-shot traces can be persisted with --trace-dir. Inspect and retain them
locally with kagent-trace-replay and kagent-trace-prune. Continuous check
JSONL can be summarized with kagent-metrics, and release artifacts can be
hashed or verified with kagent-release-manifest.
Console scripts
The installed Python console script surface is intentionally small:
kagentkagent-metricskagent-release-manifestkagent-trace-prunekagent-trace-replay
Examples:
kagent-metrics /tmp/kagent-continuous.jsonl
kagent-trace-prune /tmp/kagent-traces --max-age-days 7 --runtime-only
kagent-trace-replay /tmp/kagent-traces/RUN_ID.json
kagent-release-manifest dist/kagent.whl --output dist/manifest.json
kagent-release-manifest --verify dist/manifest.jsonDevelopment
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
scripts/run_checks.shThe public Python API remains available for local automation:
from kagent import FakeLLMProvider, run_runtime_agent
provider = FakeLLMProvider(
'{"actions":[{"id":"step-1","tool":"note","input":{"text":"hello"}}]}'
)
result = run_runtime_agent("capture hello", provider=provider)See docs/project-structure.md for the maintainer code map,
docs/architecture.md for runtime design, docs/operations.md for local
operation, SECURITY.md for security boundaries, and CHANGELOG.md for
release history.
