Local AI cost, latency, prompt, and workflow tracking.
Project description
OpenHarness
Local AI cost and workflow tracking for engineering teams.
No cloud. No signup. SQLite by default.
Install
pip install quadrant-openharness
openharness setup --demo
openharness costs
Use whichever pip command points at Python 3.10+ on your machine: pip, pip3, or python -m pip.
The package installs both command names:
openharness costs
agentharness costs
For the latest code from GitHub instead of PyPI:
pip install "git+https://github.com/Quadrant-Labs/openharness.git"
Why this exists
AI agents and AI-backed workflows can make thousands of model calls before anyone notices the bill. OpenHarness starts with the smallest useful wedge: track model calls locally, estimate cost, then show engineers where the money and latency go.
Proxy / start usage
openharness start runs a local forwarding proxy in front of an AI provider. Your app sends requests to OpenHarness, OpenHarness forwards them to the provider, then records model, token usage, latency, status, estimated cost, and optional tags in local SQLite.
This is the easiest way to use OpenHarness because your application does not need to import an OpenHarness SDK. Any OpenAI-compatible client, shell script, internal service, or agent runner can point at the local proxy.
Start an OpenAI-compatible proxy:
openharness start openai --port 8787
Then point your app at it:
export OPENAI_BASE_URL=http://127.0.0.1:8787/v1
export OPENAI_API_KEY=sk-...
Run your app normally, then view costs:
openharness costs --last 30d
Python example
from openai import OpenAI
client = OpenAI(
api_key="sk-...",
base_url="http://127.0.0.1:8787/v1",
)
response = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Review this PR for risky changes."}],
)
print(response.choices[0].message.content)
Node example
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: "http://127.0.0.1:8787/v1",
});
const response = await client.chat.completions.create({
model: "gpt-5.5",
messages: [{ role: "user", content: "Review this PR for risky changes." }],
});
console.log(response.choices[0].message.content);
curl example
curl http://127.0.0.1:8787/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-H "x-openharness-team: platform" \
-H "x-openharness-service: pr-review-bot" \
-d '{
"model": "gpt-5.5",
"messages": [{"role": "user", "content": "Review this PR."}]
}'
Tag traffic
You can tag all traffic at proxy startup:
openharness start openai \
--team platform \
--service pr-review-bot \
--env production \
--project ai-platform
Or tag individual requests with headers:
x-openharness-org: acme
x-openharness-team: platform
x-openharness-service: pr-review-bot
x-openharness-env: production
x-openharness-workflow: pr_reviews
x-openharness-step: review
Then use org-level showback:
openharness org --last 30d
Other providers
The proxy has initial usage extraction for Anthropic and Gemini:
openharness start anthropic --port 8788
openharness start google --port 8789
For any other OpenAI-compatible provider, use generic mode with an upstream base URL:
openharness start generic --target https://api.openrouter.ai/v1 --port 8787
openharness start generic --target https://api.groq.com/openai/v1 --port 8787
openharness start generic --target https://api.together.xyz/v1 --port 8787
openharness start generic --target http://localhost:11434/v1 --port 8787
If you pass --target without a provider, OpenHarness automatically uses generic mode:
openharness start --target https://api.example.com/v1
Generic mode forwards every path under the target URL and tries to extract usage from common response shapes such as usage.prompt_tokens, usage.completion_tokens, usage.input_tokens, usage.output_tokens, and usageMetadata.promptTokenCount. If OpenHarness does not know the model price, it still records tokens, latency, status, tags, and model name, but cost is reported as unknown/zero until that model is added to the pricing catalog.
Prompt previews
Prompt previews are off by default. To store a local 240-character prompt preview for each JSON request:
openharness start openai --record-prompt-preview
Notes
- OpenHarness estimates costs from provider usage metadata in non-streaming JSON responses.
- Streaming calls are forwarded, but they may not be costed unless the provider returns parseable usage data.
- The proxy stores data locally in
.openharness/openharness.dbunlessOPENHARNESS_DBis set. - The old command also works:
openharness proxy --provider openai --port 8787.
Org gateway mode
For a team or org, run OpenHarness as a shared gateway and tag traffic by owner:
openharness start openai \
--host 0.0.0.0 \
--port 8787 \
--org acme \
--team platform \
--service pr-review-bot \
--env production
Apps can also tag individual requests with headers:
x-openharness-org: acme
x-openharness-team: platform
x-openharness-service: pr-review-bot
x-openharness-env: production
x-openharness-workflow: pr_reviews
x-openharness-step: review
Or set tags on the proxy process:
export OPENHARNESS_ORG=acme
export OPENHARNESS_TEAM=platform
export OPENHARNESS_SERVICE=pr-review-bot
export OPENHARNESS_ENV=production
Org showback:
openharness org --last 30d
Example sections:
Spend by team
Spend by service
Spend by environment
Spend by workflow
Spend by customer
Spend by provider/model
Budget policies:
openharness budget init
openharness budget check
Then enable hard-stop enforcement in the proxy:
openharness start openai --enforce-budgets --budget-file .openharness/budgets.json
Budget config shape:
{
"budgets": [
{
"name": "PR review bot monthly hard stop",
"limit_usd": 1000,
"period_days": 30,
"action": "block",
"filters": {
"service": "pr-review-bot"
}
}
]
}
Export for finance, platform, or dashboards:
openharness export --format csv --output usage.csv
openharness export --format json --output usage.json
Command shape
OpenHarness is meant to feel like a terminal tool first:
openharness setup
openharness start openai --team platform --service pr-review-bot --env production
openharness costs --last 7d
openharness org --last 30d
openharness budget check
openharness export --format csv --output usage.csv
The longer names still work when you want them:
openharness proxy --provider openai
openharness report --days 30
openharness org-report --days 30
Python API
The Python API is still useful for apps that want explicit workflow and step labels in code.
Manual tracking:
from openharness import tracker
tracker.record(
provider="openai",
model="gpt-5.5",
input_tokens=5000,
output_tokens=1200,
workflow="create_pr",
step="review",
latency_ms=4200,
prompt_name="pr_review",
)
Workflow tracking:
from openharness import tracker
with tracker.workflow("create_feature"):
with tracker.step("research"):
tracker.record("anthropic", "claude-sonnet-4-6", 2000, 900)
with tracker.step("code"):
tracker.record("openai", "gpt-5.4-mini", 8000, 2400)
OpenAI wrapper:
from openai import OpenAI
from openharness import track_openai
client = track_openai(OpenAI())
response = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Review this PR"}],
)
The wrapper records model, tokens, latency, estimated cost, workflow, step, status, and errors when the SDK response exposes usage data.
CLI
openharness init
openharness record --provider openai --model gpt-5.5 --input-tokens 5000 --output-tokens 1200 --workflow pr_reviews
openharness costs --last 30d
openharness org --last 30d
openharness scan
openharness start openai --port 8787
openharness budget check
openharness export --format csv --output usage.csv
openharness pricing
openharness doctor
scan is currently an alias for reporting local OpenHarness data. A future version can inspect source trees and provider logs.
Storage
By default OpenHarness writes to:
.openharness/openharness.db
Override it with:
export OPENHARNESS_DB=/path/to/openharness.db
Pricing catalog
Costs are estimates calculated from a small built-in catalog. Prices are per 1 million tokens and were checked on 2026-06-16 against official provider docs:
- OpenAI API pricing: https://developers.openai.com/api/docs/pricing
- Anthropic model overview and pricing: https://platform.claude.com/docs/en/about-claude/models/overview
- Gemini Developer API pricing: https://ai.google.dev/gemini-api/docs/pricing
Provider billing can include regional processing, priority tiers, cache storage, search grounding, images, audio, discounts, taxes, and enterprise terms. Treat OpenHarness v0.1 numbers as directional until you wire in billing exports.
Development
python -m pip install -e .
PYTHONPATH=src python -m unittest discover -s tests
python -m openharness demo --reset
python -m openharness report
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quadrant_openharness-0.1.2.tar.gz.
File metadata
- Download URL: quadrant_openharness-0.1.2.tar.gz
- Upload date:
- Size: 31.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5681cf59039f4b128a7cfa9fb18c3f1fe2aa36885f0baa6d7cb8a92c45d9b24
|
|
| MD5 |
4ea6a35c250ee8c238aa71786a3f17b2
|
|
| BLAKE2b-256 |
39b170c328d74024d6137f5647e54741dfa0397fd897071dc42ed71aca47bf2a
|
Provenance
The following attestation bundles were made for quadrant_openharness-0.1.2.tar.gz:
Publisher:
publish.yml on Quadrant-Labs/openharness
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quadrant_openharness-0.1.2.tar.gz -
Subject digest:
a5681cf59039f4b128a7cfa9fb18c3f1fe2aa36885f0baa6d7cb8a92c45d9b24 - Sigstore transparency entry: 1846036228
- Sigstore integration time:
-
Permalink:
Quadrant-Labs/openharness@d0cb73d245056b290d1e074b504c92e1d6122047 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/Quadrant-Labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d0cb73d245056b290d1e074b504c92e1d6122047 -
Trigger Event:
push
-
Statement type:
File details
Details for the file quadrant_openharness-0.1.2-py3-none-any.whl.
File metadata
- Download URL: quadrant_openharness-0.1.2-py3-none-any.whl
- Upload date:
- Size: 29.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dc7be03f1b1a4634637dc0d332dcacf6464999621667f2c93adf8d5a1c7f017
|
|
| MD5 |
efb4e5116171d3a24138312e60bdd9e5
|
|
| BLAKE2b-256 |
518a24a652e4892fafd4282eaa596300d81d6e942895e460beb4d1725b0db278
|
Provenance
The following attestation bundles were made for quadrant_openharness-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on Quadrant-Labs/openharness
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quadrant_openharness-0.1.2-py3-none-any.whl -
Subject digest:
0dc7be03f1b1a4634637dc0d332dcacf6464999621667f2c93adf8d5a1c7f017 - Sigstore transparency entry: 1846036556
- Sigstore integration time:
-
Permalink:
Quadrant-Labs/openharness@d0cb73d245056b290d1e074b504c92e1d6122047 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/Quadrant-Labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d0cb73d245056b290d1e074b504c92e1d6122047 -
Trigger Event:
push
-
Statement type: