simplicio-loop 3.9.1__tar.gz → 3.11.0__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.
- {simplicio_loop-3.9.1/simplicio_loop.egg-info → simplicio_loop-3.11.0}/PKG-INFO +1 -12
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/README.md +55 -85
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/pyproject.toml +2 -7
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/__init__.py +2 -2
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/README.md +1 -1
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/action_gate.py +34 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/loop_stop.py +24 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/orient_rewrite.py +24 -1
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/simplicio_dashboard.py +2 -5
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/simplicio_watch.py +25 -22
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-learn/SKILL.md +12 -2
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-loop/SKILL.md +4 -4
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-orient/SKILL.md +7 -7
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/SKILL.md +69 -33
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/extension-points.md +9 -5
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/orchestration.md +19 -12
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/quality-safety-delivery.md +9 -3
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/token-capture.md +2 -2
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/token-economy.md +11 -11
- simplicio_loop-3.11.0/simplicio_loop/_bundle/skills/simplicio-tasks/references/video-evidence.md +108 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0/simplicio_loop.egg-info}/PKG-INFO +1 -12
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop.egg-info/SOURCES.txt +0 -1
- simplicio_loop-3.11.0/simplicio_loop.egg-info/requires.txt +9 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/tests/test_action_gate.py +5 -1
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/tests/test_worker_smoke.py +41 -2
- simplicio_loop-3.9.1/simplicio_loop/_bundle/skills/simplicio-tasks/references/headroom-adapter.md +0 -246
- simplicio_loop-3.9.1/simplicio_loop/_bundle/skills/simplicio-tasks/references/video-evidence.md +0 -111
- simplicio_loop-3.9.1/simplicio_loop.egg-info/requires.txt +0 -22
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/LICENSE +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/MANIFEST.in +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/PYPI.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/setup.cfg +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/hooks.claude.json +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/hooks.json +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/learn_stop.py +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/loop_capture.py +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/orient_clamp.py +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-compress/SKILL.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-review/SKILL.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/agentsview-adapter.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/azure-devops-adapter.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/lmcache-adapter.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/standing-loop-247.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/understand-anything-adapter.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/web-evidence.md +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/cli.py +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop.egg-info/dependency_links.txt +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop.egg-info/entry_points.txt +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop.egg-info/top_level.txt +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/tests/test_loop_e2e.py +0 -0
- {simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/tests/test_worker_selftests.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simplicio-loop
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.11.0
|
|
4
4
|
Summary: The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime.
|
|
5
5
|
Author-email: Wesley Simplicio <wesleybob4@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -26,17 +26,6 @@ Requires-Dist: pytest>=7; extra == "dev"
|
|
|
26
26
|
Provides-Extra: ml
|
|
27
27
|
Requires-Dist: model2vec>=0.3; extra == "ml"
|
|
28
28
|
Requires-Dist: numpy>=1.21; extra == "ml"
|
|
29
|
-
Provides-Extra: onnx
|
|
30
|
-
Requires-Dist: onnxruntime>=1.16; extra == "onnx"
|
|
31
|
-
Requires-Dist: huggingface_hub>=0.20; extra == "onnx"
|
|
32
|
-
Requires-Dist: tokenizers>=0.15; extra == "onnx"
|
|
33
|
-
Requires-Dist: numpy>=1.21; extra == "onnx"
|
|
34
|
-
Requires-Dist: pillow>=9; extra == "onnx"
|
|
35
|
-
Provides-Extra: kompress
|
|
36
|
-
Requires-Dist: onnxruntime>=1.16; extra == "kompress"
|
|
37
|
-
Requires-Dist: huggingface_hub>=0.20; extra == "kompress"
|
|
38
|
-
Requires-Dist: tokenizers>=0.15; extra == "kompress"
|
|
39
|
-
Requires-Dist: numpy>=1.21; extra == "kompress"
|
|
40
29
|
Dynamic: license-file
|
|
41
30
|
|
|
42
31
|
# simplicio-loop
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
<a href="#-the-11-skills--accelerators"><img src="https://img.shields.io/badge/skills-11-7C3AED" alt="11 skills"></a>
|
|
10
10
|
<a href="#-source-adapters"><img src="https://img.shields.io/badge/source%20adapters-5-00E08A" alt="5 source adapters"></a>
|
|
11
11
|
<a href="#-11-runtimes-one-protocol"><img src="https://img.shields.io/badge/runtimes-11-2563EB" alt="11 runtimes"></a>
|
|
12
|
-
<a href="#-the-
|
|
13
|
-
<a href="#-token-economy"><img src="https://img.shields.io/badge/tokens-up%20to%2096%25%20fewer-green" alt="Up to
|
|
12
|
+
<a href="#-the-48-extension-points"><img src="https://img.shields.io/badge/extension%20points-48-00E08A" alt="48 extension points"></a>
|
|
13
|
+
<a href="#-token-economy"><img src="https://img.shields.io/badge/tokens-up%20to%2096%25%20fewer-green" alt="Up to 90% fewer tokens"></a>
|
|
14
14
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License"></a>
|
|
15
|
+
<a href="https://discord.gg/wM6tr7xVb"><img src="https://img.shields.io/badge/Discord-Join%20Simplicio-5865F2?logo=discord&logoColor=white" alt="Join the Simplicio Discord"></a>
|
|
15
16
|
</p>
|
|
16
17
|
|
|
17
18
|
<p align="center">
|
|
@@ -62,7 +63,7 @@ loop that **runs the code (not just compiles it)**, opens PRs, resolves CI/revie
|
|
|
62
63
|
and keeps watching **24/7** for new work — all behind safety gates and a hard cost kill-switch.
|
|
63
64
|
|
|
64
65
|
```text
|
|
65
|
-
/simplicio-tasks
|
|
66
|
+
/simplicio-tasks finish all open issues
|
|
66
67
|
→ identity + pre-flight (kill-switch, auth, watcher)
|
|
67
68
|
→ discover 50 issues · dedup · build dependency DAG
|
|
68
69
|
→ autoscale fleet = 14 · pipeline implement→review→merge
|
|
@@ -74,22 +75,26 @@ and keeps watching **24/7** for new work — all behind safety gates and a hard
|
|
|
74
75
|
Three things make it different: it is a **super-plugin of focused skills**, it runs the **same
|
|
75
76
|
protocol on 11 runtimes**, and it does all of this with **aggressive, honest token economy**.
|
|
76
77
|
|
|
78
|
+
<p align="center">
|
|
79
|
+
<img src="assets/simplicio-loop-infographic.png" alt="simplicio-loop — the whole system at a glance: 6 core skills, 5 satellites, 5 accelerators, 48 extension points, 11 runtimes, up to 90% fewer tokens" width="920" />
|
|
80
|
+
</p>
|
|
81
|
+
|
|
77
82
|
---
|
|
78
83
|
|
|
79
|
-
## 📘 Official capability record (v3.
|
|
84
|
+
## 📘 Official capability record (v3.10.2)
|
|
80
85
|
|
|
81
86
|
The complete, official roster of what `simplicio-tasks` ships — every capability below is **real,
|
|
82
|
-
runnable, and tested** (`python3 scripts/check.py`: claims-audit 4/4 +
|
|
87
|
+
runnable, and tested** (`python3 scripts/check.py`: claims-audit 4/4 + 28 tests). Each links to its
|
|
83
88
|
deep section and its worker.
|
|
84
89
|
|
|
85
90
|
| Capability | What it does | Proof / worker | Details |
|
|
86
91
|
|---|---|---|---|
|
|
87
|
-
| 🎬 **Video evidence** (`video_evidence`) |
|
|
92
|
+
| 🎬 **Video evidence** (`video_evidence`) | Records the **real browser session** as moving proof a UI change works (Playwright, default); renders a **deterministic captioned MP4** with [hyperframes](https://github.com/heygen-com/hyperframes) for an explicit explainer request (`/simplicio-tasks make a video of screen X`) | `scripts/video_evidence.py` · BLOCKED (never fake-pass) without the toolchain | [§ Video evidence](#-video-evidence--playwright-by-default-hyperframes-on-request) |
|
|
88
93
|
| 🧠 **Attempt memory + stall detector** | A durable run-journal (`.orchestrator/loop/journal.jsonl`) + a stall detector so the loop **changes strategy instead of oscillating**; incremental triage (`since`) reads only the delta each turn | `scripts/loop_journal.py` · `selftest` 9/9 | [§ Anti-oscillation](#-attempt-memory--stall-detector-anti-oscillation) |
|
|
94
|
+
| 🧭 **Repo conventions** (`repo_conventions`) | **Learns the repo's own playbook** — mines git history + merged PRs + static config into `.orchestrator/conventions.json` so every new branch/commit/PR mirrors the team's established style; worktree-per-item isolation is the default | `scripts/repo_conventions.py` · `selftest` 19/19 | [§ The full flow](#️-the-full-flow--from-demand-to-delivery) |
|
|
89
95
|
| 🔒 **Fail-closed safety gate** (`action_gate`) | A `PreToolUse`/git-pre-push hook that **mechanically blocks** force-push, history rewrite, mass-delete, destructive DDL, infra teardown, and secret-laden commits/pushes — Step 5 made executable, not prose | `hooks/action_gate.py` · `selftest` 15/15 | [§ Safety](#-safety-non-negotiable) |
|
|
90
96
|
| 🔬 **Local verification** | A test suite (worker selftests + an **e2e of the loop driver** proving evidence-gated exit) + a **claims-audit** (referenced scripts exist · counts consistent · `_bundle ≡ source`) — all local, **no paid CI** | `scripts/check.py` · `scripts/claims_audit.py` · `tests/` | [§ Tests & local checks](#-tests--local-checks-no-paid-ci) |
|
|
91
97
|
| ✅ **Honest savings** | The savings line is now **evidence-gated, not mandatory** — a number is shown only with a measured receipt (clamp/signatures/cache/`deterministic_edit`/ledger); never fabricated | token-economy contract | [§ Token economy](#-token-economy) |
|
|
92
|
-
| 💳 **Open-core billing** | A deterministic, privacy-preserving meter→invoice over the metering the loop already produces (kill-switch + `savings_ledger`) — three tiers (seat/run/metered) | `scripts/billing_aggregator.py` · `selftest` 11/11 | [PRICING.md](PRICING.md) |
|
|
93
98
|
|
|
94
99
|
Two loop **modes** make termination explicit: **converge** (a single hard task — ends on the
|
|
95
100
|
evidence-gated `<promise>` or a stall escalation) vs **drain** (a queue — ends when the source
|
|
@@ -111,7 +116,7 @@ fallback.
|
|
|
111
116
|
|
|
112
117
|
| # | Capability | Absorbs | What it does | Token impact |
|
|
113
118
|
|---|---|---|---|---|
|
|
114
|
-
| 1 | 🔁 **simplicio-tasks** | — | The orchestrator loop:
|
|
119
|
+
| 1 | 🔁 **simplicio-tasks** | — | The orchestrator loop: 48 extension points, dual-path router, self-audit convergence | Core |
|
|
115
120
|
| 2 | ♾️ **simplicio-loop** | [ralph-loop](https://github.com/cursor/plugins/tree/main/ralph-loop) | Hardened Ralph loop: evidence-gated `<promise>` exit, max_iterations cap | Loop drive |
|
|
116
121
|
| 3 | 🧱 **simplicio-orient** | [rtk](https://github.com/rtk-ai/rtk) + [caveman](https://github.com/JuliusBrussee/caveman) | Terminal-first execution, output-reduction catalog, tee-cache, signatures-read | L0 deterministic |
|
|
117
122
|
| 4 | 🔥 **simplicio-review** | [thermos](https://github.com/cursor/plugins/tree/main/thermos) | Parallel adversarial review on distinct rubrics → deduped verdict | Quality gate |
|
|
@@ -120,8 +125,8 @@ fallback.
|
|
|
120
125
|
| 7 | 🧭 **Understand Anything** | [Egonex-AI](https://github.com/Egonex-AI/Understand-Anything) | Knowledge graph orient: semantic search, guided tours, dependency graph | **L0 zero tokens** |
|
|
121
126
|
| 8 | 📊 **agentsview** | [kenn-io](https://github.com/kenn-io/agentsview) | Session analytics, cost tracking, stalled-session discovery | **L1** SQL only |
|
|
122
127
|
| 9 | ⚡ **LMCache** | [LMCache](https://github.com/LMCache/LMCache) | KV cache between loop turns — 40-70% TTFT reduction on local models | GPU time ↓ |
|
|
123
|
-
| 10 | 🗜️ **Simplicio capture engine** | `engine/simplicio_engine.py` (native, stdlib-only
|
|
124
|
-
| 11 | 🎬 **video_evidence (
|
|
128
|
+
| 10 | 🗜️ **Simplicio capture engine** | `engine/simplicio_engine.py` (native, stdlib-only) | Transparent capture proxy: forwards to the real provider, measures + deterministically compresses, writes `proxy_savings.json` | **deterministic** |
|
|
129
|
+
| 11 | 🎬 **video_evidence** | Playwright (default) · [hyperframes](https://github.com/heygen-com/hyperframes) (on request) | Records the **real session** as moving proof of a UI change (Playwright); renders a **deterministic captioned MP4** explainer with hyperframes when the video IS the deliverable | Evidence producer |
|
|
125
130
|
|
|
126
131
|
Each skill lives under [`.claude/skills/`](.claude/skills); each accelerator has a reference doc
|
|
127
132
|
under `.claude/skills/simplicio-tasks/references/` (the video producer:
|
|
@@ -223,7 +228,7 @@ flowchart TD
|
|
|
223
228
|
subgraph QG["7 · Quality gates"]
|
|
224
229
|
direction LR
|
|
225
230
|
Q1["AC gate = real DoD"]
|
|
226
|
-
Q2["WORKS not just compiles · web_verify (Playwright) · video_evidence (hyperframes
|
|
231
|
+
Q2["WORKS not just compiles · web_verify (Playwright) · video_evidence (Playwright recording · hyperframes on request)"]
|
|
227
232
|
Q3["adversarial review · thermos rubrics"]
|
|
228
233
|
end
|
|
229
234
|
QG --> SG
|
|
@@ -294,42 +299,36 @@ loop_journal.py stall --k 3 --exit-code # PROGRESS → re-feed · STALLED
|
|
|
294
299
|
|
|
295
300
|
---
|
|
296
301
|
|
|
297
|
-
## 🎬 Video evidence —
|
|
302
|
+
## 🎬 Video evidence — Playwright by default, hyperframes on request
|
|
298
303
|
|
|
299
|
-
The loop
|
|
300
|
-
|
|
301
|
-
(by HeyGen) — it renders HTML/CSS/media compositions to a **deterministic MP4** ("same input, same
|
|
302
|
-
frames, same output"), so the demo is a CI-reproducible artifact, not a throwaway recording. No API
|
|
303
|
-
keys; local render via headless Chrome + FFmpeg (Node 22+).
|
|
304
|
-
|
|
305
|
-
Two ways it fires — both via the `video_evidence` extension point (worker
|
|
306
|
-
[`scripts/video_evidence.py`](scripts/video_evidence.py), contract
|
|
304
|
+
The loop produces **demo videos** as proof a change works — **two engines**, one `video_evidence`
|
|
305
|
+
extension point (worker [`scripts/video_evidence.py`](scripts/video_evidence.py), contract
|
|
307
306
|
[`references/video-evidence.md`](.claude/skills/simplicio-tasks/references/video-evidence.md)):
|
|
308
307
|
|
|
309
|
-
1. **
|
|
310
|
-
the
|
|
308
|
+
1. **Default — the normal evidence flow uses Playwright.** After a UI change, `video_evidence`
|
|
309
|
+
records the **real browser session** driving the screen (Playwright native video → `.webm`, →
|
|
310
|
+
`.mp4` with FFmpeg) — the strongest "works, not just compiles" receipt (Step 4b) and a valid
|
|
311
|
+
evidence-gated `<promise>`.
|
|
311
312
|
|
|
312
|
-
```
|
|
313
|
-
/
|
|
314
|
-
|
|
315
|
-
→ scaffold a hyperframes composition → npx hyperframes render → deterministic MP4
|
|
316
|
-
→ attach the MP4 to the PR as evidence + close with the link
|
|
313
|
+
```bash
|
|
314
|
+
python3 scripts/video_evidence.py verify --url http://localhost:3000/login \
|
|
315
|
+
--name login-demo --expect "Sign in" --issue 42 [--upload --pr 42]
|
|
317
316
|
```
|
|
318
317
|
|
|
319
|
-
2. **
|
|
320
|
-
|
|
321
|
-
|
|
318
|
+
2. **On request — a personalized explainer uses hyperframes.** When the deliverable IS a video
|
|
319
|
+
("make an explainer video of screen X"), the orchestrator renders a **deterministic, captioned
|
|
320
|
+
slideshow** of the `web_verify` screenshots with
|
|
321
|
+
[**hyperframes**](https://github.com/heygen-com/hyperframes) (by HeyGen — "same input, same
|
|
322
|
+
frames, same output", CI-reproducible, no API keys, local render via headless Chrome + FFmpeg).
|
|
322
323
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
324
|
+
```text
|
|
325
|
+
/simplicio-tasks make an explainer video of the system login screen
|
|
326
|
+
→ detect: video-creation request → web_verify captures the screens
|
|
327
|
+
→ video_evidence verify --engine hyperframes → deterministic MP4 → attached to the PR
|
|
328
|
+
```
|
|
326
329
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
python3 scripts/video_evidence.py detect --goal "grave um vídeo da tela de checkout"
|
|
330
|
-
python3 scripts/video_evidence.py verify --name checkout-demo \
|
|
331
|
-
--frames .orchestrator/tee/web --title "Checkout" --issue 42 [--upload --pr 42]
|
|
332
|
-
```
|
|
330
|
+
Either engine: a video that never recorded/rendered yields **BLOCKED**, never a fake pass. Evidence
|
|
331
|
+
is always a **file path + boolean verdict** — never video bytes in context (token economy).
|
|
333
332
|
|
|
334
333
|
---
|
|
335
334
|
|
|
@@ -341,10 +340,10 @@ python3 scripts/video_evidence.py verify --name checkout-demo \
|
|
|
341
340
|
| Terminal-first execution | Facts from shell, not LLM hallucination |
|
|
342
341
|
| Output-reduction catalog | Caps per command type (`CAP_ERRORS=20`, `CAP_WARNINGS=10`, `CAP_LIST=20`) — `orient_clamp.py` |
|
|
343
342
|
| Tee+CCR cache on failure | Never re-run a failed command — read the cached output |
|
|
344
|
-
| Signatures-only reads | `simplicio signatures <file>` — 870-line file → 65 lines (**93% saved**), bodies stripped |
|
|
343
|
+
| Signatures-only reads | `simplicio-cli signatures <file>` — 870-line file → 65 lines (**93% saved**), bodies stripped |
|
|
345
344
|
| `simplicio-compress` | Terse prose + one-time memory compaction |
|
|
346
345
|
| `orient_clamp.py` | Clamp + tee on every shell command, zero wiring |
|
|
347
|
-
| Native response cache | repeated deterministic (temp=0) request → served from cache, skips the LLM call (**100% on hit**) — `simplicio cache`, on by default (`SIMPLICIO_CACHE=0` to disable) |
|
|
346
|
+
| Native response cache | repeated deterministic (temp=0) request → served from cache, skips the LLM call (**100% on hit**) — `simplicio-cli cache`, on by default (`SIMPLICIO_CACHE=0` to disable) |
|
|
348
347
|
| Simplicio capture proxy + MCP | 60-95% fewer tokens on tool outputs via a transparent compression daemon |
|
|
349
348
|
|
|
350
349
|
Savings only count on a verified-correct outcome. Baseline = the cheapest sensible non-orchestrated
|
|
@@ -368,11 +367,11 @@ Two different things happen when you call **`simplicio-tasks`**, and they behave
|
|
|
368
367
|
| Runtime | Economy (skill) | Measurement (monitor) |
|
|
369
368
|
|---|---|---|
|
|
370
369
|
| **Hermes** | ✓ | ✓ **automatic** — already routed through the proxy (`base_url → :8788`) |
|
|
371
|
-
| **Claude** | ✓ (skill + hooks) | ✗ by default — Claude talks to `api.anthropic.com` directly; measured only once routed (`simplicio wrap claude`, or `ANTHROPIC_BASE_URL → http://127.0.0.1:8788`) |
|
|
372
|
-
| **Codex** | ✓ (skill) | ✗ by default — `simplicio init codex` adds the MCP tools but does not route LLM traffic; measured with `simplicio wrap codex` or an OpenAI base-url pointing at the proxy |
|
|
370
|
+
| **Claude** | ✓ (skill + hooks) | ✗ by default — Claude talks to `api.anthropic.com` directly; measured only once routed (`simplicio-cli wrap claude`, or `ANTHROPIC_BASE_URL → http://127.0.0.1:8788`) |
|
|
371
|
+
| **Codex** | ✓ (skill) | ✗ by default — `simplicio-cli init codex` adds the MCP tools but does not route LLM traffic; measured with `simplicio-cli wrap codex` or an OpenAI base-url pointing at the proxy |
|
|
373
372
|
|
|
374
373
|
So: the **savings happen on every runtime**; the **monitor tallies them automatically on Hermes**, and on
|
|
375
|
-
Claude/Codex after a **one-time routing step** (`simplicio wrap …` / base-url → `:8788`). Without routing,
|
|
374
|
+
Claude/Codex after a **one-time routing step** (`simplicio-cli wrap …` / base-url → `:8788`). Without routing,
|
|
376
375
|
the economy still applies — the monitor just won't count those tokens. `scripts/simplicio-economy.sh wire`
|
|
377
376
|
does this routing for OpenAI-compatible clients at install time.
|
|
378
377
|
|
|
@@ -401,8 +400,8 @@ capture runs **without invoking the loop** — see `references/token-capture.md`
|
|
|
401
400
|
### 🛠️ The capture engine — one native module, every command
|
|
402
401
|
|
|
403
402
|
[`engine/simplicio_engine.py`](engine/simplicio_engine.py) is the native Simplicio capture engine
|
|
404
|
-
(stdlib-only, fail-open) — a **
|
|
405
|
-
|
|
403
|
+
(stdlib-only, fail-open) — a **native, transparent capture proxy + deterministic compression engine
|
|
404
|
+
with no external dependency**. Run any
|
|
406
405
|
command via the [`scripts/simplicio-engine`](scripts/simplicio-engine) wrapper (e.g. `simplicio-engine doctor`):
|
|
407
406
|
|
|
408
407
|
| Command | What it does |
|
|
@@ -412,7 +411,6 @@ command via the [`scripts/simplicio-engine`](scripts/simplicio-engine) wrapper (
|
|
|
412
411
|
| `cache` | native response cache (`stats`/`clear`) — a repeated deterministic request is served from cache, skipping the LLM call |
|
|
413
412
|
| `signatures` | signatures-only view of a source file (bodies stripped, ~93% fewer tokens to read code) |
|
|
414
413
|
| `semantic` | reversible extractive (semantic-lite) compression |
|
|
415
|
-
| `kompress` | **ONNX** semantic token-pruning via the real `kompress-v2-base` model |
|
|
416
414
|
| `detect` | content-type detection + smart per-block routing |
|
|
417
415
|
| `rag` | TF-IDF (or `--ml` embedding) retrieval over the CCR memory store |
|
|
418
416
|
| `memory` | CCR compress-cache-retrieve store (`remember`/`recall`/`forget`/`list`/`stats`) |
|
|
@@ -420,25 +418,6 @@ command via the [`scripts/simplicio-engine`](scripts/simplicio-engine) wrapper (
|
|
|
420
418
|
| `init` / `wrap` | register Simplicio into a client (Claude / Codex / Copilot / OpenClaw) · run a client with capture routing |
|
|
421
419
|
| `report` / `audit` / `capture` / `evals` | savings report · audit a tree for compression opportunity · dry-run a request · compression regression gate |
|
|
422
420
|
|
|
423
|
-
### 🧠 Optional real ML models — `pip install "simplicio-loop[onnx]"`
|
|
424
|
-
|
|
425
|
-
Four **real**, public (Apache-2.0) ONNX models run natively — the same models the upstream uses.
|
|
426
|
-
Without the extra, the deterministic stdlib path covers everything; models download on first use.
|
|
427
|
-
|
|
428
|
-
| Model | Command | Use |
|
|
429
|
-
|---|---|---|
|
|
430
|
-
| `kompress-v2-base` | `simplicio kompress` | semantic token pruning |
|
|
431
|
-
| `technique-router-onnx` | `simplicio router` | technique routing |
|
|
432
|
-
| `all-MiniLM-L6-v2-onnx` | `simplicio embed` · `rag --ml` | embeddings + semantic RAG |
|
|
433
|
-
| `siglip-image-encoder-onnx` | `simplicio image` | image-compression content verifier |
|
|
434
|
-
|
|
435
|
-
### ⚙️ Native Rust performance core (optional)
|
|
436
|
-
|
|
437
|
-
[`rust/`](rust) ships four crates ported + rebranded from the upstream (Apache-2.0; `NOTICE` credits it):
|
|
438
|
-
`simplicio-core` (compressors + smart-crusher), `simplicio-py` (PyO3 bindings), `simplicio-proxy`
|
|
439
|
-
(axum reverse proxy), `simplicio-parity` (Rust↔Python parity harness). Build with `maturin` — the Python
|
|
440
|
-
engine works fully without them; the crates only add native speed.
|
|
441
|
-
|
|
442
421
|
---
|
|
443
422
|
|
|
444
423
|
## 🏛️ Design pillars (in detail)
|
|
@@ -468,9 +447,8 @@ pwsh scripts/install.ps1 <runtime> [-Global] # Windows
|
|
|
468
447
|
|
|
469
448
|
**Install is complete by default — it installs everything.** One command sets up the whole stack:
|
|
470
449
|
the two loop operators (`simplicio-mapper` + `simplicio-cli`, auto-handling PEP 668 / externally-managed
|
|
471
|
-
Python and symlinking the binaries onto `PATH`), the **full Python stack** (the package
|
|
472
|
-
|
|
473
|
-
work), the **6 skills + hooks** with the loop's Stop hook wired, and the **always-on capture proxy**
|
|
450
|
+
Python and symlinking the binaries onto `PATH`), the **full Python stack** (the package itself),
|
|
451
|
+
the **6 skills + hooks** with the loop's Stop hook wired, and the **always-on capture proxy**
|
|
474
452
|
with Claude + Codex + Hermes **routed and measured** in the background. The **dashboard opens once** on a
|
|
475
453
|
fresh install, then it's on-demand (`simplicio-loop dashboard` / `simplicio-economy.sh monitor`); the
|
|
476
454
|
**menu-bar tray never opens by itself** — nothing is forced to stay open.
|
|
@@ -495,16 +473,17 @@ python3 scripts/doctor.py --repair # install/wire what's fixable; make everyth
|
|
|
495
473
|
```
|
|
496
474
|
|
|
497
475
|
`doctor` separates **REQUIRED** (python3, the two loop operators, the 6 skills, the loop hooks, the
|
|
498
|
-
capture proxy — `--repair` installs/wires them) from **OPTIONAL** accelerators (the
|
|
499
|
-
|
|
476
|
+
capture proxy — `--repair` installs/wires them) from **OPTIONAL** accelerators (the tray dep).
|
|
477
|
+
**Missing an optional piece is never a failure and
|
|
500
478
|
never blocks** — the Python engine + the deterministic path cover everything; the exit code is 0 as
|
|
501
479
|
long as every REQUIRED item is healthy.
|
|
502
480
|
|
|
503
|
-
Or, on Claude Code / Cursor,
|
|
481
|
+
Or, on Claude Code / Cursor, install it straight from the latest GitHub release (no marketplace):
|
|
504
482
|
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
|
|
483
|
+
```bash
|
|
484
|
+
gh release download --repo wesleysimplicio/simplicio-loop --archive tar.gz
|
|
485
|
+
tar xzf simplicio-loop-*.tar.gz && cd simplicio-loop-*/
|
|
486
|
+
bash scripts/install.sh claude # or: bash scripts/install.sh cursor
|
|
508
487
|
```
|
|
509
488
|
|
|
510
489
|
Then:
|
|
@@ -530,7 +509,7 @@ gate + secret-scan on. With `ceiling = 0` the watcher refuses to run unattended
|
|
|
530
509
|
mass-file delete → stop and ask. Headless + no approver → remove the destructive capability.
|
|
531
510
|
- **Enforced, not just promised** — `hooks/action_gate.py` is a **fail-closed** `PreToolUse` /
|
|
532
511
|
git-pre-push hook that mechanically blocks the above (and secret-laden commits) *before* they run.
|
|
533
|
-
The safety contract holds even if the model forgets it. `selftest` proves the ruleset (
|
|
512
|
+
The safety contract holds even if the model forgets it. `selftest` proves the ruleset (15/15).
|
|
534
513
|
- **4-state pre-execution verdict** — optimization may never raise a command's risk tier.
|
|
535
514
|
- **Trust-before-load** — perception-shaping config (clamp profiles, suppression lists) is
|
|
536
515
|
untrusted until a human reviews and hash-pins it.
|
|
@@ -568,12 +547,3 @@ python3 scripts/check.py # the whole gate (audit + tests)
|
|
|
568
547
|
## 📄 License
|
|
569
548
|
|
|
570
549
|
MIT
|
|
571
|
-
|
|
572
|
-
## 💳 Pricing
|
|
573
|
-
|
|
574
|
-
The engine is **free and MIT** — fully self-hostable, never crippled. A proposed **open-core
|
|
575
|
-
hosted tier** (managed 24/7 watcher, hosted operators, retained savings dashboard, distributed
|
|
576
|
-
`video_evidence` render) is sketched in [`PRICING.md`](PRICING.md), along with a deterministic,
|
|
577
|
-
privacy-preserving billing architecture built on the metering primitives the loop already
|
|
578
|
-
produces (`loop-budget.json` kill-switch + `savings_ledger`). It is a proposal — nothing is billed
|
|
579
|
-
today.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simplicio-loop"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.11.0"
|
|
8
8
|
description = "The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime."
|
|
9
9
|
readme = "PYPI.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -29,7 +29,7 @@ dependencies = [
|
|
|
29
29
|
"simplicio-cli",
|
|
30
30
|
]
|
|
31
31
|
|
|
32
|
-
# Optional: the real embedding backend for `simplicio semantic --ml` / `simplicio rag --ml`.
|
|
32
|
+
# Optional: the real embedding backend for `simplicio-cli semantic --ml` / `simplicio-cli rag --ml`.
|
|
33
33
|
# The native engine itself is stdlib-only; this only enables embedding-based semantic dedup +
|
|
34
34
|
# meaning retrieval. `pip install "simplicio-loop[ml]"`.
|
|
35
35
|
[project.optional-dependencies]
|
|
@@ -37,11 +37,6 @@ dependencies = [
|
|
|
37
37
|
# only a convenience for nicer output / IDE integration — never required.
|
|
38
38
|
dev = ["pytest>=7"]
|
|
39
39
|
ml = ["model2vec>=0.3", "numpy>=1.21"]
|
|
40
|
-
# ONNX model commands (the REAL headroom models, downloaded on first use):
|
|
41
|
-
# kompress -> chopratejas/kompress-v2-base (~274MB) · router -> chopratejas/technique-router-onnx (~32MB)
|
|
42
|
-
# embed -> Qdrant/all-MiniLM-L6-v2-onnx (~90MB). `pip install "simplicio-loop[onnx]"`.
|
|
43
|
-
onnx = ["onnxruntime>=1.16", "huggingface_hub>=0.20", "tokenizers>=0.15", "numpy>=1.21", "pillow>=9"]
|
|
44
|
-
kompress = ["onnxruntime>=1.16", "huggingface_hub>=0.20", "tokenizers>=0.15", "numpy>=1.21"]
|
|
45
40
|
|
|
46
41
|
[project.urls]
|
|
47
42
|
Homepage = "https://github.com/wesleysimplicio/simplicio-loop"
|
|
@@ -39,7 +39,7 @@ the ruleset (14/14).
|
|
|
39
39
|
`orient_clamp.py` is a plain wrapper — use it anywhere, any runtime, no hooks:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
python3 hooks/orient_clamp.py --
|
|
42
|
+
python3 hooks/orient_clamp.py -- go test ./... # reduced output, tee log on failure
|
|
43
43
|
python3 hooks/orient_clamp.py --json -- git diff # machine summary
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -41,6 +41,34 @@ except Exception:
|
|
|
41
41
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
42
42
|
REPO = os.path.dirname(HERE)
|
|
43
43
|
|
|
44
|
+
|
|
45
|
+
def _project_relevant():
|
|
46
|
+
"""Project-relevance gate for the PreToolUse path ONLY.
|
|
47
|
+
|
|
48
|
+
The plugin's Bash gate must not impose itself on every repo on the machine — it acts
|
|
49
|
+
only inside an active simplicio-loop project. Relevant when the opt-in env var
|
|
50
|
+
SIMPLICIO_LOOP (or SIMPLICIO_ORCHESTRATOR) is set, or when a `.orchestrator/` marker
|
|
51
|
+
dir (the orchestrator's state dir, created when the loop runs) exists in the current
|
|
52
|
+
working directory or an ancestor. Outside such a project the PreToolUse hook no-ops.
|
|
53
|
+
The explicit CLI / git-hook entry points (check / scan-diff / selftest) are NOT gated —
|
|
54
|
+
they are invoked deliberately and always run.
|
|
55
|
+
"""
|
|
56
|
+
if os.environ.get("SIMPLICIO_LOOP") or os.environ.get("SIMPLICIO_ORCHESTRATOR"):
|
|
57
|
+
return True
|
|
58
|
+
home = os.path.realpath(os.path.expanduser("~"))
|
|
59
|
+
d = os.path.realpath(os.getcwd())
|
|
60
|
+
for _ in range(40): # depth backstop so an off-home tree can't climb forever
|
|
61
|
+
parent = os.path.dirname(d)
|
|
62
|
+
# Never treat the home dir or a drive/filesystem root as a project marker location:
|
|
63
|
+
# a stray ~/.orchestrator, or a marker at a drive root, must not widen the scope.
|
|
64
|
+
if d == home or parent == d:
|
|
65
|
+
return False
|
|
66
|
+
if os.path.isdir(os.path.join(d, ".orchestrator")):
|
|
67
|
+
return True
|
|
68
|
+
d = parent
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
|
|
44
72
|
# Irreversible / history-rewriting / destructive ops → BLOCK and route to a human (Step 5).
|
|
45
73
|
# High-precision patterns: each is genuinely hard to undo; benign commands never match.
|
|
46
74
|
IRREVERSIBLE = [
|
|
@@ -193,6 +221,12 @@ def cmd_scan_diff(opts):
|
|
|
193
221
|
|
|
194
222
|
def from_pretooluse():
|
|
195
223
|
"""Claude PreToolUse mode: read tool call JSON on stdin, gate the Bash command."""
|
|
224
|
+
try:
|
|
225
|
+
relevant = _project_relevant()
|
|
226
|
+
except Exception:
|
|
227
|
+
relevant = True # safety gate: can't prove irrelevant → still run the gate (fail-closed)
|
|
228
|
+
if not relevant:
|
|
229
|
+
sys.exit(0) # outside a simplicio-loop project → no-op (project-relevance gate)
|
|
196
230
|
try:
|
|
197
231
|
raw = sys.stdin.read()
|
|
198
232
|
data = json.loads(raw) if raw.strip() else {}
|
|
@@ -23,6 +23,8 @@ DONE_FLAG = os.path.join(LOOP_DIR, "done")
|
|
|
23
23
|
LAST_RESP = os.path.join(LOOP_DIR, "last_response.txt")
|
|
24
24
|
STOP_SIGNAL = os.path.join(".orchestrator", "STOP")
|
|
25
25
|
BUDGET = os.path.join(".orchestrator", "loop-budget.json")
|
|
26
|
+
GATE_LOCK = os.path.join(LOOP_DIR, "gate.lock")
|
|
27
|
+
GATE_TTL_SEC = 1800 # 30 min — a stale lock must NEVER permanently trap the loop (fail-open)
|
|
26
28
|
|
|
27
29
|
EVIDENCE_RE = re.compile(
|
|
28
30
|
r"(https?://\S+/pull/\d+)" # a PR URL
|
|
@@ -108,6 +110,23 @@ def last_assistant_text(stdin):
|
|
|
108
110
|
return ""
|
|
109
111
|
|
|
110
112
|
|
|
113
|
+
def gate_running():
|
|
114
|
+
"""True when a background gate (verification workflow / CI / long task) is in flight + fresh.
|
|
115
|
+
|
|
116
|
+
The orchestrator touches `.orchestrator/loop/gate.lock` before launching a background gate and
|
|
117
|
+
removes it on completion. While present AND fresh, the turn ended because we are WAITING on that
|
|
118
|
+
gate — not because the loop is idle — so the Stop hook must NOT re-feed the goal. A stale lock
|
|
119
|
+
(older than the TTL) is ignored so a leftover file can never trap the agent (fail-open).
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
if not os.path.exists(GATE_LOCK):
|
|
123
|
+
return False
|
|
124
|
+
import time
|
|
125
|
+
return (time.time() - os.path.getmtime(GATE_LOCK)) < GATE_TTL_SEC
|
|
126
|
+
except Exception:
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
|
|
111
130
|
def budget_halted():
|
|
112
131
|
try:
|
|
113
132
|
if not os.path.exists(BUDGET):
|
|
@@ -139,6 +158,11 @@ def main():
|
|
|
139
158
|
# Explicit STOP signal beats everything.
|
|
140
159
|
if os.path.exists(STOP_SIGNAL):
|
|
141
160
|
cleanup_and_stop()
|
|
161
|
+
# Waiting on a background gate (workflow / CI / long task)? Let the turn end WITHOUT
|
|
162
|
+
# consuming an iteration or re-feeding — we are blocked on that gate, not idle. The gate's
|
|
163
|
+
# completion re-invokes the agent; the loop resumes then (lock is gone). Preserves state.
|
|
164
|
+
if gate_running():
|
|
165
|
+
allow_stop()
|
|
142
166
|
# (1) No active loop.
|
|
143
167
|
if not os.path.exists(SCRATCHPAD):
|
|
144
168
|
allow_stop()
|
{simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/orient_rewrite.py
RENAMED
|
@@ -26,11 +26,32 @@ CLAMP = os.path.join(os.path.dirname(os.path.abspath(__file__)), "orient_clamp.p
|
|
|
26
26
|
CONFIG = os.path.join(".orchestrator", "orient.toml")
|
|
27
27
|
DEFAULT_EXCLUDES = ["curl", "wget", "playwright", "ssh", "vim", "less", "top", "htop"]
|
|
28
28
|
|
|
29
|
+
|
|
30
|
+
def _project_relevant():
|
|
31
|
+
"""Project-relevance gate: this PreToolUse hook acts ONLY inside an active
|
|
32
|
+
simplicio-loop project, never on unrelated repos. Relevant when the opt-in env var
|
|
33
|
+
SIMPLICIO_LOOP (or SIMPLICIO_ORCHESTRATOR) is set, or a `.orchestrator/` marker dir
|
|
34
|
+
exists in the current working directory or an ancestor. Outside such a project the
|
|
35
|
+
hook no-ops and the command runs raw."""
|
|
36
|
+
if os.environ.get("SIMPLICIO_LOOP") or os.environ.get("SIMPLICIO_ORCHESTRATOR"):
|
|
37
|
+
return True
|
|
38
|
+
home = os.path.realpath(os.path.expanduser("~"))
|
|
39
|
+
d = os.path.realpath(os.getcwd())
|
|
40
|
+
for _ in range(40): # depth backstop so an off-home tree can't climb forever
|
|
41
|
+
parent = os.path.dirname(d)
|
|
42
|
+
# Never treat the home dir or a drive/filesystem root as a project marker location:
|
|
43
|
+
# a stray ~/.orchestrator, or a marker at a drive root, must not widen the scope.
|
|
44
|
+
if d == home or parent == d:
|
|
45
|
+
return False
|
|
46
|
+
if os.path.isdir(os.path.join(d, ".orchestrator")):
|
|
47
|
+
return True
|
|
48
|
+
d = parent
|
|
49
|
+
return False
|
|
50
|
+
|
|
29
51
|
# read-only, output-heavy commands worth clamping (prefix match on the first token(s))
|
|
30
52
|
ALLOW = [
|
|
31
53
|
"git status", "git log", "git diff", "git show", "git branch",
|
|
32
54
|
"ls", "ll", "dir", "rg ", "grep ", "cat ", "type ", "tree",
|
|
33
|
-
"cargo check", "cargo test", "cargo clippy", "cargo build",
|
|
34
55
|
"npm test", "npm run", "pnpm test", "yarn test", "jest", "vitest",
|
|
35
56
|
"go test", "go build", "go vet", "pytest", "python -m pytest",
|
|
36
57
|
"mvn ", "gradle ", "tsc", "eslint", "ruff", "golangci-lint",
|
|
@@ -61,6 +82,8 @@ def load_excludes():
|
|
|
61
82
|
|
|
62
83
|
def main():
|
|
63
84
|
try:
|
|
85
|
+
if not _project_relevant():
|
|
86
|
+
allow_unchanged() # outside a simplicio-loop project → no-op (project-relevance gate)
|
|
64
87
|
raw = sys.stdin.read()
|
|
65
88
|
data = json.loads(raw) if raw.strip() else {}
|
|
66
89
|
ti = data.get("tool_input", data.get("toolInput", {})) or {}
|
{simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/simplicio_dashboard.py
RENAMED
|
@@ -30,14 +30,11 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
|
30
30
|
# Structured savings file written by the capture engine — the primary data source.
|
|
31
31
|
SAVINGS_JSON_CANDIDATES = [
|
|
32
32
|
Path(HOME) / ".simplicio" / "proxy_savings.json",
|
|
33
|
-
Path(HOME) / ".headroom" / "proxy_savings.json",
|
|
34
33
|
]
|
|
35
|
-
# Raw proxy log (Simplicio-named first; engine dir
|
|
34
|
+
# Raw proxy log (Simplicio-named first; engine dir kept for back-compat).
|
|
36
35
|
LOG_CANDIDATES = [
|
|
37
36
|
Path(HOME) / ".simplicio" / "logs" / "proxy.log",
|
|
38
37
|
Path(HOME) / ".hermes" / "logs" / "simplicio-proxy.log",
|
|
39
|
-
Path(HOME) / ".headroom" / "logs" / "proxy.log",
|
|
40
|
-
Path(HOME) / ".hermes" / "logs" / "headroom.log",
|
|
41
38
|
]
|
|
42
39
|
LOGO_CANDIDATES = [
|
|
43
40
|
REPO_ROOT / "assets" / "simplicio-loop-logo.png",
|
|
@@ -45,7 +42,7 @@ LOGO_CANDIDATES = [
|
|
|
45
42
|
]
|
|
46
43
|
# Cross-platform temp dir (Windows has no /tmp) — must match simplicio_loop/cli.py PID_FILE.
|
|
47
44
|
PID_FILE = Path(tempfile.gettempdir()) / "simplicio-token-monitor.pid"
|
|
48
|
-
PROXY_PORT = os.environ.get("SIMPLICIO_PROXY_PORT",
|
|
45
|
+
PROXY_PORT = os.environ.get("SIMPLICIO_PROXY_PORT", "8788")
|
|
49
46
|
# Engine call: the native Simplicio engine module, invoked cross-platform via this interpreter.
|
|
50
47
|
ENGINE_CMD = [sys.executable or "python3", str(REPO_ROOT / "engine" / "simplicio_engine.py")]
|
|
51
48
|
|
{simplicio_loop-3.9.1 → simplicio_loop-3.11.0}/simplicio_loop/_bundle/hooks/simplicio_watch.py
RENAMED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Simplicio Token Monitor (CLI watch) — proxy + savings status for simplicio-loop.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Drives the native Simplicio capture engine (`engine/simplicio_engine.py`) — no external
|
|
5
|
+
dependency. Proxy reachability and lifetime savings come from the engine's own
|
|
6
|
+
`doctor` / `memory stats` subcommands.
|
|
6
7
|
|
|
7
8
|
Usage:
|
|
8
9
|
python3 hooks/simplicio_watch.py status # show proxy + savings status
|
|
9
10
|
python3 hooks/simplicio_watch.py start # start the compression proxy
|
|
10
11
|
python3 hooks/simplicio_watch.py stop # stop the compression proxy
|
|
11
12
|
"""
|
|
12
|
-
import json
|
|
13
13
|
import os
|
|
14
14
|
import subprocess
|
|
15
15
|
import sys
|
|
16
|
+
from pathlib import Path
|
|
16
17
|
|
|
17
18
|
HOME = os.path.expanduser("~")
|
|
18
|
-
LOGS = os.path.join(HOME, ".
|
|
19
|
+
LOGS = os.path.join(HOME, ".simplicio", "logs")
|
|
20
|
+
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
21
|
+
# Native engine: invoked cross-platform via this interpreter (no external binary).
|
|
22
|
+
ENGINE_CMD = [sys.executable or "python3", str(REPO_ROOT / "engine" / "simplicio_engine.py")]
|
|
23
|
+
PROXY_PORT = os.environ.get("SIMPLICIO_PROXY_PORT", "8788")
|
|
19
24
|
PROXY_SERVICE = "ai.simplicio.proxy"
|
|
20
25
|
|
|
21
26
|
|
|
@@ -32,34 +37,32 @@ def run(cmd, timeout=10):
|
|
|
32
37
|
|
|
33
38
|
|
|
34
39
|
def status():
|
|
35
|
-
out,
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
out, _ = run([*ENGINE_CMD, "doctor", "--port", PROXY_PORT])
|
|
41
|
+
running = "running" in out.lower() and "not reachable" not in out.lower()
|
|
42
|
+
if running:
|
|
43
|
+
log(f"✅ Simplicio proxy — RUNNING (port {PROXY_PORT})")
|
|
38
44
|
else:
|
|
39
45
|
log("❌ Simplicio proxy — NOT RUNNING")
|
|
40
|
-
|
|
46
|
+
for line in out.split("\n"):
|
|
47
|
+
if line.strip().startswith(("proxy:", "savings:")):
|
|
48
|
+
log(f" {line.strip()}")
|
|
49
|
+
out2, _ = run([*ENGINE_CMD, "memory", "stats"])
|
|
41
50
|
for line in out2.split("\n"):
|
|
42
51
|
if "Total" in line or "Database" in line:
|
|
43
52
|
log(f" {line.strip()}")
|
|
44
|
-
out3, _ = run(["headroom", "output-savings"]) # external accelerator binary
|
|
45
|
-
if "No output-savings data yet" in out3:
|
|
46
|
-
log(" 📊 Output savings: no data yet (seed with `headroom learn`)")
|
|
47
|
-
else:
|
|
48
|
-
log(f" 📊 Output savings: {out3[:80]}")
|
|
49
53
|
# Savings ledger
|
|
50
|
-
ledger =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
total = sum(1 for _ in open(ledger))
|
|
54
|
+
ledger = REPO_ROOT / ".simplicio" / "ledger" / "savings-events.jsonl"
|
|
55
|
+
if ledger.is_file():
|
|
56
|
+
total = sum(1 for _ in ledger.open(errors="replace"))
|
|
54
57
|
log(f" 💰 Savings ledger: {total} events")
|
|
55
|
-
log(f" 🪵 Logs: {LOGS}/
|
|
56
|
-
return 0 if
|
|
58
|
+
log(f" 🪵 Logs: {LOGS}/proxy.log")
|
|
59
|
+
return 0 if running else 1
|
|
57
60
|
|
|
58
61
|
|
|
59
62
|
def start():
|
|
60
|
-
log("Starting Simplicio compression proxy on port
|
|
61
|
-
log(" Use:
|
|
62
|
-
log(f"
|
|
63
|
+
log(f"Starting Simplicio compression proxy on port {PROXY_PORT}...")
|
|
64
|
+
log(f" Use: scripts/simplicio-engine proxy --port {PROXY_PORT}")
|
|
65
|
+
log(f" Or as a service: launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/{PROXY_SERVICE}.plist")
|
|
63
66
|
return 0
|
|
64
67
|
|
|
65
68
|
|