relayloom 0.3.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.
- relayloom-0.3.0/LICENSE +21 -0
- relayloom-0.3.0/PKG-INFO +101 -0
- relayloom-0.3.0/README.md +165 -0
- relayloom-0.3.0/README_PYPI.md +60 -0
- relayloom-0.3.0/pyproject.toml +55 -0
- relayloom-0.3.0/relayloom/__init__.py +3 -0
- relayloom-0.3.0/relayloom/__main__.py +39 -0
- relayloom-0.3.0/relayloom/ap/__init__.py +0 -0
- relayloom-0.3.0/relayloom/ap/__main__.py +3 -0
- relayloom-0.3.0/relayloom/ap/alerts.py +228 -0
- relayloom-0.3.0/relayloom/ap/app.py +244 -0
- relayloom-0.3.0/relayloom/ap/benchmark.py +221 -0
- relayloom-0.3.0/relayloom/ap/casefile.py +72 -0
- relayloom-0.3.0/relayloom/ap/cases.py +206 -0
- relayloom-0.3.0/relayloom/ap/crossing.py +48 -0
- relayloom-0.3.0/relayloom/ap/diagnosis.py +79 -0
- relayloom-0.3.0/relayloom/ap/gateway.py +113 -0
- relayloom-0.3.0/relayloom/ap/i18n.py +44 -0
- relayloom-0.3.0/relayloom/ap/investigator.py +236 -0
- relayloom-0.3.0/relayloom/ap/ledger.py +224 -0
- relayloom-0.3.0/relayloom/ap/lookagent.py +146 -0
- relayloom-0.3.0/relayloom/ap/masking.py +32 -0
- relayloom-0.3.0/relayloom/ap/matcher.py +57 -0
- relayloom-0.3.0/relayloom/ap/models.py +235 -0
- relayloom-0.3.0/relayloom/ap/phone_page.py +82 -0
- relayloom-0.3.0/relayloom/ap/pipeline.py +537 -0
- relayloom-0.3.0/relayloom/ap/policy.json +75 -0
- relayloom-0.3.0/relayloom/ap/policy.py +66 -0
- relayloom-0.3.0/relayloom/ap/portal.py +121 -0
- relayloom-0.3.0/relayloom/ap/py.typed +0 -0
- relayloom-0.3.0/relayloom/ap/receipts.py +159 -0
- relayloom-0.3.0/relayloom/ap/receiving.py +92 -0
- relayloom-0.3.0/relayloom/ap/sam_worker.py +85 -0
- relayloom-0.3.0/relayloom/ap/schema.py +83 -0
- relayloom-0.3.0/relayloom/ap/track_worker.py +62 -0
- relayloom-0.3.0/relayloom/ap/video.py +158 -0
- relayloom-0.3.0/relayloom/cli.py +447 -0
- relayloom-0.3.0/relayloom/controller.py +493 -0
- relayloom-0.3.0/relayloom/meta.py +209 -0
- relayloom-0.3.0/relayloom/policy.json +37 -0
- relayloom-0.3.0/relayloom/py.typed +0 -0
- relayloom-0.3.0/relayloom/server.py +190 -0
- relayloom-0.3.0/relayloom.egg-info/PKG-INFO +101 -0
- relayloom-0.3.0/relayloom.egg-info/SOURCES.txt +61 -0
- relayloom-0.3.0/relayloom.egg-info/dependency_links.txt +1 -0
- relayloom-0.3.0/relayloom.egg-info/entry_points.txt +2 -0
- relayloom-0.3.0/relayloom.egg-info/requires.txt +12 -0
- relayloom-0.3.0/relayloom.egg-info/top_level.txt +1 -0
- relayloom-0.3.0/setup.cfg +4 -0
- relayloom-0.3.0/tests/test_alerts.py +163 -0
- relayloom-0.3.0/tests/test_ap.py +414 -0
- relayloom-0.3.0/tests/test_autonomy.py +162 -0
- relayloom-0.3.0/tests/test_cli.py +110 -0
- relayloom-0.3.0/tests/test_controller.py +291 -0
- relayloom-0.3.0/tests/test_crossing.py +36 -0
- relayloom-0.3.0/tests/test_gateway.py +108 -0
- relayloom-0.3.0/tests/test_languages.py +101 -0
- relayloom-0.3.0/tests/test_lookagent.py +114 -0
- relayloom-0.3.0/tests/test_meta.py +203 -0
- relayloom-0.3.0/tests/test_meta_checks.py +121 -0
- relayloom-0.3.0/tests/test_persistent_sam.py +57 -0
- relayloom-0.3.0/tests/test_scenarios.py +24 -0
- relayloom-0.3.0/tests/test_video.py +95 -0
relayloom-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sriharsan B S
|
|
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.
|
relayloom-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: relayloom
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Pay for what arrived. Prove it. Accounts payable that counts the goods with open weight Meta models (Muse Glimmer, SAM 3.1) on your own machine.
|
|
5
|
+
Author: Sriharsan B S
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://relayloom.vercel.app
|
|
8
|
+
Project-URL: Documentation, https://relayloom.vercel.app/developers
|
|
9
|
+
Project-URL: Source, https://github.com/Sriharsan/relayloom
|
|
10
|
+
Project-URL: Issues, https://github.com/Sriharsan/relayloom/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/Sriharsan/relayloom/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: accounts payable,three-way match,invoice,receiving,SAM 3.1,Muse Glimmer,signed receipts,offline,local-first
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Operating System :: MacOS
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Office/Business :: Financial :: Accounting
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.11
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: cryptography>=44
|
|
31
|
+
Requires-Dist: PyMuPDF>=1.26
|
|
32
|
+
Requires-Dist: opencv-python-headless>=4.10
|
|
33
|
+
Requires-Dist: numpy>=1.26
|
|
34
|
+
Requires-Dist: Pillow>=10
|
|
35
|
+
Provides-Extra: models
|
|
36
|
+
Requires-Dist: ultralytics>=8.3; extra == "models"
|
|
37
|
+
Requires-Dist: huggingface_hub>=0.26; extra == "models"
|
|
38
|
+
Provides-Extra: qr
|
|
39
|
+
Requires-Dist: segno>=1.6; extra == "qr"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# Relayloom
|
|
43
|
+
|
|
44
|
+
**Pay for what arrived. Prove it.**
|
|
45
|
+
|
|
46
|
+
Relayloom matches a supplier bill with the purchase order and with what was actually counted on the dock, holds any payment the goods do not support, and writes **signed receipts** you can verify with the network off. Muse Glimmer and SAM 3.1, open weight Meta models, run on your own machine.
|
|
47
|
+
|
|
48
|
+
The paperwork says 50. The dock got 46. `relayloom check` says HELD, and says why.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
python -m pip install relayloom
|
|
52
|
+
relayloom doctor
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Try it in a minute, no models needed
|
|
56
|
+
|
|
57
|
+
`bill.json` (what the bill says), `po.json` (what was ordered), and a count of what arrived:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
relayloom check --bill-json bill.json --po po.json --counted 46
|
|
61
|
+
relayloom verify relayloom-out/receipts.jsonl
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Bill CAL-0990: billed 50, counted 46. Result: HELD
|
|
66
|
+
- CARTON-HD: billed 50 with 0 already billed, received 46
|
|
67
|
+
Signed receipts: relayloom-out/receipts.jsonl Verify: relayloom verify relayloom-out/receipts.jsonl
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Exit code `0` means clear to enter, `3` means held, `2` means it could not run. Add `--json` for scripts.
|
|
71
|
+
|
|
72
|
+
## Count the goods from photos
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
python -m pip install "relayloom[models]"
|
|
76
|
+
python -m pip install git+https://github.com/ultralytics/CLIP.git # text prompts for SAM 3.1 (a Git-only dependency, so it is not bundled)
|
|
77
|
+
export HF_TOKEN=... # your own Hugging Face read token (SAM 3.1 needs the access request)
|
|
78
|
+
relayloom models pull # one time; after this everything runs offline
|
|
79
|
+
relayloom models serve # Muse Glimmer on 127.0.0.1, in another terminal
|
|
80
|
+
relayloom check --bill bill.pdf --photos dock/ --po po.json --agent
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
With `--agent`, Muse Glimmer proposes the words to look for, calls SAM 3.1 as a tool, and looks at the numbered overlay itself. **Code owns the number**: it is only ever the masks SAM returned, and a count is accepted only when two different words agree, or when Glimmer has looked at the overlay and no other count contradicts it. Otherwise the bill is held for a person.
|
|
84
|
+
|
|
85
|
+
## What it does not do
|
|
86
|
+
|
|
87
|
+
- It does not send a bill, a photo or a number anywhere. `relayloom doctor` and `verify` make no network calls at all.
|
|
88
|
+
- It does not pay anything. It decides, with evidence, and a person approves what the policy says needs approval.
|
|
89
|
+
- It does not claim real time on a CPU. Counting a photo takes about 40 seconds and reading a bill several minutes on a laptop CPU; measured timings are on the [Proof page](https://relayloom.vercel.app/proof).
|
|
90
|
+
|
|
91
|
+
## Commands
|
|
92
|
+
|
|
93
|
+
| Command | What it does |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| `relayloom check` | match a bill, a purchase order and the goods; write signed receipts |
|
|
96
|
+
| `relayloom verify RECEIPTS` | check signatures, hashes and chain order offline |
|
|
97
|
+
| `relayloom doctor` | say what is ready and the one command that fixes what is not |
|
|
98
|
+
| `relayloom models pull` / `serve` | download the models with your own token / start Muse Glimmer locally |
|
|
99
|
+
| `relayloom serve` | the demo app and phone alerts (needs a clone of the repository) |
|
|
100
|
+
|
|
101
|
+
Docs, the policy file and the receipt format: https://relayloom.vercel.app/developers. Source and threat model: https://github.com/Sriharsan/relayloom. MIT licensed.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Relayloom
|
|
2
|
+
|
|
3
|
+
**Relayloom: autonomous accounts payable that checks the goods, not just the paperwork.**
|
|
4
|
+
|
|
5
|
+
Agents read the bill, look at what actually arrived, investigate any gap with evidence, and pay only what
|
|
6
|
+
the books and the goods both support. Runs inside the company's own network on Meta open weight models.
|
|
7
|
+
|
|
8
|
+
The paperwork says 50. The dock got 46. Relayloom is for the receiving and accounts payable team of a
|
|
9
|
+
manufacturer or distributor that buys physical goods. The example company in this repository is
|
|
10
|
+
Northgate Components, with fictional suppliers and demo records only.
|
|
11
|
+
|
|
12
|
+
**Live site and proof:** https://relayloom.vercel.app. On a demo set of 30 deliveries built by us, paperwork only caught
|
|
13
|
+
5 of 17 bad bills and paperwork plus goods caught 17 of 17 with no wrong payment ([docs/BENCHMARK.md](docs/BENCHMARK.md)).
|
|
14
|
+
|
|
15
|
+
## Install the command line
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
python -m pip install git+https://github.com/Sriharsan/relayloom.git # a PyPI release of the same package follows
|
|
19
|
+
relayloom doctor # what is ready on this machine, and the command that fixes the rest
|
|
20
|
+
relayloom check --bill-json bill.json --po po.json --counted 46 # no models needed: HELD or clear, with signed receipts
|
|
21
|
+
relayloom check --bill bill.pdf --photos dock/ --po po.json --agent # Muse Glimmer proposes the words, SAM 3.1 counts, Glimmer looks at the overlay
|
|
22
|
+
relayloom verify relayloom-out/receipts.jsonl # verify the receipts offline
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pip install -r requirements-ap.txt
|
|
27
|
+
python -m pytest -q # 127 tests
|
|
28
|
+
python -m relayloom.ap.benchmark --counter recorded # the benchmark on saved SAM 3.1 counts, a few seconds
|
|
29
|
+
python scripts/export_bench_run.py out.json # the seven cases on the real agents, with signed receipts
|
|
30
|
+
python -m relayloom.ap --batch # the app on http://127.0.0.1:8800 (replays the saved readings)
|
|
31
|
+
python -m relayloom.ap --batch --phone # also prints a link for alerts on a phone on the same Wi-Fi
|
|
32
|
+
python scripts/security_report.py # runs and times every security control
|
|
33
|
+
python scripts/record_demo_video.py # records the captioned picture of the live site to speak over
|
|
34
|
+
python scripts/add_voice.py my-voice.m4a # puts your own voice on that picture and checks the three minute limit
|
|
35
|
+
python scripts/video_demo.py # a dock clip becomes a held delivery, from saved frames and counts
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Recorded mode replays outputs from real runs on one laptop with their date, route and timings on screen, and uses a small
|
|
39
|
+
built in ledger. `--live` runs the models on your own machine and uses ERPNext (see below).
|
|
40
|
+
|
|
41
|
+
## What it does
|
|
42
|
+
|
|
43
|
+
1. **Reads the bill.** Muse Glimmer 30B turns a bill into a strict schema. Private numbers (GSTIN, bank account,
|
|
44
|
+
IFSC, phone, email) are masked first. Text hidden in the PDF is found and never reaches the model.
|
|
45
|
+
2. **Looks at what arrived.** SAM 3.1 counts the goods in every photo of every delivery. Repeated photos are counted once.
|
|
46
|
+
A purchase order can have several receiving events, and they add up as a running total.
|
|
47
|
+
3. **Matches.** Code compares order, bill and goods received, with tolerances from a policy file the model cannot change.
|
|
48
|
+
4. **Investigates every mismatch before a person sees it.** The Investigator recounts from every photo, adds up all deliveries
|
|
49
|
+
on the order, checks the order price and the last price paid, looks for a duplicate bill, and checks the supplier's
|
|
50
|
+
past shortfalls. Every statement in its finding cites a record, a photo or a recount, and code checks every citation
|
|
51
|
+
and every number before the finding is shown. It then names the likely cause (short delivery, price above the order, duplicate bill,
|
|
52
|
+
or the two counts disagree, or unclear), how sure the records let it be, and what to do next, and it proposes an action. The policy decides.
|
|
53
|
+
5. **Enters and checks.** A matching bill is entered by the Clerk, and a separate Checker reads it back and compares every
|
|
54
|
+
field. Only then does the case say "entered and checked". Payment details only ever come from the supplier master.
|
|
55
|
+
6. **Waits for the owner where it matters.** Disputes, mismatches, bills above the owner's limit and new suppliers wait in
|
|
56
|
+
the approval inbox. Muse Glimmer drafts the dispute and a browser agent files it in a local supplier portal.
|
|
57
|
+
7. **Keeps a file.** When a case ends, the Archivist writes a case file (cause, reasons, decision, the supplier's record) and puts its hash in
|
|
58
|
+
the receipts. Later investigations of that supplier read the supplier file.
|
|
59
|
+
8. **Proves it.** Every step writes a signed receipt, chained per case, that anyone can verify offline. The audit trail is tamper-evident:
|
|
60
|
+
change any recorded decision and the chain breaks at that step.
|
|
61
|
+
|
|
62
|
+
## Autonomy
|
|
63
|
+
|
|
64
|
+
Levels live in [`relayloom/ap/policy.json`](relayloom/ap/policy.json), read once at start. Bills, photos, model output
|
|
65
|
+
and requests cannot change them.
|
|
66
|
+
|
|
67
|
+
- **Runs alone:** read bills, count goods, match, investigate mismatches, enter matching bills, check the readback, reconcile after reconnect.
|
|
68
|
+
- **Waits for the owner:** any mismatch, any bill above the owner's amount limit, sending a dispute, a new supplier or changed bank details.
|
|
69
|
+
- **Never:** change bank details from invoice text, enter a bill whose readback failed, change the books while offline.
|
|
70
|
+
|
|
71
|
+
## What is real and what is labelled
|
|
72
|
+
|
|
73
|
+
| Part | Status |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| Muse Glimmer 30B reading bills and writing disputes | Real runs on a laptop CPU: 9 Northgate bill readings, all valid, 4 min 33 s to 8 min 51 s each, and 2 dispute drafts, plus 7 readings on the first bill set ([docs/RESULTS.md](docs/RESULTS.md)). Findings in recorded mode are written by code from the evidence. |
|
|
76
|
+
| SAM 3.1 counting photos | Real runs on the same CPU, 115 saved in `fixtures/recorded/sam` with the numbered overlays. 101 of the 102 counts the system uses match the delivery record. |
|
|
77
|
+
| ERPNext ledger | Real, in Docker on localhost. A built in ledger with the same calls is used in recorded mode. Each run says which ran. |
|
|
78
|
+
| Benchmark | Demo set built by us, real SAM 3.1 counts. See [docs/BENCHMARK.md](docs/BENCHMARK.md). In it the bills come from the generator and the findings are written by code. |
|
|
79
|
+
| Network boundary | **Tested in Docker on 3 November 2026, all checks pass** ([docs/boundary-result.json](docs/boundary-result.json)): the agents run on a network with no route out, direct connections fail, the gateway refuses hosts that are not in the policy and logs each refusal, and all seven cases pass inside. Verification with the laptop itself switched offline is one command, `python scripts/offline_check.py`, which writes a dated report. |
|
|
80
|
+
| Phone alerts | Built: `python -m relayloom.ap --phone`. A separate read only page on your local network, behind a random token, no internet. Covered by unit tests and verified end to end in a phone sized browser. |
|
|
81
|
+
| Security controls | 11 of 11 pass their checks and add about 30 ms to a case ([docs/SECURITY_CHECKS.md](docs/SECURITY_CHECKS.md)). |
|
|
82
|
+
| Video evidence | Built: `python scripts/dock_watch.py clip.mp4` (or a camera number or stream address). A delivery is detected 0.25 s after the first movement at 0.35 ms of compute per frame, the steady views become photographs, and SAM 3.1 counts them. Verified on a recorded demo clip (28 and 18 counted, 46 of 50 billed). The clip is demo. |
|
|
83
|
+
| Real photos | Builder-provided test photos, a mix of free-licence stock and the builder's own, not a claim about real deliveries. 18 photos counted by SAM 3.1 with two words each, 8 with hand counts: at the old setting the total error was 33 items and at 0.5 it was 12 ([docs/REAL_GOODS.md](docs/REAL_GOODS.md), [docs/CONFIDENCE.md](docs/CONFIDENCE.md)). The default confidence is 0.5 because of this. |
|
|
84
|
+
| Real orders | 85 real purchase orders from the State of California open data, 369 cases with the exception types published accounts payable sources describe, all pass ([docs/REAL_WORLD_CHECK.md](docs/REAL_WORLD_CHECK.md)). Running it found and fixed real problems: quantities above 100,000, fractional counts, multi-line orders, unit of measure differences, concurrent receipt writes. |
|
|
85
|
+
| Package | `relayloom` 0.3.0 builds, passes the PyPI check, and installs and runs in a clean environment with the network blocked, 18 of 18 steps ([docs/PACKAGE_CHECK.md](docs/PACKAGE_CHECK.md)), plus 44 command line scenarios ([docs/PACKAGE_SCENARIOS.md](docs/PACKAGE_SCENARIOS.md)). Not yet published to PyPI. |
|
|
86
|
+
| Languages | Phone alerts and the approval screen in English, Tamil and Hindi, 135 strings, every one listed for a native check in [docs/LANGUAGES.md](docs/LANGUAGES.md). A Hindi and a Tamil bill were read by Muse Glimmer with every field correct ([docs/LANGUAGE_BILL_RESULT.md](docs/LANGUAGE_BILL_RESULT.md)). |
|
|
87
|
+
| Real cases | Eleven documented cases from courts, audits and news, each read at its source, not Relayloom users ([docs/SOURCES.md](docs/SOURCES.md)). |
|
|
88
|
+
| Sensors | Out of scope. Nothing is simulated. |
|
|
89
|
+
|
|
90
|
+
Timings on the screen are real. On this laptop Muse Glimmer needs several minutes per bill and SAM 3.1 about a minute
|
|
91
|
+
per photo. That is why the app runs bills as a background batch.
|
|
92
|
+
|
|
93
|
+
## Run the cases
|
|
94
|
+
|
|
95
|
+
Each case is one command that prints PASS or FAIL per check and says which models and which ledger ran. They read bills from
|
|
96
|
+
the saved Muse Glimmer readings and count from the saved SAM 3.1 runs, so all seven pass from a clean clone in seconds.
|
|
97
|
+
`python scripts/export_bench_run.py out.json` runs them with signed receipts. To record fresh readings, run
|
|
98
|
+
`python scripts/record_glimmer.py` (about 1 hour on a laptop CPU).
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
python -m relayloom.ap.cases match # a matching delivery, entered and checked, no person involved
|
|
102
|
+
python -m relayloom.ap.cases short # paperwork says 50, the dock got 46: investigation, approval, dispute
|
|
103
|
+
python -m relayloom.ap.cases price # rate above the order
|
|
104
|
+
python -m relayloom.ap.cases injection # hidden text asking to change the bank account
|
|
105
|
+
python -m relayloom.ap.cases netcut # network cut mid batch, reconnect, no duplicate
|
|
106
|
+
python -m relayloom.ap.cases duplicate # same goods billed again under a new number
|
|
107
|
+
python -m relayloom.ap.cases split # one order, two deliveries, one bill
|
|
108
|
+
python -m relayloom.ap.benchmark # the benchmark on the demo set
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Add `--live` to run Muse Glimmer and SAM 3.1 on your machine and the ledger in ERPNext.
|
|
112
|
+
|
|
113
|
+
## Running it live
|
|
114
|
+
|
|
115
|
+
1. **Muse Glimmer:** download `Muse-Glimmer-30B-KQuant-17GB-Q4_K_M.gguf` from `meta-models/Muse-Glimmer-30B-GGUF` and serve it with
|
|
116
|
+
llama.cpp b10353 or newer (`llama-server --jinja`). Put its address in `.env` as `GLIMMER_URL`.
|
|
117
|
+
2. **SAM 3.1:** the weights are gated on Hugging Face. Request access, put a read token in `.env` as `HF_TOKEN`, and run
|
|
118
|
+
`python scripts/record_sam.py`. It needs Ultralytics 8.4 or newer in the Python named by `RELAYLOOM_SAM_PYTHON`.
|
|
119
|
+
3. **ERPNext:** `docker compose -f pwd.yml up -d` from `frappe/frappe_docker`, then `python scripts/setup_erpnext.py`.
|
|
120
|
+
It replaces the default password, creates an API user and seeds the demo records.
|
|
121
|
+
|
|
122
|
+
Keys live only in `.env`, which git ignores. The paid Meta Model API adapter in `relayloom/meta.py` is kept and stays off.
|
|
123
|
+
|
|
124
|
+
## Tests
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
python -m pytest -q # 127 Python tests
|
|
128
|
+
node --test tests/ui.test.cjs tests/verify.test.cjs # 14 Node tests
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The site is built from `site-src` (`npm install`, `npm run data`, `npm run build`) into `site/`.
|
|
132
|
+
|
|
133
|
+
## Repository map
|
|
134
|
+
|
|
135
|
+
| Where | What |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| `relayloom/ap/` | The product: policy, masking, schema, matcher, Investigator, ledger, receipts, gateway, agents. |
|
|
138
|
+
| `fixtures/` | Demo bills, delivery photos and the benchmark set, plus `fixtures/recorded/` with real SAM 3.1 and Muse Glimmer outputs. |
|
|
139
|
+
| `docs/RESULTS.md`, `docs/BENCHMARK.md` | The evidence: timings, counts, the seven cases and the benchmark. |
|
|
140
|
+
| `site-src/` and `site/` | The website: source and the built version served on Vercel. |
|
|
141
|
+
| `scripts/` | Recording, exporting, fixtures and the boundary probe. |
|
|
142
|
+
| `deploy/` | The Docker network with no route out. |
|
|
143
|
+
| `relayloom/` (controller, server) and `web/` | The first workroom from 28 to 30 October. The accounts payable system reuses its approval, limit and receipt ideas. |
|
|
144
|
+
|
|
145
|
+
Built on Meta open weights and the official open-weight cookbook: the Reader uses the structured output and reasoning
|
|
146
|
+
effort recipes for Muse Glimmer ([sources](docs/SOURCES.md)). Theme: Push the Frontier.
|
|
147
|
+
|
|
148
|
+
## Hackathon
|
|
149
|
+
|
|
150
|
+
Meta Global AI Developer Hackathon, Startups track. The building period is 27 October to 4 November 2026 (ET).
|
|
151
|
+
Everything in this repository was built inside it; see [docs/HACKATHON_UPDATES.md](docs/HACKATHON_UPDATES.md) for each
|
|
152
|
+
commit and what it added. The shared revision workroom from 28 to 30 October is still here (`python -m relayloom`); the
|
|
153
|
+
accounts payable system is built on its approval, limit and receipt ideas.
|
|
154
|
+
|
|
155
|
+
## Read more
|
|
156
|
+
|
|
157
|
+
- [Benchmark](docs/BENCHMARK.md) · [Results from our own runs](docs/RESULTS.md) · [Sources](docs/SOURCES.md) · [Submission text](docs/SUBMISSION_FORM_TEXT.md)
|
|
158
|
+
- [Hackathon updates by commit](docs/HACKATHON_UPDATES.md) · [Submission notes](SUBMISSION_META.md) · [Video script](docs/VIDEO_SCRIPT.md)
|
|
159
|
+
- [Submission checklist](docs/SUBMIT_CHECKLIST.md) · [X post](docs/X_POST.md) · [Autonomy](docs/AUTONOMY.md) · [Product and architecture](docs/PRODUCT.md) · [Security](SECURITY.md)
|
|
160
|
+
|
|
161
|
+
Use demo information only. This is a loopback app, not a hosting service; do not expose its port.
|
|
162
|
+
|
|
163
|
+
## License and authorship
|
|
164
|
+
|
|
165
|
+
MIT. Original work by Sriharsan B S. No customers, pilots, revenue or funding are claimed.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Relayloom
|
|
2
|
+
|
|
3
|
+
**Pay for what arrived. Prove it.**
|
|
4
|
+
|
|
5
|
+
Relayloom matches a supplier bill with the purchase order and with what was actually counted on the dock, holds any payment the goods do not support, and writes **signed receipts** you can verify with the network off. Muse Glimmer and SAM 3.1, open weight Meta models, run on your own machine.
|
|
6
|
+
|
|
7
|
+
The paperwork says 50. The dock got 46. `relayloom check` says HELD, and says why.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
python -m pip install relayloom
|
|
11
|
+
relayloom doctor
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Try it in a minute, no models needed
|
|
15
|
+
|
|
16
|
+
`bill.json` (what the bill says), `po.json` (what was ordered), and a count of what arrived:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
relayloom check --bill-json bill.json --po po.json --counted 46
|
|
20
|
+
relayloom verify relayloom-out/receipts.jsonl
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
Bill CAL-0990: billed 50, counted 46. Result: HELD
|
|
25
|
+
- CARTON-HD: billed 50 with 0 already billed, received 46
|
|
26
|
+
Signed receipts: relayloom-out/receipts.jsonl Verify: relayloom verify relayloom-out/receipts.jsonl
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Exit code `0` means clear to enter, `3` means held, `2` means it could not run. Add `--json` for scripts.
|
|
30
|
+
|
|
31
|
+
## Count the goods from photos
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python -m pip install "relayloom[models]"
|
|
35
|
+
python -m pip install git+https://github.com/ultralytics/CLIP.git # text prompts for SAM 3.1 (a Git-only dependency, so it is not bundled)
|
|
36
|
+
export HF_TOKEN=... # your own Hugging Face read token (SAM 3.1 needs the access request)
|
|
37
|
+
relayloom models pull # one time; after this everything runs offline
|
|
38
|
+
relayloom models serve # Muse Glimmer on 127.0.0.1, in another terminal
|
|
39
|
+
relayloom check --bill bill.pdf --photos dock/ --po po.json --agent
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
With `--agent`, Muse Glimmer proposes the words to look for, calls SAM 3.1 as a tool, and looks at the numbered overlay itself. **Code owns the number**: it is only ever the masks SAM returned, and a count is accepted only when two different words agree, or when Glimmer has looked at the overlay and no other count contradicts it. Otherwise the bill is held for a person.
|
|
43
|
+
|
|
44
|
+
## What it does not do
|
|
45
|
+
|
|
46
|
+
- It does not send a bill, a photo or a number anywhere. `relayloom doctor` and `verify` make no network calls at all.
|
|
47
|
+
- It does not pay anything. It decides, with evidence, and a person approves what the policy says needs approval.
|
|
48
|
+
- It does not claim real time on a CPU. Counting a photo takes about 40 seconds and reading a bill several minutes on a laptop CPU; measured timings are on the [Proof page](https://relayloom.vercel.app/proof).
|
|
49
|
+
|
|
50
|
+
## Commands
|
|
51
|
+
|
|
52
|
+
| Command | What it does |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `relayloom check` | match a bill, a purchase order and the goods; write signed receipts |
|
|
55
|
+
| `relayloom verify RECEIPTS` | check signatures, hashes and chain order offline |
|
|
56
|
+
| `relayloom doctor` | say what is ready and the one command that fixes what is not |
|
|
57
|
+
| `relayloom models pull` / `serve` | download the models with your own token / start Muse Glimmer locally |
|
|
58
|
+
| `relayloom serve` | the demo app and phone alerts (needs a clone of the repository) |
|
|
59
|
+
|
|
60
|
+
Docs, the policy file and the receipt format: https://relayloom.vercel.app/developers. Source and threat model: https://github.com/Sriharsan/relayloom. MIT licensed.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "relayloom"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Pay for what arrived. Prove it. Accounts payable that counts the goods with open weight Meta models (Muse Glimmer, SAM 3.1) on your own machine."
|
|
9
|
+
readme = "README_PYPI.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Sriharsan B S" }]
|
|
14
|
+
keywords = ["accounts payable", "three-way match", "invoice", "receiving", "SAM 3.1", "Muse Glimmer", "signed receipts", "offline", "local-first"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
20
|
+
"Operating System :: Microsoft :: Windows",
|
|
21
|
+
"Operating System :: MacOS",
|
|
22
|
+
"Operating System :: POSIX :: Linux",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Topic :: Office/Business :: Financial :: Accounting",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Image Recognition",
|
|
29
|
+
"Typing :: Typed",
|
|
30
|
+
]
|
|
31
|
+
dependencies = ["cryptography>=44", "PyMuPDF>=1.26", "opencv-python-headless>=4.10", "numpy>=1.26", "Pillow>=10"]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
models = ["ultralytics>=8.3", "huggingface_hub>=0.26"]
|
|
35
|
+
qr = ["segno>=1.6"]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
relayloom = "relayloom.cli:main"
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://relayloom.vercel.app"
|
|
42
|
+
Documentation = "https://relayloom.vercel.app/developers"
|
|
43
|
+
Source = "https://github.com/Sriharsan/relayloom"
|
|
44
|
+
Issues = "https://github.com/Sriharsan/relayloom/issues"
|
|
45
|
+
Changelog = "https://github.com/Sriharsan/relayloom/blob/main/CHANGELOG.md"
|
|
46
|
+
|
|
47
|
+
[tool.setuptools]
|
|
48
|
+
packages = ["relayloom", "relayloom.ap"]
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.dynamic]
|
|
51
|
+
version = { attr = "relayloom.__version__" }
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.package-data]
|
|
54
|
+
relayloom = ["policy.json", "py.typed"]
|
|
55
|
+
"relayloom.ap" = ["policy.json", "py.typed"]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Start Relayloom. Rehearsal is the default; Meta requires explicit opt-in."""
|
|
2
|
+
import argparse
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .controller import Controller
|
|
6
|
+
from .server import LocalServer
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
11
|
+
parser.add_argument("--port", type=int, default=8800)
|
|
12
|
+
parser.add_argument("--database", type=Path, default=Path("data/relayloom.sqlite3"))
|
|
13
|
+
parser.add_argument("--enable-meta-synthetic", action="store_true", help="Allow billable Meta calls only after explicit environment configuration; synthetic fixture only")
|
|
14
|
+
args = parser.parse_args()
|
|
15
|
+
if not 1 <= args.port <= 65535:
|
|
16
|
+
parser.error("port must be between 1 and 65535")
|
|
17
|
+
if args.enable_meta_synthetic:
|
|
18
|
+
from .meta import MetaWorker
|
|
19
|
+
try:
|
|
20
|
+
worker = MetaWorker.from_environment()
|
|
21
|
+
except (ValueError, OSError) as error:
|
|
22
|
+
parser.error(str(error))
|
|
23
|
+
controller = Controller(args.database, worker=worker)
|
|
24
|
+
else:
|
|
25
|
+
controller = Controller(args.database)
|
|
26
|
+
server = LocalServer(("127.0.0.1", args.port), controller)
|
|
27
|
+
print(f"Relayloom {controller.mode} mode: http://127.0.0.1:{args.port}")
|
|
28
|
+
print("Synthetic specialist outputs. No live inference or external actions." if controller.mode == "rehearsal" else "Meta enabled for the bundled fictional fixture. Run specialists may consume credits. No external actions.")
|
|
29
|
+
try:
|
|
30
|
+
server.serve_forever()
|
|
31
|
+
except KeyboardInterrupt:
|
|
32
|
+
pass
|
|
33
|
+
finally:
|
|
34
|
+
server.server_close()
|
|
35
|
+
controller.close()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
main()
|
|
File without changes
|