Skip to main content

KHarness

A lightweight Python framework for building LLM agents with tool use, conversation memory, and multi-round research pipelines. Supports local inference via llama.cpp and Ollama.


Installation

pip install kharness

Optional dependencies (install what you need):

pip install langchain-core          # Required for tool decorators
pip install ddgs beautifulsoup4     # Web tools
pip install yahoors                 # Stock tools

Providers

Providers wrap a local inference backend and expose a unified chat() interface.

Ollama

from kharness.providers import Ollama

provider = Ollama("qwen2.5:7b")             # model is required

response = provider.chat(
    [{"role": "user", "content": "Hello!"}]
)
Parameter Default Description
model — Model name (required)
server_url "http://localhost" Server host
port "11434" Server port
max_iterations 10 Max tool-call loop iterations

LlamaCpp

Assumes a llama-server process is already running. Connect to it:

from kharness.providers import LlamaCpp

provider = LlamaCpp()                       # defaults: 127.0.0.1:8080

if provider.check_health():
    response = provider.chat(
        [{"role": "user", "content": "Hello!"}]
    )
Parameter Default Description
server_url "http://127.0.0.1" Server host
port "8080" Server port
max_iterations 5 Max tool-call loop iterations
strip_tools_after 3 Force text response after N tool rounds

Agent

Agent wraps a provider with optional tools and memory, exposing run() for chat and research() for multi-round deep dives.

Basic chat

from kharness.providers import Ollama
from kharness.agent import Agent

provider = Ollama("qwen2.5:7b")

agent = Agent(provider)
response = agent.run("What is the capital of France?")
print(response)

With a system prompt file

agent = Agent(provider, soul_md_path="persona.md")

With tools

Pass a dict or list of dicts mapping tool names to LangChain @tool objects:

from kharness.tools import WEB_TOOL_MAP

agent = Agent(provider, tool_map=WEB_TOOL_MAP)
response = agent.run("What happened in the news today?")

With memory

Attach a Memory object to maintain conversation history across turns:

from kharness.memory import Memory

memory = Memory(max_turns=20)
agent = Agent(provider, memory=memory)

agent.run("My name is Alice.")
agent.run("What's my name?")   # remembers "Alice"

Memory

Memory manages a sliding window of conversation history. It stores messages as {"role": ..., "content": ...} dicts — the format all providers expect.

from kharness.memory import Memory

memory = Memory(max_turns=10)   # keeps last 10 user/assistant pairs
memory.add("user", "Hello")
memory.add("assistant", "Hi there!")

history = memory.get_history()  # list of message dicts
memory.clear()
Parameter Default Description
max_turns 20 Max user/assistant pairs to retain

Research pipeline

agent.research() runs a structured multi-round research loop:

  1. Plan — generates search queries from the question
  2. Gather — runs web searches for each query
  3. Analyze — synthesizes findings and decides if more searching is needed
  4. Repeat — loops up to max_rounds times if gaps remain
  5. Report — writes a final comprehensive answer
from kharness.providers import Ollama
from kharness.tools import WEB_TOOL_MAP
from kharness.agent import Agent

provider = Ollama("qwen2.5:14b")

agent = Agent(provider, tool_map=WEB_TOOL_MAP)

report = agent.research(
    "What are the latest developments in fusion energy?",
    max_rounds=3,
    planning_tokens=512,
    analysis_tokens=2048,
    report_tokens=8000,
)
print(report)
Parameter Default Description
max_rounds 3 Maximum search/analyze iterations
planning_tokens 1024 Token budget for query planning
analysis_tokens 2048 Token budget for per-round analysis
report_tokens 8000 Token budget for final report
debug True Log phase progress

Tools

Tools are standard LangChain @tool functions. Convenience maps are exported for easy use with Agent.

Web tools

from kharness.tools import WEB_TOOL_MAP
Tool Description
web_search DuckDuckGo text search, returns top snippets
fetch_page Fetches a URL and extracts readable text
news_search DuckDuckGo news search with dates
image_search Returns direct image URLs
wikipedia_summary Wikimedia REST API summary
search_and_fetch Combines search + full page fetch
search_subreddit Fetches top posts from a subreddit

Stock tools

from kharness.tools import STOCK_TOOL_MAP
Tool Description
get_candles OHLCV candlestick data
get_options Options chain (calls and puts)
get_income_statements Income statement financials
get_balance_sheet Balance sheet financials
get_cash_flow Cash flow statement

Custom tools

Any LangChain @tool works:

from langchain_core.tools import tool

@tool
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

agent = Agent(provider, tool_map={"add": add})

Logging

KHarness uses Python's standard logging module. To see runtime output:

import logging
logging.basicConfig(level=logging.INFO)

Use logging.DEBUG to see individual tool calls.


Requirements

Metadata

Release files for kharness 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kharness 0.1.1
File Size Uploaded
kharness-0.1.1.tar.gz 14.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kharness 0.1.1
File Interpreter ABI Platform
kharness-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 29.8 kB

Release files / kharness-0.1.1.tar.gz

Download URL kharness-0.1.1.tar.gz
Size 14.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8c1e49171f486f22e74de846a21eaea557acdb037f8de2f0a2c105dcf6ea2b07
BLAKE2b-256 checksum
How to use checksums
1dca658ad538d90415948ceda113afbf6b40436e970104a92ffee7c47cc274b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release files / kharness-0.1.1-py3-none-any.whl

Download URL kharness-0.1.1-py3-none-any.whl
Size 15.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc8cc7a8f6b0a263bd93fea5d0022ad56bc2c28fa369b6b945f41f982201f4dc
BLAKE2b-256 checksum
How to use checksums
19ecc4501b542b88c819d0307cc113aa48738c1bb543cb403ed13ae94dbe4236
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page