local-agentic-harness 0.6.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- local_agentic_harness-0.6.9/AUTHORS.md +7 -0
- local_agentic_harness-0.6.9/LICENSE +21 -0
- local_agentic_harness-0.6.9/PKG-INFO +379 -0
- local_agentic_harness-0.6.9/README.md +360 -0
- local_agentic_harness-0.6.9/agentic_harness/__init__.py +8 -0
- local_agentic_harness-0.6.9/agentic_harness/adapters/__init__.py +15 -0
- local_agentic_harness-0.6.9/agentic_harness/adapters/coding_agent.py +119 -0
- local_agentic_harness-0.6.9/agentic_harness/adapters/github_actions.py +217 -0
- local_agentic_harness-0.6.9/agentic_harness/adapters/local_llm.py +71 -0
- local_agentic_harness-0.6.9/agentic_harness/adapters/shell.py +79 -0
- local_agentic_harness-0.6.9/agentic_harness/adapters/tmux.py +64 -0
- local_agentic_harness-0.6.9/agentic_harness/cli.py +253 -0
- local_agentic_harness-0.6.9/agentic_harness/core/__init__.py +33 -0
- local_agentic_harness-0.6.9/agentic_harness/core/artifacts.py +134 -0
- local_agentic_harness-0.6.9/agentic_harness/core/config.py +259 -0
- local_agentic_harness-0.6.9/agentic_harness/core/errors.py +33 -0
- local_agentic_harness-0.6.9/agentic_harness/core/loop_guard.py +63 -0
- local_agentic_harness-0.6.9/agentic_harness/core/review.py +157 -0
- local_agentic_harness-0.6.9/agentic_harness/core/state.py +110 -0
- local_agentic_harness-0.6.9/agentic_harness/core/supervisor.py +112 -0
- local_agentic_harness-0.6.9/agentic_harness/core/worker.py +26 -0
- local_agentic_harness-0.6.9/local_agentic_harness.egg-info/PKG-INFO +379 -0
- local_agentic_harness-0.6.9/local_agentic_harness.egg-info/SOURCES.txt +32 -0
- local_agentic_harness-0.6.9/local_agentic_harness.egg-info/dependency_links.txt +1 -0
- local_agentic_harness-0.6.9/local_agentic_harness.egg-info/entry_points.txt +2 -0
- local_agentic_harness-0.6.9/local_agentic_harness.egg-info/requires.txt +8 -0
- local_agentic_harness-0.6.9/local_agentic_harness.egg-info/top_level.txt +1 -0
- local_agentic_harness-0.6.9/pyproject.toml +38 -0
- local_agentic_harness-0.6.9/setup.cfg +4 -0
- local_agentic_harness-0.6.9/tests/test_adapters.py +523 -0
- local_agentic_harness-0.6.9/tests/test_ci_workflow.py +72 -0
- local_agentic_harness-0.6.9/tests/test_cli.py +466 -0
- local_agentic_harness-0.6.9/tests/test_core_engine.py +384 -0
- local_agentic_harness-0.6.9/tests/test_examples.py +134 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael / Moortekweb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: local-agentic-harness
|
|
3
|
+
Version: 0.6.9
|
|
4
|
+
Summary: A local-first goal execution harness with deterministic review gates.
|
|
5
|
+
Author: Michael / Moortekweb
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: AUTHORS.md
|
|
11
|
+
Requires-Dist: PyYAML>=6.0
|
|
12
|
+
Provides-Extra: test
|
|
13
|
+
Requires-Dist: build>=1.2; extra == "test"
|
|
14
|
+
Requires-Dist: mypy>=1.10; extra == "test"
|
|
15
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
16
|
+
Requires-Dist: ruff>=0.5; extra == "test"
|
|
17
|
+
Requires-Dist: types-PyYAML>=6.0; extra == "test"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# Agentic Harness
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
[](https://github.com/moortekweb-art/agentic-harness/actions)
|
|
25
|
+
[](https://www.python.org/)
|
|
26
|
+
[](LICENSE)
|
|
27
|
+
[](https://buymeacoffee.com/moortekweb3)
|
|
28
|
+
|
|
29
|
+
A small Python harness for running long-lived agent goals without turning your local scripts into a tangled control plane.
|
|
30
|
+
|
|
31
|
+
Agentic Harness gives you a project-local goal loop: start a goal, execute it through an adapter, save artifacts, run deterministic review, and stop before auto-continue loops get weird.
|
|
32
|
+
|
|
33
|
+
## Project Links
|
|
34
|
+
|
|
35
|
+
- [Examples](examples/) include shell, coding-agent, the fix-failing-tests demo, local LLM, tmux, GitHub Actions, and real-world recipe examples.
|
|
36
|
+
- [Release checklist](docs/RELEASE_CHECKLIST.md) documents the v0.6.9 release checks.
|
|
37
|
+
- [PyPI trusted publishing](docs/PYPI_TRUSTED_PUBLISHING.md) documents the active publish workflow and external PyPI setup required for tokenless publishing.
|
|
38
|
+
- [Repo artwork](docs/assets/) includes a social preview banner and square icon.
|
|
39
|
+
- [Support the project](https://buymeacoffee.com/moortekweb3) via Buy Me a Coffee.
|
|
40
|
+
- [Attraction plan](ATTRACTION_PLAN.md) captures public project positioning and follow-up ideas.
|
|
41
|
+
- [CI workflow](.github/workflows/ci.yml) runs tests, ruff, mypy, compile smoke checks, package builds, wheel installs, and CLI smoke checks on Linux, Windows, and macOS.
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pipx install git+https://github.com/moortekweb-art/agentic-harness.git
|
|
47
|
+
agentic-harness init
|
|
48
|
+
cat > .agentic-harness/config.yml <<'YAML'
|
|
49
|
+
version: 1
|
|
50
|
+
worker: shell
|
|
51
|
+
shell_command:
|
|
52
|
+
- python
|
|
53
|
+
- -c
|
|
54
|
+
- "import os; print('goal:', os.environ['AGENTIC_HARNESS_OBJECTIVE'])"
|
|
55
|
+
YAML
|
|
56
|
+
agentic-harness start "write a changelog for the last three commits"
|
|
57
|
+
agentic-harness continue && agentic-harness review
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For one-shot local runs:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
agentic-harness run "write a changelog for the last three commits"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Why This Exists
|
|
67
|
+
|
|
68
|
+
Most agent tooling lands in one of two places:
|
|
69
|
+
|
|
70
|
+
- Frameworks that are flexible but abstract enough that you still need to build the operational loop yourself.
|
|
71
|
+
- Internal scripts that work on one machine, with one naming scheme, one set of paths, and one operator.
|
|
72
|
+
|
|
73
|
+
Agentic Harness is the middle ground: a small state machine, adapter interface, artifact store, CLI, and deterministic review contract. It is meant for developers who already have useful local tools and want a safer way to run them as repeatable goals.
|
|
74
|
+
|
|
75
|
+
## How It Works
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
goal text
|
|
79
|
+
|
|
|
80
|
+
v
|
|
81
|
+
pending -> planning -> in_progress -> review -> done
|
|
82
|
+
| |
|
|
83
|
+
v v
|
|
84
|
+
failed <----- failed
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
CLI ──> Supervisor ──> Worker adapter ──> local tool / tmux / CI / LLM
|
|
89
|
+
|
|
|
90
|
+
├── state.json
|
|
91
|
+
├── markdown reports
|
|
92
|
+
├── deterministic review result
|
|
93
|
+
└── loop guard
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The core package has no systemd, Cloudflare, GPU, or server-specific assumptions. Runtime state lives in `.agentic-harness/` inside your project.
|
|
97
|
+
|
|
98
|
+
## Features
|
|
99
|
+
|
|
100
|
+
- Deterministic review gates: pass/fail criteria are code, not model vibes.
|
|
101
|
+
- Artifact-first execution: every goal writes structured JSON state and review data.
|
|
102
|
+
- Loop guard: auto-continue has a project-local circuit breaker persisted at
|
|
103
|
+
`.agentic-harness/guard.json`, so repeated CLI invocations share the same
|
|
104
|
+
safety window.
|
|
105
|
+
- State lock and active-goal guard: mutating commands acquire
|
|
106
|
+
`.agentic-harness/state.lock`, and `start` refuses to overwrite an unfinished
|
|
107
|
+
active goal.
|
|
108
|
+
- Adapter system: shell, coding-agent CLI, tmux, GitHub Actions, and OpenAI-compatible local LLM adapters are included.
|
|
109
|
+
- Local-model friendly: any model served through an OpenAI-compatible chat
|
|
110
|
+
endpoint can be wrapped with deterministic review, including current
|
|
111
|
+
30B-40B local-model experiments such as Ornith 35B.
|
|
112
|
+
- Project-local config: no hardcoded absolute paths.
|
|
113
|
+
- Small public API: `Goal`, `Supervisor`, and `Worker`.
|
|
114
|
+
|
|
115
|
+
## Installation
|
|
116
|
+
|
|
117
|
+
Install as a CLI with pipx:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pipx install git+https://github.com/moortekweb-art/agentic-harness.git
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
After the first PyPI publish, install the released distribution with:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
pipx install local-agentic-harness
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The Python distribution name is `local-agentic-harness` so it can be reserved
|
|
130
|
+
on PyPI without colliding with the unrelated existing `agentic-harness` package.
|
|
131
|
+
The installed CLI command remains `agentic-harness`.
|
|
132
|
+
|
|
133
|
+
For development:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
git clone https://github.com/moortekweb-art/agentic-harness.git
|
|
137
|
+
cd agentic-harness
|
|
138
|
+
python -m venv .venv
|
|
139
|
+
. .venv/bin/activate
|
|
140
|
+
python -m pip install -e ".[test]"
|
|
141
|
+
python -m pytest tests/ -q
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Usage Examples
|
|
145
|
+
|
|
146
|
+
See [examples/](examples/) for complete project-local examples with READMEs, safety notes, and expected output.
|
|
147
|
+
For the critique-driven demo, see
|
|
148
|
+
[examples/fix-failing-tests-demo](examples/fix-failing-tests-demo/).
|
|
149
|
+
|
|
150
|
+
### Shell Worker
|
|
151
|
+
|
|
152
|
+
`.agentic-harness/config.yml`
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
version: 1
|
|
156
|
+
worker: shell
|
|
157
|
+
shell_command:
|
|
158
|
+
- python
|
|
159
|
+
- -c
|
|
160
|
+
- "import os; print('goal:', os.environ['AGENTIC_HARNESS_OBJECTIVE'])"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
agentic-harness start "summarize open TODOs"
|
|
165
|
+
agentic-harness continue
|
|
166
|
+
agentic-harness review
|
|
167
|
+
agentic-harness status
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
For a compact operator view instead of JSON:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
agentic-harness status --format text
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Local LLM Worker
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from agentic_harness import Supervisor
|
|
180
|
+
from agentic_harness.adapters import LocalLLMAdapter
|
|
181
|
+
|
|
182
|
+
worker = LocalLLMAdapter(
|
|
183
|
+
endpoint="http://127.0.0.1:4000/v1/chat/completions",
|
|
184
|
+
model="local-model",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
supervisor = Supervisor(project_dir=".", worker=worker)
|
|
188
|
+
supervisor.start("draft release notes for v0.6.9")
|
|
189
|
+
supervisor.continue_goal()
|
|
190
|
+
supervisor.review()
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Adapters
|
|
194
|
+
|
|
195
|
+
Adapters implement one method: `run(goal) -> WorkerResult`.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from agentic_harness.core.worker import WorkerResult
|
|
199
|
+
|
|
200
|
+
class MyWorker:
|
|
201
|
+
def run(self, goal):
|
|
202
|
+
path = f".agentic-harness/runs/{goal.id}/output.txt"
|
|
203
|
+
# call your tool here
|
|
204
|
+
return WorkerResult(success=True, summary="done", artifacts=[path])
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Then wire it into the supervisor:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from agentic_harness import Supervisor
|
|
211
|
+
|
|
212
|
+
supervisor = Supervisor(project_dir=".", worker=MyWorker())
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Configuration
|
|
216
|
+
|
|
217
|
+
`agentic-harness init` creates `.agentic-harness/config.yml`.
|
|
218
|
+
|
|
219
|
+
```yaml
|
|
220
|
+
version: 1
|
|
221
|
+
worker: noop
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`noop` is a safe placeholder. It does not pass review by default because no real
|
|
225
|
+
worker ran. For a demo-only path, opt in explicitly:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
version: 1
|
|
229
|
+
worker: noop
|
|
230
|
+
allow_noop_success: true
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Shell worker configuration:
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
version: 1
|
|
237
|
+
worker:
|
|
238
|
+
type: shell
|
|
239
|
+
shell_command:
|
|
240
|
+
- make
|
|
241
|
+
- agent-goal
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The shell adapter exposes:
|
|
245
|
+
|
|
246
|
+
- `AGENTIC_HARNESS_GOAL_ID`
|
|
247
|
+
- `AGENTIC_HARNESS_OBJECTIVE`
|
|
248
|
+
|
|
249
|
+
Coding-agent worker configuration:
|
|
250
|
+
|
|
251
|
+
```yaml
|
|
252
|
+
version: 1
|
|
253
|
+
worker:
|
|
254
|
+
type: coding_agent
|
|
255
|
+
coding_agent_command:
|
|
256
|
+
- codex
|
|
257
|
+
- exec
|
|
258
|
+
- --full-auto
|
|
259
|
+
- "{objective}"
|
|
260
|
+
coding_agent_transcript: .agentic-harness/runs/{goal_id}/coding-agent.log
|
|
261
|
+
review:
|
|
262
|
+
command:
|
|
263
|
+
- python
|
|
264
|
+
- -m
|
|
265
|
+
- pytest
|
|
266
|
+
- tests/
|
|
267
|
+
- -q
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Tmux worker configuration:
|
|
271
|
+
|
|
272
|
+
```yaml
|
|
273
|
+
version: 1
|
|
274
|
+
worker: tmux
|
|
275
|
+
tmux_command: "python worker.py --goal {goal_id}"
|
|
276
|
+
tmux_session_prefix: agentic-harness
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Local LLM worker configuration:
|
|
280
|
+
|
|
281
|
+
```yaml
|
|
282
|
+
version: 1
|
|
283
|
+
worker: local_llm
|
|
284
|
+
llm_endpoint: http://127.0.0.1:4000/v1/chat/completions
|
|
285
|
+
llm_model: local-model
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
GitHub Actions worker configuration:
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
version: 1
|
|
292
|
+
worker: github_actions
|
|
293
|
+
github_owner: moortekweb-art
|
|
294
|
+
github_repo: agentic-harness
|
|
295
|
+
github_workflow_id: ci.yml
|
|
296
|
+
github_token: token-from-your-secret-store
|
|
297
|
+
github_wait: true
|
|
298
|
+
github_api_version: 2026-03-10
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Configuration is intentionally small and strict: unsupported schema versions,
|
|
302
|
+
unknown keys, unsupported workers, malformed values, and workers without their
|
|
303
|
+
required settings are rejected instead of silently ignored. Config files are
|
|
304
|
+
parsed with PyYAML, so flat keys and grouped sections are both supported.
|
|
305
|
+
|
|
306
|
+
## Review Helpers
|
|
307
|
+
|
|
308
|
+
The core review module includes small deterministic criteria factories:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
from agentic_harness.core import (
|
|
312
|
+
DeterministicReviewer,
|
|
313
|
+
artifact_exists,
|
|
314
|
+
command_passes,
|
|
315
|
+
file_changed,
|
|
316
|
+
git_clean,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
reviewer = DeterministicReviewer([
|
|
320
|
+
artifact_exists(".", ".agentic-harness/runs/example/report.md"),
|
|
321
|
+
command_passes(["python", "-m", "pytest", "tests/", "-q"]),
|
|
322
|
+
file_changed(".", "CHANGELOG.md"),
|
|
323
|
+
git_clean("."),
|
|
324
|
+
])
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
You can also configure common review gates in `.agentic-harness/config.yml`:
|
|
328
|
+
|
|
329
|
+
```yaml
|
|
330
|
+
version: 1
|
|
331
|
+
worker:
|
|
332
|
+
type: shell
|
|
333
|
+
shell_command:
|
|
334
|
+
- make
|
|
335
|
+
- agent-goal
|
|
336
|
+
review:
|
|
337
|
+
command:
|
|
338
|
+
- python
|
|
339
|
+
- -m
|
|
340
|
+
- pytest
|
|
341
|
+
- tests/
|
|
342
|
+
- -q
|
|
343
|
+
git_clean: true
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
`GitHubActionsAdapter` dispatches workflows by default. Set `github_wait: true`
|
|
347
|
+
or `wait_for_completion=True` to wait for the exact workflow run returned by
|
|
348
|
+
GitHub's modern workflow dispatch API. Older GitHub API responses that do not
|
|
349
|
+
return a run URL fall back to polling workflow_dispatch runs created after the
|
|
350
|
+
dispatch request.
|
|
351
|
+
|
|
352
|
+
## Public API
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
from agentic_harness import Goal, Supervisor, Worker
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Contributing
|
|
359
|
+
|
|
360
|
+
Issues and pull requests are welcome. Good first contributions:
|
|
361
|
+
|
|
362
|
+
- Add adapter examples for common local coding agents.
|
|
363
|
+
- Improve the deterministic review helpers.
|
|
364
|
+
- Improve examples for common local workflows.
|
|
365
|
+
- Write docs for running the harness in a small team.
|
|
366
|
+
|
|
367
|
+
Keep the core small. If a feature assumes a particular server, model provider, or operator workflow, it probably belongs in an adapter or example.
|
|
368
|
+
|
|
369
|
+
## License
|
|
370
|
+
|
|
371
|
+
MIT. Copyright (c) 2026 Michael / Moortekweb. See [LICENSE](LICENSE) and
|
|
372
|
+
[AUTHORS.md](AUTHORS.md).
|
|
373
|
+
|
|
374
|
+
## Support
|
|
375
|
+
|
|
376
|
+
If Agentic Harness helps your local AI workflow, you can support the project
|
|
377
|
+
here:
|
|
378
|
+
|
|
379
|
+
https://buymeacoffee.com/moortekweb3
|