Skip to main content

Course Harness

Course Harness is a local-first application for creating source-grounded Courses in a human-readable Course Workspace.

Install and launch

Install uv. It downloads Python 3.14 if you do not have it.

uvx --torch-backend cpu course-harness

Or install it as a command-line tool:

uv tool install --torch-backend cpu course-harness
course-harness

--torch-backend cpu installs the CPU build of PyTorch for local document conversion. Without it, uv installs the CUDA build on Linux, which downloads several gigabytes of GPU libraries.

To run the latest revision from GitHub (no flag needed; the CPU build is selected automatically):

uvx --from git+https://github.com/martinkozle/course-harness.git course-harness

The command opens http://127.0.0.1:8765 with the Workspace Launcher, where you create or open a Course Workspace. Useful options:

course-harness /path/to/course-workspace  # open a Workspace directly (`.` works too)
course-harness --no-browser               # do not open the browser
course-harness --port 9000                # use another local port

Optional: install LibreOffice (libreoffice or soffice on PATH) for high-fidelity slide thumbnails.

What it does

  • Sources: add PDF, .pptx, .docx, and web pages, or discover papers through arXiv, Crossref, Semantic Scholar, and OpenAlex. Documents are converted locally with Docling; the layout and OCR models are downloaded on first use, after you confirm.
  • Course Agent: plans the Course, researches sources, and writes Lectures. Only Sources added to the Course can be cited.
  • Connectors: web search and page reading through remote MCP servers. Exa is set up by default and works without a key.
  • History: save and restore Course Revisions, publish Releases, and export Lectures to PowerPoint.

Canonical Course state lives in readable files in the Course Workspace. Caches, conversations, and credentials live in platform-native user locations outside it; credentials go to the operating system keyring when one is available. Settings → Diagnostics shows the exact locations.

Each Course Agent run is also traced for debugging, beside its conversation in the chat store: traces/<conversation id>.jsonl holds one line per model request, response, and tool call, with timings, token usage (including cached input tokens), and only the messages that changed since the previous request. If a request sets history_rewritten, instructions_changed, or tools_changed, the provider could not reuse its prompt cache for the conversation so far. A trace is removed with its conversation, or after two weeks without new runs. The conversation itself is saved around every model request, so stopping a run keeps everything up to that point.

Models works with OpenRouter, OpenAI, Anthropic, Amazon Bedrock, and any OpenAI-compatible server. Under Found on this computer, it lists the provider credentials it can see and lets you add each one with a single click. It looks at OPENAI_API_KEY, ANTHROPIC_API_KEY, OPENROUTER_API_KEY, AWS_BEARER_TOKEN_BEDROCK, AWS session variables (such as those set by awsume), and the profiles in ~/.aws. None of these is used until you add it. For Bedrock, an AWS profile is the most robust choice: only its name is stored, and the AWS SDK refreshes SSO and role credentials by itself. Session variables are read from the shell that started Course Harness, so after they expire, refresh them and restart from that shell. Prompt caching is turned on for Anthropic and OpenRouter models, and for Bedrock models that support it.

To use an OpenAI-compatible provider on another machine over plain HTTP, select Allow HTTP to another host. The API key and Course content are then sent unencrypted, so use it only on a network you trust.

Development

Development uses Nix with flakes. The flake pins Python, uv, Bun, Node.js, Chromium, and Git; uv.lock and bun.lock pin application packages.

nix develop   # or `direnv allow` once with nix-direnv

Entering the shell installs the pre-commit and pre-push hooks (Biome, Ruff, ty, nixfmt, uv lock freshness, and hygiene checks). Their configuration lives in flake.nix.

Launch from a checkout:

uv sync --locked
bun install --frozen-lockfile
bun run build
uv run course-harness

For frontend hot reload, run the API and Vite side by side; Vite serves http://127.0.0.1:5173 and proxies /api:

uv run course-harness /path/to/course-workspace --no-browser
bun run dev

Checks:

pre-commit run --all-files
uv run pytest
bun run lint
bun run typecheck
bun run build
bun run test:e2e   # Playwright smoke journey

Outside Nix, install the Playwright browser once with bunx playwright install --with-deps chromium or set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH.

Build the wheel and smoke-test it through uvx, uv tool install, and a git+file:// install of the current commit, all in isolated temporary environments:

uv run python scripts/verify_distribution.py

The Release workflow runs these checks on every push to main. To publish a version:

uv version --bump minor   # or patch/major; updates pyproject.toml and uv.lock
git commit -am "Release 0.2.0" && git push

Then create a GitHub Release with a new tag v0.2.0 on that commit (or push the tag with git tag v0.2.0 && git push origin v0.2.0). The tag must match the package version. The workflow publishes to PyPI through trusted publishing and attaches the wheel and source distribution to the Release.

Without Nix, install Python 3.14, uv, Bun 1.3 or newer, Node.js, and Chromium, then use the same commands.

Metadata

Release files for course-harness 0.3.0

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

Source distribution (sdist)

Source distribution for course-harness 0.3.0
File Size Uploaded Provenance
course_harness-0.3.0.tar.gz 791.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for course-harness 0.3.0
File Interpreter ABI Platform
course_harness-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / course_harness-0.3.0.tar.gz

Download URL course_harness-0.3.0.tar.gz
Size 791.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c5440367a2392f9000da677d3cdf382f4a611f1e5f2e20e10e36ecbc163cb96b
BLAKE2b-256 checksum
How to use checksums
5721c6bfc879471c2c65d189705a31306be8e7137fe907b3a796455d526ba437
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / course_harness-0.3.0-py3-none-any.whl

Download URL course_harness-0.3.0-py3-none-any.whl
Size 820.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
569221b02bc7d89b82dae9f13c1e7252767597b8a1565a56a0172673727f9933
BLAKE2b-256 checksum
How to use checksums
3c3a1727f799977e67ffe6893c612d0e228a1f97346c7ae04edd1f3b2ad357d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for course-harness 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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