Skip to main content

A small pluggable AI agent harness with sessions and tools.

Project description

My Harness

My Harness is a small educational AI agent harness.

It has:

  • terminal CLI command: my-harness
  • pluggable LLM providers
  • OpenAI provider included
  • session creation/resume/listing
  • session storage as JSON
  • tool-calling loop
  • scalable tools folder structure
  • prompt folder for agent instructions
  • skills folder for optional agent behaviors
  • subagent creation tool
  • workspace-restricted file tools
  • bash disabled by default
  • tools: read_file, write_file, optional bash

Install for local development

cd "C:/Users/shiva/Downloads/custom harness"
python -m venv .venv
.venv/Scripts/activate
python -m pip install --upgrade pip
pip install -e .

Now run from anywhere:

my-harness

or:

myharness

A command with a space like my harness is not recommended because terminals treat spaces as separators. Use my-harness.

Configure

After installing, users can create API key config with:

my-harness --workspace "C:/path/to/project" --init-config

This creates:

<workspace>/.env

Then edit that file and add the API key.

Alternatively, manually create .env in the folder where you run my-harness or inside the selected workspace:

LLM_PROVIDER=openai
OPENAI_API_KEY=your_api_key_here
OPENAI_MODEL=gpt-4o-mini

Or set the API key globally in your shell.

Windows PowerShell:

setx OPENAI_API_KEY "your_api_key_here"

macOS/Linux:

export OPENAI_API_KEY="your_api_key_here"

You can copy the example:

copy .env.example .env

Usage

Create a new session in the current folder as workspace:

my-harness

Use a specific workspace:

my-harness --workspace "C:/path/to/project"

List sessions in current folder:

my-harness --list-sessions

Resume a session:

my-harness --session <session-id>

Choose provider/model:

my-harness --provider openai --model gpt-4o-mini

Interactive model/API-key setup:

my-harness --setup-model

Inside chat, use:

/model

Currently supported provider: openai.

OpenAI model choices shown by setup include:

gpt-4o-mini
gpt-4o
gpt-4.1-mini
gpt-4.1
o4-mini

If API keys are missing, chat will not start. The setup flow asks the user to paste the key first.

Disable subagents if you do not want the agent to spawn focused helper agents:

my-harness --no-subagents

Enable bash if you need shell commands:

my-harness --enable-bash

Important: read_file and write_file are restricted to the workspace. bash is not a strong workspace sandbox because shell commands can still try to access paths outside the workspace if your OS allows it. For strong isolation, run my-harness inside Docker/VM.

Use custom prompt files:

my-harness --system-prompt ./system.md --user-prompt ./prompt.md

Or set them in .env:

MY_HARNESS_SYSTEM_PROMPT=C:/path/to/system.md
MY_HARNESS_USER_PROMPT=C:/path/to/prompt.md

Meaning:

  • system.md = common agent instructions for all agents
  • prompt.md = specialized user/project instructions

Sessions

Sessions are stored inside the selected workspace:

<workspace>/.my_harness/sessions/<session-id>.json

Each session contains:

{
  "id": "uuid",
  "created_at": "timestamp",
  "updated_at": "timestamp",
  "messages": []
}

Project structure

custom harness/
  pyproject.toml
  MANIFEST.in
  README.md
  .env.example
  my_harness/
    __init__.py
    main.py
    agent.py
    session.py
    llm.py
    prompts/
      __init__.py
      loader.py
      system.md
      prompt.md
    skills/
      __init__.py
      loader.py
      subagents.md
    providers/
      __init__.py
      base.py
      factory.py
      openai_provider.py
    tools/
      __init__.py
      base.py
      runner.py
      filesystem/
        read_file.py
        write_file.py
      shell/
        bash.py
      subagents/
        create_subagent.py
  docs/
    packaging.md

Add another tool

Create a new file under my_harness/tools/, for example:

my_harness/tools/network/http_get.py

Implement BaseTool:

from ..base import BaseTool

class HttpGetTool(BaseTool):
    name = "http_get"
    description = "Fetch a URL."

    def schema(self):
        return {
            "type": "function",
            "function": {
                "name": self.name,
                "description": self.description,
                "parameters": {
                    "type": "object",
                    "properties": {"url": {"type": "string"}},
                    "required": ["url"],
                },
            },
        }

    def execute(self, url: str) -> str:
        return "TODO: fetch URL"

Then register it in my_harness/tools/runner.py.

Skills and subagents

Skill instructions live in:

my_harness/skills/

The included skill file is:

my_harness/skills/subagents.md

It teaches the main agent when to use the create_subagent tool.

The subagent tool:

  • creates a separate session
  • gives the subagent a focused task
  • lets it use workspace-safe tools
  • returns the result to the main agent

Subagent sessions are stored in the same workspace session folder and marked with:

"kind": "subagent"

Agent prompts

Default instructions live in:

my_harness/prompts/system.md

You can edit that file during development, or pass a custom prompt at runtime:

my-harness --system-prompt ./system.md

Add another LLM provider

Create:

my_harness/providers/my_provider.py

Example:

from .base import LLMProvider

class MyProvider(LLMProvider):
    def __init__(self, model=None):
        self.model = model or "my-default-model"

    def chat(self, messages, tools):
        # Call your provider API here.
        # Return a response compatible with agent.py.
        pass

Register it in my_harness/providers/factory.py:

from .my_provider import MyProvider

SUPPORTED_PROVIDERS = {
    "openai": OpenAIProvider,
    "myprovider": MyProvider,
}

Then run:

my-harness --provider myprovider

Build package

pip install build twine
python -m build

Output appears in:

dist/

Install the wheel on another system:

pip install dist/my_harness-0.1.0-py3-none-any.whl

More docs

See:

docs/packaging.md

Workspace access and safety

File access is controlled in my_harness/tools/base.py using ToolContext.safe_path().

This blocks paths like:

../secret.txt
C:/Users/shiva/secret.txt

when they are outside the configured workspace.

By default, only workspace-safe file tools are enabled:

  • read_file
  • write_file

The bash tool is disabled by default. Enable it only when needed:

my-harness --enable-bash

For true security, use Docker/VM/container isolation.

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

my_harness-0.1.0.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

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

my_harness-0.1.0-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file my_harness-0.1.0.tar.gz.

File metadata

  • Download URL: my_harness-0.1.0.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for my_harness-0.1.0.tar.gz
Algorithm Hash digest
SHA256 73cd84ca435e2102226c7c32b673f7ebe6dfe344275fe82b3d4dee83d3d86629
MD5 53898b83b8e8f9d813aad5571a82f469
BLAKE2b-256 419139f1e64210c7b18bed455c65e97aaa9ddae46125355796eaa373fa7bdc3b

See more details on using hashes here.

File details

Details for the file my_harness-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: my_harness-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for my_harness-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0f03373d019a7caff241ce1bf24213ccc37955b513c08fb46a02a81c5515eece
MD5 0f653eb7a6cc861d4c49719f7aef3d05
BLAKE2b-256 f5bf00d4d9dfc36b63ae37d2ed62dae37b0fa26a6df82353acb2278fff3250df

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