quorum-ai 0.1.5__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.
- quorum_ai-0.1.5/.dockerignore +91 -0
- quorum_ai-0.1.5/.dockerignore.bak3 +93 -0
- quorum_ai-0.1.5/.env.example +21 -0
- quorum_ai-0.1.5/.firebase/hosting.bGFuZGluZw.cache +4 -0
- quorum_ai-0.1.5/.gitignore +16 -0
- quorum_ai-0.1.5/CHANGELOG.md +78 -0
- quorum_ai-0.1.5/Dockerfile +100 -0
- quorum_ai-0.1.5/Dockerfile.bak +97 -0
- quorum_ai-0.1.5/Dockerfile.bak2 +96 -0
- quorum_ai-0.1.5/Dockerfile.bak4 +97 -0
- quorum_ai-0.1.5/PKG-INFO +257 -0
- quorum_ai-0.1.5/README.md +203 -0
- quorum_ai-0.1.5/complex_test.py +26 -0
- quorum_ai-0.1.5/deploy/cloudrun.yaml +141 -0
- quorum_ai-0.1.5/docs/AUDIT_FINDINGS_v0.1.2.md +239 -0
- quorum_ai-0.1.5/docs/AUDIT_FINDINGS_v0.1.4.md +73 -0
- quorum_ai-0.1.5/docs/AUDIT_FINDINGS_v0.1.5.md +89 -0
- quorum_ai-0.1.5/docs/CONTEXT_PROFILES.md +121 -0
- quorum_ai-0.1.5/docs/POSTMORTEM_v0.1.0_deploy.md +100 -0
- quorum_ai-0.1.5/docs/SELF_EVAL_2026-06-17.json +242 -0
- quorum_ai-0.1.5/landing/README.md +112 -0
- quorum_ai-0.1.5/landing/index.html +303 -0
- quorum_ai-0.1.5/landing/node.png +0 -0
- quorum_ai-0.1.5/landing/risk.png +0 -0
- quorum_ai-0.1.5/pyproject.toml +68 -0
- quorum_ai-0.1.5/quorum_overnight_topics.txt +136 -0
- quorum_ai-0.1.5/scripts/README.md +37 -0
- quorum_ai-0.1.5/scripts/quorum-research-mode/README.md +89 -0
- quorum_ai-0.1.5/scripts/quorum-research-mode/genetic_prompts.py +266 -0
- quorum_ai-0.1.5/scripts/quorum-research-mode/lora_finetune_setup.py +200 -0
- quorum_ai-0.1.5/scripts/quorum-self-modify/self_modify.py +800 -0
- quorum_ai-0.1.5/scripts/smoke_test_docker.sh +187 -0
- quorum_ai-0.1.5/src/quorum/__init__.py +15 -0
- quorum_ai-0.1.5/src/quorum/_local_mode.py +50 -0
- quorum_ai-0.1.5/src/quorum/agents/__init__.py +26 -0
- quorum_ai-0.1.5/src/quorum/agents/autopilot.py +126 -0
- quorum_ai-0.1.5/src/quorum/agents/drafts.py +350 -0
- quorum_ai-0.1.5/src/quorum/agents/reframe.py +139 -0
- quorum_ai-0.1.5/src/quorum/agents/tools/__init__.py +164 -0
- quorum_ai-0.1.5/src/quorum/agents/tools/linkedin.py +204 -0
- quorum_ai-0.1.5/src/quorum/agents/tools/mcp.py +116 -0
- quorum_ai-0.1.5/src/quorum/agents/tools/metrics_store.py +193 -0
- quorum_ai-0.1.5/src/quorum/agents/tools/twitter.py +127 -0
- quorum_ai-0.1.5/src/quorum/billing/__init__.py +13 -0
- quorum_ai-0.1.5/src/quorum/billing/email_sender.py +316 -0
- quorum_ai-0.1.5/src/quorum/billing/stripe_billing.py +1224 -0
- quorum_ai-0.1.5/src/quorum/cli.py +802 -0
- quorum_ai-0.1.5/src/quorum/context.py +105 -0
- quorum_ai-0.1.5/src/quorum/core/__init__.py +1 -0
- quorum_ai-0.1.5/src/quorum/core/consensus.py +765 -0
- quorum_ai-0.1.5/src/quorum/core/embeddings.py +716 -0
- quorum_ai-0.1.5/src/quorum/core/memory.py +654 -0
- quorum_ai-0.1.5/src/quorum/customer_keys.py +220 -0
- quorum_ai-0.1.5/src/quorum/doctor.py +418 -0
- quorum_ai-0.1.5/src/quorum/evolution/__init__.py +0 -0
- quorum_ai-0.1.5/src/quorum/evolution/ab_testing.py +1135 -0
- quorum_ai-0.1.5/src/quorum/evolution/adversarial.py +1457 -0
- quorum_ai-0.1.5/src/quorum/evolution/architecture_search.py +908 -0
- quorum_ai-0.1.5/src/quorum/evolution/competition.py +1227 -0
- quorum_ai-0.1.5/src/quorum/evolution/distillation.py +758 -0
- quorum_ai-0.1.5/src/quorum/evolution/federated.py +597 -0
- quorum_ai-0.1.5/src/quorum/evolution/hebbian.py +936 -0
- quorum_ai-0.1.5/src/quorum/evolution/memory_loop.py +585 -0
- quorum_ai-0.1.5/src/quorum/evolution/meta.py +783 -0
- quorum_ai-0.1.5/src/quorum/evolution/overnight.py +150 -0
- quorum_ai-0.1.5/src/quorum/evolution/rlhf.py +1021 -0
- quorum_ai-0.1.5/src/quorum/evolution/router.py +897 -0
- quorum_ai-0.1.5/src/quorum/evolution/self_prompt.py +1173 -0
- quorum_ai-0.1.5/src/quorum/evolution/swarm.py +127 -0
- quorum_ai-0.1.5/src/quorum/evolution/synthetic_data.py +975 -0
- quorum_ai-0.1.5/src/quorum/evolution/web_learner.py +313 -0
- quorum_ai-0.1.5/src/quorum/firestore_stores.py +351 -0
- quorum_ai-0.1.5/src/quorum/hsp/__init__.py +5 -0
- quorum_ai-0.1.5/src/quorum/hsp/ai_act_cert.py +518 -0
- quorum_ai-0.1.5/src/quorum/hsp/gate.py +162 -0
- quorum_ai-0.1.5/src/quorum/hsp/webhook.py +478 -0
- quorum_ai-0.1.5/src/quorum/providers/__init__.py +1 -0
- quorum_ai-0.1.5/src/quorum/providers/anthropic.py +92 -0
- quorum_ai-0.1.5/src/quorum/providers/base.py +43 -0
- quorum_ai-0.1.5/src/quorum/providers/claude_cli.py +85 -0
- quorum_ai-0.1.5/src/quorum/providers/cohere.py +85 -0
- quorum_ai-0.1.5/src/quorum/providers/deepseek.py +78 -0
- quorum_ai-0.1.5/src/quorum/providers/gemini.py +82 -0
- quorum_ai-0.1.5/src/quorum/providers/grok.py +77 -0
- quorum_ai-0.1.5/src/quorum/providers/mistral.py +83 -0
- quorum_ai-0.1.5/src/quorum/providers/moonshot.py +107 -0
- quorum_ai-0.1.5/src/quorum/providers/nvidia.py +98 -0
- quorum_ai-0.1.5/src/quorum/providers/ollama.py +52 -0
- quorum_ai-0.1.5/src/quorum/providers/openai.py +93 -0
- quorum_ai-0.1.5/src/quorum/providers/qwen.py +148 -0
- quorum_ai-0.1.5/src/quorum/providers/registry.py +185 -0
- quorum_ai-0.1.5/src/quorum/providers/replicate.py +112 -0
- quorum_ai-0.1.5/src/quorum/providers/zhipu.py +105 -0
- quorum_ai-0.1.5/src/quorum/server/__init__.py +23 -0
- quorum_ai-0.1.5/src/quorum/server/main.py +2017 -0
- quorum_ai-0.1.5/src/quorum/web/__init__.py +5 -0
- quorum_ai-0.1.5/src/quorum/web/multi_source.py +187 -0
- quorum_ai-0.1.5/src/quorum/web/search.py +109 -0
- quorum_ai-0.1.5/tests/__init__.py +0 -0
- quorum_ai-0.1.5/tests/evolution/__init__.py +0 -0
- quorum_ai-0.1.5/tests/evolution/test_ab_testing.py +350 -0
- quorum_ai-0.1.5/tests/evolution/test_adversarial.py +226 -0
- quorum_ai-0.1.5/tests/evolution/test_competition.py +250 -0
- quorum_ai-0.1.5/tests/evolution/test_hebbian.py +239 -0
- quorum_ai-0.1.5/tests/evolution/test_meta.py +147 -0
- quorum_ai-0.1.5/tests/evolution/test_self_prompt.py +286 -0
- quorum_ai-0.1.5/tests/evolution/test_synthetic_data.py +243 -0
- quorum_ai-0.1.5/tests/providers/__init__.py +0 -0
- quorum_ai-0.1.5/tests/providers/test_cohere.py +68 -0
- quorum_ai-0.1.5/tests/providers/test_grok.py +54 -0
- quorum_ai-0.1.5/tests/providers/test_mistral.py +175 -0
- quorum_ai-0.1.5/tests/test_consensus.py +51 -0
- quorum_ai-0.1.5/uv.lock +2349 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# .dockerignore — keep the build context small and secret-free
|
|
3
|
+
# ============================================================================
|
|
4
|
+
|
|
5
|
+
# --- Tests & dev tooling --------------------------------------------------
|
|
6
|
+
tests/
|
|
7
|
+
test/
|
|
8
|
+
**/tests/
|
|
9
|
+
**/test_*.py
|
|
10
|
+
**/*_test.py
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.coverage
|
|
13
|
+
.coverage.*
|
|
14
|
+
htmlcov/
|
|
15
|
+
.tox/
|
|
16
|
+
.nox/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.hypothesis/
|
|
20
|
+
|
|
21
|
+
# --- Python build / cache -------------------------------------------------
|
|
22
|
+
__pycache__/
|
|
23
|
+
**/__pycache__/
|
|
24
|
+
*.py[cod]
|
|
25
|
+
*$py.class
|
|
26
|
+
*.so
|
|
27
|
+
*.egg
|
|
28
|
+
*.egg-info/
|
|
29
|
+
build/
|
|
30
|
+
dist/
|
|
31
|
+
.eggs/
|
|
32
|
+
pip-wheel-metadata/
|
|
33
|
+
|
|
34
|
+
# --- Virtualenvs ----------------------------------------------------------
|
|
35
|
+
.venv/
|
|
36
|
+
venv/
|
|
37
|
+
env/
|
|
38
|
+
.env/
|
|
39
|
+
ENV/
|
|
40
|
+
|
|
41
|
+
# --- VCS ------------------------------------------------------------------
|
|
42
|
+
.git/
|
|
43
|
+
.gitignore
|
|
44
|
+
.gitattributes
|
|
45
|
+
.github/
|
|
46
|
+
.gitlab-ci.yml
|
|
47
|
+
|
|
48
|
+
# --- Local data / databases ----------------------------------------------
|
|
49
|
+
*.db
|
|
50
|
+
*.sqlite
|
|
51
|
+
*.sqlite3
|
|
52
|
+
*.db-journal
|
|
53
|
+
data/
|
|
54
|
+
local_data/
|
|
55
|
+
|
|
56
|
+
# --- Secrets / environment files -----------------------------------------
|
|
57
|
+
.env
|
|
58
|
+
.env.*
|
|
59
|
+
!.env.example
|
|
60
|
+
*.pem
|
|
61
|
+
*.key
|
|
62
|
+
*.crt
|
|
63
|
+
secrets/
|
|
64
|
+
.secrets/
|
|
65
|
+
|
|
66
|
+
# --- Editor / OS noise ----------------------------------------------------
|
|
67
|
+
.vscode/
|
|
68
|
+
.idea/
|
|
69
|
+
*.swp
|
|
70
|
+
*.swo
|
|
71
|
+
*~
|
|
72
|
+
.DS_Store
|
|
73
|
+
Thumbs.db
|
|
74
|
+
|
|
75
|
+
# --- Docker / CI artifacts -----------------------------------------------
|
|
76
|
+
Dockerfile*
|
|
77
|
+
!Dockerfile
|
|
78
|
+
docker-compose*.yml
|
|
79
|
+
.dockerignore
|
|
80
|
+
|
|
81
|
+
# --- Docs / misc not needed in image -------------------------------------
|
|
82
|
+
CHANGELOG.md
|
|
83
|
+
CONTRIBUTING.md
|
|
84
|
+
LICENSE
|
|
85
|
+
docs/
|
|
86
|
+
landing/
|
|
87
|
+
!src/**/*.md
|
|
88
|
+
|
|
89
|
+
# --- Logs -----------------------------------------------------------------
|
|
90
|
+
*.log
|
|
91
|
+
logs/
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# .dockerignore — keep the build context small and secret-free
|
|
3
|
+
# ============================================================================
|
|
4
|
+
|
|
5
|
+
# --- Tests & dev tooling --------------------------------------------------
|
|
6
|
+
tests/
|
|
7
|
+
test/
|
|
8
|
+
**/tests/
|
|
9
|
+
**/test_*.py
|
|
10
|
+
**/*_test.py
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.coverage
|
|
13
|
+
.coverage.*
|
|
14
|
+
htmlcov/
|
|
15
|
+
.tox/
|
|
16
|
+
.nox/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.hypothesis/
|
|
20
|
+
|
|
21
|
+
# --- Python build / cache -------------------------------------------------
|
|
22
|
+
__pycache__/
|
|
23
|
+
**/__pycache__/
|
|
24
|
+
*.py[cod]
|
|
25
|
+
*$py.class
|
|
26
|
+
*.so
|
|
27
|
+
*.egg
|
|
28
|
+
*.egg-info/
|
|
29
|
+
build/
|
|
30
|
+
dist/
|
|
31
|
+
.eggs/
|
|
32
|
+
pip-wheel-metadata/
|
|
33
|
+
|
|
34
|
+
# --- Virtualenvs ----------------------------------------------------------
|
|
35
|
+
.venv/
|
|
36
|
+
venv/
|
|
37
|
+
env/
|
|
38
|
+
.env/
|
|
39
|
+
ENV/
|
|
40
|
+
|
|
41
|
+
# --- VCS ------------------------------------------------------------------
|
|
42
|
+
.git/
|
|
43
|
+
.gitignore
|
|
44
|
+
.gitattributes
|
|
45
|
+
.github/
|
|
46
|
+
.gitlab-ci.yml
|
|
47
|
+
|
|
48
|
+
# --- Local data / databases ----------------------------------------------
|
|
49
|
+
*.db
|
|
50
|
+
*.sqlite
|
|
51
|
+
*.sqlite3
|
|
52
|
+
*.db-journal
|
|
53
|
+
data/
|
|
54
|
+
local_data/
|
|
55
|
+
|
|
56
|
+
# --- Secrets / environment files -----------------------------------------
|
|
57
|
+
.env
|
|
58
|
+
.env.*
|
|
59
|
+
!.env.example
|
|
60
|
+
*.pem
|
|
61
|
+
*.key
|
|
62
|
+
*.crt
|
|
63
|
+
secrets/
|
|
64
|
+
.secrets/
|
|
65
|
+
|
|
66
|
+
# --- Editor / OS noise ----------------------------------------------------
|
|
67
|
+
.vscode/
|
|
68
|
+
.idea/
|
|
69
|
+
*.swp
|
|
70
|
+
*.swo
|
|
71
|
+
*~
|
|
72
|
+
.DS_Store
|
|
73
|
+
Thumbs.db
|
|
74
|
+
|
|
75
|
+
# --- Docker / CI artifacts -----------------------------------------------
|
|
76
|
+
Dockerfile*
|
|
77
|
+
!Dockerfile
|
|
78
|
+
docker-compose*.yml
|
|
79
|
+
.dockerignore
|
|
80
|
+
|
|
81
|
+
# --- Docs / misc not needed in image -------------------------------------
|
|
82
|
+
README.md
|
|
83
|
+
CHANGELOG.md
|
|
84
|
+
CONTRIBUTING.md
|
|
85
|
+
LICENSE
|
|
86
|
+
docs/
|
|
87
|
+
landing/
|
|
88
|
+
*.md
|
|
89
|
+
!src/**/*.md
|
|
90
|
+
|
|
91
|
+
# --- Logs -----------------------------------------------------------------
|
|
92
|
+
*.log
|
|
93
|
+
logs/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Bring Your Own Keys (BYOK) — Quorum never stores or proxies your API keys.
|
|
2
|
+
# All keys are read at runtime by the provider you actually use.
|
|
3
|
+
|
|
4
|
+
# Paid providers (you bring your account)
|
|
5
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
6
|
+
OPENAI_API_KEY=sk-...
|
|
7
|
+
GOOGLE_AI_STUDIO_KEY=AQ...
|
|
8
|
+
XAI_API_KEY=xai-...
|
|
9
|
+
|
|
10
|
+
# Open-source models via Replicate (one key, many models)
|
|
11
|
+
REPLICATE_API_TOKEN=r8_...
|
|
12
|
+
|
|
13
|
+
# Local Llama via Ollama (free, runs on your machine)
|
|
14
|
+
OLLAMA_HOST=http://localhost:11434
|
|
15
|
+
|
|
16
|
+
# HSP integration (commercial users only)
|
|
17
|
+
HSP_PROTOCOL_KEY=
|
|
18
|
+
HSP_GATE_WEBHOOK=
|
|
19
|
+
|
|
20
|
+
# Optional: embedding model for semantic consensus
|
|
21
|
+
QUORUM_EMBED_PROVIDER=gemini # gemini | openai | local
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
README.md,1781574398026,744fde70922291a99a47ce695c74c75d7c3593911d35c90533ba42cd21ae3ae8
|
|
2
|
+
index.html,1781773507666,5b983a5323d553e3edeeacb05e5fcc7dfdd2cdccac9fe69643e0cb2ad18921b9
|
|
3
|
+
risk.png,1781773493192,489e1f4f91a1630ab03a11695eebb21bc4621ed4ddb28089cadeb9eb407a7b7f
|
|
4
|
+
node.png,1781773493970,ef8d24f596115951ad4452d55a6685be9d1ad674dc83b1bf014084150a5540a4
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Quorum are documented here. Format loosely follows Keep-a-Changelog; versioning follows SemVer.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] — 2026-06-16
|
|
6
|
+
|
|
7
|
+
The "real product" release: 13 self-evolution loops, vector memory, HSP gate, FastAPI server, Stripe billing, and EU AI Act per-query PDF certificate. All modules ship with in-memory fallbacks so tests pass without external keys.
|
|
8
|
+
|
|
9
|
+
### Added — core
|
|
10
|
+
|
|
11
|
+
- `src/quorum/core/embeddings.py` — async embedding client (OpenAI / Cohere / local) with cosine + euclidean similarity helpers; replaces the v0.0.1 Jaccard placeholder for semantic consensus
|
|
12
|
+
- `src/quorum/core/memory.py` — vector memory store backed by aiosqlite (with pure-Python in-memory fallback); recall-by-prompt for the memory loop
|
|
13
|
+
|
|
14
|
+
### Added — 13 self-evolution loops (`src/quorum/evolution/`)
|
|
15
|
+
|
|
16
|
+
- `rlhf.py` — explicit thumbs/correction-driven weight updates
|
|
17
|
+
- `hebbian.py` — co-correctness correlation between model pairs
|
|
18
|
+
- `distillation.py` — cheap models learn from consensus answers
|
|
19
|
+
- `router.py` — per-domain model weighting (code, vision, biomed, …)
|
|
20
|
+
- `memory_loop.py` — retrieval-augmented consensus on similar past prompts
|
|
21
|
+
- `meta.py` — meta-learning audit of which loops are improving accuracy
|
|
22
|
+
- `competition.py` — pairwise model duels, ELO-style ranking
|
|
23
|
+
- `ab_testing.py` — two prompt variants per call, win-rate tracking
|
|
24
|
+
- `synthetic_data.py` — high-confidence consensus → training data export
|
|
25
|
+
- `federated.py` — cross-tenant signal aggregation without raw data leak
|
|
26
|
+
- `self_prompt.py` — Quorum rewrites ambiguous prompts before fan-out
|
|
27
|
+
- `adversarial.py` — red-team prompts; models that fall for them lose weight
|
|
28
|
+
- `architecture_search.py` — trial new model combos / topologies; promote winners
|
|
29
|
+
|
|
30
|
+
### Added — HSP gate & compliance (`src/quorum/hsp/`)
|
|
31
|
+
|
|
32
|
+
- `ai_act_cert.py` — per-query PDF certificate (reportlab) satisfying EU AI Act Art. 12 + Art. 13; SHA-256 hash-chain across tenant; required for the 2026-08-02 enforcement window
|
|
33
|
+
- `webhook.py` — signed HSP gate decision callback handler (patent PCT/US26/11908)
|
|
34
|
+
|
|
35
|
+
### Added — billing (`src/quorum/billing/`)
|
|
36
|
+
|
|
37
|
+
- `stripe_billing.py` — Stripe-backed metered billing for Free / Pro / Team / Enterprise tiers + Compliance add-on; signature-verified webhook handler; in-memory fallback when `STRIPE_API_KEY` is unset so CI passes without secrets
|
|
38
|
+
|
|
39
|
+
### Added — server (`src/quorum/server/`)
|
|
40
|
+
|
|
41
|
+
- `main.py` — FastAPI app with slowapi rate limiting, Bearer/BYOK auth, endpoints: `/v1/consensus`, `/v1/consensus/stream` (SSE), `/v1/models`, `/v1/feedback`, `/v1/cert/{id}`, `/v1/billing/checkout`, `/v1/billing/webhook`, `/v1/hsp/webhook`, `/v1/usage`, `/healthz`, `/metrics`; entry point `quorum-server`
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- `pyproject.toml` — version bump 0.0.1 → 0.1.0; status Alpha → Beta; new deps: reportlab, stripe, fastapi, uvicorn[standard], slowapi; aiosqlite as optional `storage` extra; mypy added to `dev`; new script `quorum-server`
|
|
46
|
+
- `README.md` — full rewrite covering the 13 loops, billing tiers, hosted API endpoints, EU AI Act certification, and an ASCII architecture diagram
|
|
47
|
+
- `src/quorum/core/consensus.py` — replaced Jaccard placeholder with semantic-similarity path through `core/embeddings.py`; surfaces `evolution_signals` from the 13 loops
|
|
48
|
+
|
|
49
|
+
### Notes
|
|
50
|
+
|
|
51
|
+
- Every external service (Stripe, Supabase, HSP webhook signing) has a graceful in-memory or stub fallback when env vars are missing — `pytest` runs green on a clean machine
|
|
52
|
+
- All evolution loops are async write-backs; they never block the request path
|
|
53
|
+
- HSP-gated modules carry the dual Apache 2.0 + HSP commercial-restriction header
|
|
54
|
+
|
|
55
|
+
## [0.0.1] — 2026-06-16
|
|
56
|
+
|
|
57
|
+
Initial public cut. Minimal but real: five providers, async fan-out, lexical placeholder for consensus scoring, CLI.
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- `README.md`, `LICENSE` (Apache 2.0), `LICENSE-HSP` (PCT/US26/11908 commercial restrictions)
|
|
62
|
+
- `quorum/pyproject.toml` — package config, Python 3.10+, BYOK extras
|
|
63
|
+
- `quorum/src/quorum/__init__.py` — public `consensus` re-export
|
|
64
|
+
- `quorum/src/quorum/cli.py` — typer-based `quorum` CLI
|
|
65
|
+
- `quorum/src/quorum/core/consensus.py` — async orchestrator, Jaccard placeholder scoring
|
|
66
|
+
- `quorum/src/quorum/providers/base.py` — provider ABC
|
|
67
|
+
- `quorum/src/quorum/providers/registry.py` — provider discovery + ordering
|
|
68
|
+
- `quorum/src/quorum/providers/anthropic.py` — Claude client (BYOK)
|
|
69
|
+
- `quorum/src/quorum/providers/gemini.py` — Gemini client (BYOK)
|
|
70
|
+
- `quorum/src/quorum/providers/openai.py` — GPT client (BYOK)
|
|
71
|
+
- `quorum/src/quorum/providers/ollama.py` — local Ollama client
|
|
72
|
+
- `quorum/src/quorum/providers/replicate.py` — Replicate-hosted Llama/Mistral
|
|
73
|
+
- `quorum/src/quorum/hsp/__init__.py`, `hsp/gate.py` — decorator stub for HSP-gated calls
|
|
74
|
+
- `quorum/tests/test_consensus.py` — async smoke test, no external keys required
|
|
75
|
+
- `quorum/.env.example`, `quorum/.gitignore`
|
|
76
|
+
|
|
77
|
+
[0.1.0]: https://github.com/jaquelinejaque/sovereignchain/releases/tag/v0.1.0
|
|
78
|
+
[0.0.1]: https://github.com/jaquelinejaque/sovereignchain/releases/tag/v0.0.1
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# Quorum API — Multi-stage Dockerfile for Cloud Run
|
|
4
|
+
# Stage 1: builder — installs deps with uv into a virtualenv
|
|
5
|
+
# Stage 2: runner — slim runtime, non-root user, copies only the venv + src
|
|
6
|
+
# ============================================================================
|
|
7
|
+
|
|
8
|
+
# ----------------------------------------------------------------------------
|
|
9
|
+
# Stage 1 — builder
|
|
10
|
+
# ----------------------------------------------------------------------------
|
|
11
|
+
FROM python:3.12-slim AS builder
|
|
12
|
+
|
|
13
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
14
|
+
PYTHONUNBUFFERED=1 \
|
|
15
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
16
|
+
PIP_NO_CACHE_DIR=1 \
|
|
17
|
+
UV_LINK_MODE=copy \
|
|
18
|
+
UV_COMPILE_BYTECODE=1 \
|
|
19
|
+
VIRTUAL_ENV=/opt/venv \
|
|
20
|
+
PATH="/opt/venv/bin:${PATH}"
|
|
21
|
+
|
|
22
|
+
# Build-time OS deps (kept minimal; purged in runner stage by not copying)
|
|
23
|
+
RUN apt-get update \
|
|
24
|
+
&& apt-get install -y --no-install-recommends \
|
|
25
|
+
build-essential \
|
|
26
|
+
curl \
|
|
27
|
+
ca-certificates \
|
|
28
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
29
|
+
|
|
30
|
+
# Install uv (fast resolver/installer from Astral)
|
|
31
|
+
RUN pip install --no-cache-dir "uv>=0.4.0"
|
|
32
|
+
|
|
33
|
+
# Create isolated virtualenv we will copy into the runner
|
|
34
|
+
RUN uv venv "${VIRTUAL_ENV}"
|
|
35
|
+
|
|
36
|
+
WORKDIR /build
|
|
37
|
+
|
|
38
|
+
# Copy dependency manifest first to maximize Docker layer cache
|
|
39
|
+
COPY pyproject.toml ./
|
|
40
|
+
# Optional lock file — copy if present (graceful: ignored if missing on context)
|
|
41
|
+
|
|
42
|
+
# Install project dependencies into the venv
|
|
43
|
+
# --system would target /usr; we explicitly target the venv via VIRTUAL_ENV.
|
|
44
|
+
RUN uv pip install --no-cache --requirement pyproject.toml
|
|
45
|
+
|
|
46
|
+
# Copy the actual source and install the project itself (editable=False)
|
|
47
|
+
COPY README.md ./
|
|
48
|
+
COPY src ./src
|
|
49
|
+
RUN uv pip install --no-cache --no-deps .
|
|
50
|
+
|
|
51
|
+
# ----------------------------------------------------------------------------
|
|
52
|
+
# Stage 2 — runner (slim, non-root)
|
|
53
|
+
# ----------------------------------------------------------------------------
|
|
54
|
+
FROM python:3.12-slim AS runner
|
|
55
|
+
|
|
56
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
57
|
+
PYTHONUNBUFFERED=1 \
|
|
58
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
59
|
+
VIRTUAL_ENV=/opt/venv \
|
|
60
|
+
PATH="/opt/venv/bin:${PATH}" \
|
|
61
|
+
PORT=8080 \
|
|
62
|
+
HOST=0.0.0.0
|
|
63
|
+
|
|
64
|
+
# Runtime OS deps only — curl is needed for HEALTHCHECK
|
|
65
|
+
RUN apt-get update \
|
|
66
|
+
&& apt-get install -y --no-install-recommends \
|
|
67
|
+
curl \
|
|
68
|
+
ca-certificates \
|
|
69
|
+
tini \
|
|
70
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
71
|
+
&& groupadd --system --gid 1001 quorum \
|
|
72
|
+
&& useradd --system --uid 1001 --gid quorum --home-dir /app --shell /usr/sbin/nologin quorum
|
|
73
|
+
|
|
74
|
+
WORKDIR /app
|
|
75
|
+
|
|
76
|
+
# Copy the prepared virtualenv from builder
|
|
77
|
+
COPY --from=builder --chown=quorum:quorum /opt/venv /opt/venv
|
|
78
|
+
|
|
79
|
+
# Copy project files needed at runtime
|
|
80
|
+
COPY --chown=quorum:quorum pyproject.toml ./
|
|
81
|
+
COPY --chown=quorum:quorum src ./src
|
|
82
|
+
|
|
83
|
+
# Drop privileges
|
|
84
|
+
# Pre-create writable data dir for SQLite stores (api_keys, usage, memory, etc).
|
|
85
|
+
# /app is otherwise read-only for non-root, so api_key_store/memory/etc would fail.
|
|
86
|
+
RUN mkdir -p /app/.quorum && chown -R quorum:quorum /app/.quorum
|
|
87
|
+
USER quorum:quorum
|
|
88
|
+
|
|
89
|
+
EXPOSE 8080
|
|
90
|
+
|
|
91
|
+
# Cloud Run probes /healthz; local docker run uses this HEALTHCHECK too.
|
|
92
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
93
|
+
CMD curl -fsS "http://127.0.0.1:${PORT:-8080}/healthz" || exit 1
|
|
94
|
+
|
|
95
|
+
# tini = proper PID 1 (reaps zombies, forwards signals to uvicorn)
|
|
96
|
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
|
97
|
+
|
|
98
|
+
# Cloud Run injects $PORT (default 8080); host must be 0.0.0.0
|
|
99
|
+
# Use sh -c so ${PORT:-8080} expansion happens at runtime, not build time.
|
|
100
|
+
CMD ["sh", "-c", "exec uvicorn quorum.server.main:app --host 0.0.0.0 --port ${PORT:-8080} --proxy-headers --forwarded-allow-ips='*'"]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# Quorum API — Multi-stage Dockerfile for Cloud Run
|
|
4
|
+
# Stage 1: builder — installs deps with uv into a virtualenv
|
|
5
|
+
# Stage 2: runner — slim runtime, non-root user, copies only the venv + src
|
|
6
|
+
# ============================================================================
|
|
7
|
+
|
|
8
|
+
# ----------------------------------------------------------------------------
|
|
9
|
+
# Stage 1 — builder
|
|
10
|
+
# ----------------------------------------------------------------------------
|
|
11
|
+
FROM python:3.12-slim AS builder
|
|
12
|
+
|
|
13
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
14
|
+
PYTHONUNBUFFERED=1 \
|
|
15
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
16
|
+
PIP_NO_CACHE_DIR=1 \
|
|
17
|
+
UV_LINK_MODE=copy \
|
|
18
|
+
UV_COMPILE_BYTECODE=1 \
|
|
19
|
+
VIRTUAL_ENV=/opt/venv \
|
|
20
|
+
PATH="/opt/venv/bin:${PATH}"
|
|
21
|
+
|
|
22
|
+
# Build-time OS deps (kept minimal; purged in runner stage by not copying)
|
|
23
|
+
RUN apt-get update \
|
|
24
|
+
&& apt-get install -y --no-install-recommends \
|
|
25
|
+
build-essential \
|
|
26
|
+
curl \
|
|
27
|
+
ca-certificates \
|
|
28
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
29
|
+
|
|
30
|
+
# Install uv (fast resolver/installer from Astral)
|
|
31
|
+
RUN pip install --no-cache-dir "uv>=0.4.0"
|
|
32
|
+
|
|
33
|
+
# Create isolated virtualenv we will copy into the runner
|
|
34
|
+
RUN uv venv "${VIRTUAL_ENV}"
|
|
35
|
+
|
|
36
|
+
WORKDIR /build
|
|
37
|
+
|
|
38
|
+
# Copy dependency manifest first to maximize Docker layer cache
|
|
39
|
+
COPY pyproject.toml ./
|
|
40
|
+
# Optional lock file — copy if present (graceful: ignored if missing on context)
|
|
41
|
+
COPY uv.loc[k] ./
|
|
42
|
+
|
|
43
|
+
# Install project dependencies into the venv
|
|
44
|
+
# --system would target /usr; we explicitly target the venv via VIRTUAL_ENV.
|
|
45
|
+
RUN uv pip install --no-cache --requirement pyproject.toml
|
|
46
|
+
|
|
47
|
+
# Copy the actual source and install the project itself (editable=False)
|
|
48
|
+
COPY src ./src
|
|
49
|
+
RUN uv pip install --no-cache --no-deps .
|
|
50
|
+
|
|
51
|
+
# ----------------------------------------------------------------------------
|
|
52
|
+
# Stage 2 — runner (slim, non-root)
|
|
53
|
+
# ----------------------------------------------------------------------------
|
|
54
|
+
FROM python:3.12-slim AS runner
|
|
55
|
+
|
|
56
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
57
|
+
PYTHONUNBUFFERED=1 \
|
|
58
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
59
|
+
VIRTUAL_ENV=/opt/venv \
|
|
60
|
+
PATH="/opt/venv/bin:${PATH}" \
|
|
61
|
+
PORT=8080 \
|
|
62
|
+
HOST=0.0.0.0
|
|
63
|
+
|
|
64
|
+
# Runtime OS deps only — curl is needed for HEALTHCHECK
|
|
65
|
+
RUN apt-get update \
|
|
66
|
+
&& apt-get install -y --no-install-recommends \
|
|
67
|
+
curl \
|
|
68
|
+
ca-certificates \
|
|
69
|
+
tini \
|
|
70
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
71
|
+
&& groupadd --system --gid 1001 quorum \
|
|
72
|
+
&& useradd --system --uid 1001 --gid quorum --home-dir /app --shell /usr/sbin/nologin quorum
|
|
73
|
+
|
|
74
|
+
WORKDIR /app
|
|
75
|
+
|
|
76
|
+
# Copy the prepared virtualenv from builder
|
|
77
|
+
COPY --from=builder --chown=quorum:quorum /opt/venv /opt/venv
|
|
78
|
+
|
|
79
|
+
# Copy project files needed at runtime
|
|
80
|
+
COPY --chown=quorum:quorum pyproject.toml ./
|
|
81
|
+
COPY --chown=quorum:quorum src ./src
|
|
82
|
+
|
|
83
|
+
# Drop privileges
|
|
84
|
+
USER quorum:quorum
|
|
85
|
+
|
|
86
|
+
EXPOSE 8080
|
|
87
|
+
|
|
88
|
+
# Cloud Run probes /healthz; local docker run uses this HEALTHCHECK too.
|
|
89
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
90
|
+
CMD curl -fsS "http://127.0.0.1:${PORT:-8080}/healthz" || exit 1
|
|
91
|
+
|
|
92
|
+
# tini = proper PID 1 (reaps zombies, forwards signals to uvicorn)
|
|
93
|
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
|
94
|
+
|
|
95
|
+
# Cloud Run injects $PORT (default 8080); host must be 0.0.0.0
|
|
96
|
+
# Use sh -c so ${PORT:-8080} expansion happens at runtime, not build time.
|
|
97
|
+
CMD ["sh", "-c", "exec uvicorn quorum.server.main:app --host 0.0.0.0 --port ${PORT:-8080} --proxy-headers --forwarded-allow-ips='*'"]
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# Quorum API — Multi-stage Dockerfile for Cloud Run
|
|
4
|
+
# Stage 1: builder — installs deps with uv into a virtualenv
|
|
5
|
+
# Stage 2: runner — slim runtime, non-root user, copies only the venv + src
|
|
6
|
+
# ============================================================================
|
|
7
|
+
|
|
8
|
+
# ----------------------------------------------------------------------------
|
|
9
|
+
# Stage 1 — builder
|
|
10
|
+
# ----------------------------------------------------------------------------
|
|
11
|
+
FROM python:3.12-slim AS builder
|
|
12
|
+
|
|
13
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
14
|
+
PYTHONUNBUFFERED=1 \
|
|
15
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
16
|
+
PIP_NO_CACHE_DIR=1 \
|
|
17
|
+
UV_LINK_MODE=copy \
|
|
18
|
+
UV_COMPILE_BYTECODE=1 \
|
|
19
|
+
VIRTUAL_ENV=/opt/venv \
|
|
20
|
+
PATH="/opt/venv/bin:${PATH}"
|
|
21
|
+
|
|
22
|
+
# Build-time OS deps (kept minimal; purged in runner stage by not copying)
|
|
23
|
+
RUN apt-get update \
|
|
24
|
+
&& apt-get install -y --no-install-recommends \
|
|
25
|
+
build-essential \
|
|
26
|
+
curl \
|
|
27
|
+
ca-certificates \
|
|
28
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
29
|
+
|
|
30
|
+
# Install uv (fast resolver/installer from Astral)
|
|
31
|
+
RUN pip install --no-cache-dir "uv>=0.4.0"
|
|
32
|
+
|
|
33
|
+
# Create isolated virtualenv we will copy into the runner
|
|
34
|
+
RUN uv venv "${VIRTUAL_ENV}"
|
|
35
|
+
|
|
36
|
+
WORKDIR /build
|
|
37
|
+
|
|
38
|
+
# Copy dependency manifest first to maximize Docker layer cache
|
|
39
|
+
COPY pyproject.toml ./
|
|
40
|
+
# Optional lock file — copy if present (graceful: ignored if missing on context)
|
|
41
|
+
|
|
42
|
+
# Install project dependencies into the venv
|
|
43
|
+
# --system would target /usr; we explicitly target the venv via VIRTUAL_ENV.
|
|
44
|
+
RUN uv pip install --no-cache --requirement pyproject.toml
|
|
45
|
+
|
|
46
|
+
# Copy the actual source and install the project itself (editable=False)
|
|
47
|
+
COPY src ./src
|
|
48
|
+
RUN uv pip install --no-cache --no-deps .
|
|
49
|
+
|
|
50
|
+
# ----------------------------------------------------------------------------
|
|
51
|
+
# Stage 2 — runner (slim, non-root)
|
|
52
|
+
# ----------------------------------------------------------------------------
|
|
53
|
+
FROM python:3.12-slim AS runner
|
|
54
|
+
|
|
55
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
56
|
+
PYTHONUNBUFFERED=1 \
|
|
57
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
58
|
+
VIRTUAL_ENV=/opt/venv \
|
|
59
|
+
PATH="/opt/venv/bin:${PATH}" \
|
|
60
|
+
PORT=8080 \
|
|
61
|
+
HOST=0.0.0.0
|
|
62
|
+
|
|
63
|
+
# Runtime OS deps only — curl is needed for HEALTHCHECK
|
|
64
|
+
RUN apt-get update \
|
|
65
|
+
&& apt-get install -y --no-install-recommends \
|
|
66
|
+
curl \
|
|
67
|
+
ca-certificates \
|
|
68
|
+
tini \
|
|
69
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
70
|
+
&& groupadd --system --gid 1001 quorum \
|
|
71
|
+
&& useradd --system --uid 1001 --gid quorum --home-dir /app --shell /usr/sbin/nologin quorum
|
|
72
|
+
|
|
73
|
+
WORKDIR /app
|
|
74
|
+
|
|
75
|
+
# Copy the prepared virtualenv from builder
|
|
76
|
+
COPY --from=builder --chown=quorum:quorum /opt/venv /opt/venv
|
|
77
|
+
|
|
78
|
+
# Copy project files needed at runtime
|
|
79
|
+
COPY --chown=quorum:quorum pyproject.toml ./
|
|
80
|
+
COPY --chown=quorum:quorum src ./src
|
|
81
|
+
|
|
82
|
+
# Drop privileges
|
|
83
|
+
USER quorum:quorum
|
|
84
|
+
|
|
85
|
+
EXPOSE 8080
|
|
86
|
+
|
|
87
|
+
# Cloud Run probes /healthz; local docker run uses this HEALTHCHECK too.
|
|
88
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
89
|
+
CMD curl -fsS "http://127.0.0.1:${PORT:-8080}/healthz" || exit 1
|
|
90
|
+
|
|
91
|
+
# tini = proper PID 1 (reaps zombies, forwards signals to uvicorn)
|
|
92
|
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
|
93
|
+
|
|
94
|
+
# Cloud Run injects $PORT (default 8080); host must be 0.0.0.0
|
|
95
|
+
# Use sh -c so ${PORT:-8080} expansion happens at runtime, not build time.
|
|
96
|
+
CMD ["sh", "-c", "exec uvicorn quorum.server.main:app --host 0.0.0.0 --port ${PORT:-8080} --proxy-headers --forwarded-allow-ips='*'"]
|