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.
Files changed (63) hide show
  1. relayloom-0.3.0/LICENSE +21 -0
  2. relayloom-0.3.0/PKG-INFO +101 -0
  3. relayloom-0.3.0/README.md +165 -0
  4. relayloom-0.3.0/README_PYPI.md +60 -0
  5. relayloom-0.3.0/pyproject.toml +55 -0
  6. relayloom-0.3.0/relayloom/__init__.py +3 -0
  7. relayloom-0.3.0/relayloom/__main__.py +39 -0
  8. relayloom-0.3.0/relayloom/ap/__init__.py +0 -0
  9. relayloom-0.3.0/relayloom/ap/__main__.py +3 -0
  10. relayloom-0.3.0/relayloom/ap/alerts.py +228 -0
  11. relayloom-0.3.0/relayloom/ap/app.py +244 -0
  12. relayloom-0.3.0/relayloom/ap/benchmark.py +221 -0
  13. relayloom-0.3.0/relayloom/ap/casefile.py +72 -0
  14. relayloom-0.3.0/relayloom/ap/cases.py +206 -0
  15. relayloom-0.3.0/relayloom/ap/crossing.py +48 -0
  16. relayloom-0.3.0/relayloom/ap/diagnosis.py +79 -0
  17. relayloom-0.3.0/relayloom/ap/gateway.py +113 -0
  18. relayloom-0.3.0/relayloom/ap/i18n.py +44 -0
  19. relayloom-0.3.0/relayloom/ap/investigator.py +236 -0
  20. relayloom-0.3.0/relayloom/ap/ledger.py +224 -0
  21. relayloom-0.3.0/relayloom/ap/lookagent.py +146 -0
  22. relayloom-0.3.0/relayloom/ap/masking.py +32 -0
  23. relayloom-0.3.0/relayloom/ap/matcher.py +57 -0
  24. relayloom-0.3.0/relayloom/ap/models.py +235 -0
  25. relayloom-0.3.0/relayloom/ap/phone_page.py +82 -0
  26. relayloom-0.3.0/relayloom/ap/pipeline.py +537 -0
  27. relayloom-0.3.0/relayloom/ap/policy.json +75 -0
  28. relayloom-0.3.0/relayloom/ap/policy.py +66 -0
  29. relayloom-0.3.0/relayloom/ap/portal.py +121 -0
  30. relayloom-0.3.0/relayloom/ap/py.typed +0 -0
  31. relayloom-0.3.0/relayloom/ap/receipts.py +159 -0
  32. relayloom-0.3.0/relayloom/ap/receiving.py +92 -0
  33. relayloom-0.3.0/relayloom/ap/sam_worker.py +85 -0
  34. relayloom-0.3.0/relayloom/ap/schema.py +83 -0
  35. relayloom-0.3.0/relayloom/ap/track_worker.py +62 -0
  36. relayloom-0.3.0/relayloom/ap/video.py +158 -0
  37. relayloom-0.3.0/relayloom/cli.py +447 -0
  38. relayloom-0.3.0/relayloom/controller.py +493 -0
  39. relayloom-0.3.0/relayloom/meta.py +209 -0
  40. relayloom-0.3.0/relayloom/policy.json +37 -0
  41. relayloom-0.3.0/relayloom/py.typed +0 -0
  42. relayloom-0.3.0/relayloom/server.py +190 -0
  43. relayloom-0.3.0/relayloom.egg-info/PKG-INFO +101 -0
  44. relayloom-0.3.0/relayloom.egg-info/SOURCES.txt +61 -0
  45. relayloom-0.3.0/relayloom.egg-info/dependency_links.txt +1 -0
  46. relayloom-0.3.0/relayloom.egg-info/entry_points.txt +2 -0
  47. relayloom-0.3.0/relayloom.egg-info/requires.txt +12 -0
  48. relayloom-0.3.0/relayloom.egg-info/top_level.txt +1 -0
  49. relayloom-0.3.0/setup.cfg +4 -0
  50. relayloom-0.3.0/tests/test_alerts.py +163 -0
  51. relayloom-0.3.0/tests/test_ap.py +414 -0
  52. relayloom-0.3.0/tests/test_autonomy.py +162 -0
  53. relayloom-0.3.0/tests/test_cli.py +110 -0
  54. relayloom-0.3.0/tests/test_controller.py +291 -0
  55. relayloom-0.3.0/tests/test_crossing.py +36 -0
  56. relayloom-0.3.0/tests/test_gateway.py +108 -0
  57. relayloom-0.3.0/tests/test_languages.py +101 -0
  58. relayloom-0.3.0/tests/test_lookagent.py +114 -0
  59. relayloom-0.3.0/tests/test_meta.py +203 -0
  60. relayloom-0.3.0/tests/test_meta_checks.py +121 -0
  61. relayloom-0.3.0/tests/test_persistent_sam.py +57 -0
  62. relayloom-0.3.0/tests/test_scenarios.py +24 -0
  63. relayloom-0.3.0/tests/test_video.py +95 -0
@@ -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.
@@ -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,3 @@
1
+ """Relayloom: accounts payable that checks the goods, not just the paperwork."""
2
+
3
+ __version__ = "0.3.0"
@@ -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
@@ -0,0 +1,3 @@
1
+ from .app import main
2
+
3
+ main()