HOARD tier: $50/mo unlimited (30-day entitlement), bolder provable claims, idempotent DB migrations
This commit is contained in:
@@ -11,9 +11,19 @@
|
||||
"free_monthly": 30,
|
||||
"admin_key": "sk-draco-admin-CHANGE_ME",
|
||||
"plans": {
|
||||
"satchel": {"usd": 3, "credits": 60},
|
||||
"crate": {"usd": 10, "credits": 250},
|
||||
"hoard": {"usd": 25, "credits": 750}
|
||||
"satchel": {
|
||||
"usd": 3,
|
||||
"credits": 60
|
||||
},
|
||||
"crate": {
|
||||
"usd": 10,
|
||||
"credits": 250
|
||||
},
|
||||
"hoard": {
|
||||
"usd": 50,
|
||||
"credits": 1000000,
|
||||
"label": "UNLIMITED 30 DAYS"
|
||||
}
|
||||
},
|
||||
"btcpay": {
|
||||
"url": "https://btcpay.thetempleofdoom.com",
|
||||
@@ -21,4 +31,4 @@
|
||||
"api_key": "SET_ME",
|
||||
"webhook_secret": "SET_ME"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
credits INTEGER DEFAULT 0,
|
||||
free_used INTEGER DEFAULT 0,
|
||||
total_calls INTEGER DEFAULT 0,
|
||||
unlimited_until VARCHAR(32),
|
||||
is_admin INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
last_used_at TIMESTAMP
|
||||
@@ -59,10 +60,16 @@ def db():
|
||||
def init_db():
|
||||
c = db()
|
||||
c.executescript(SCHEMA)
|
||||
try: # in-place migration for DBs created before total_calls existed
|
||||
c.execute("SELECT total_calls FROM users LIMIT 1")
|
||||
except sqlite3.OperationalError:
|
||||
c.execute("ALTER TABLE users ADD COLUMN total_calls INTEGER DEFAULT 0")
|
||||
for col, decl in (("total_calls", "INTEGER DEFAULT 0"), # idempotent migrations:
|
||||
("unlimited_until", "VARCHAR(32)")): # gunicorn workers race at boot
|
||||
try:
|
||||
c.execute(f"SELECT {col} FROM users LIMIT 1")
|
||||
except sqlite3.OperationalError:
|
||||
try:
|
||||
c.execute(f"ALTER TABLE users ADD COLUMN {col} {decl}")
|
||||
except sqlite3.OperationalError as e: # another worker won the race
|
||||
if "duplicate column" not in str(e).lower():
|
||||
raise
|
||||
c.commit()
|
||||
c.execute("INSERT OR IGNORE INTO users (email, api_key, credits, is_admin) VALUES (?,?,?,1)",
|
||||
("admin@draco.local", CFG["admin_key"], 999999))
|
||||
@@ -417,7 +424,9 @@ def consume(user, kind, detail="", ip=""):
|
||||
cur = c.execute("SELECT credits, free_used FROM users WHERE id=?", (user["id"],)).fetchone()
|
||||
row = c.execute("SELECT * FROM users WHERE id=?", (user["id"],)).fetchone()
|
||||
month = time.strftime("%Y-%m")
|
||||
if row["free_used"] < CFG["free_monthly"]:
|
||||
if row["unlimited_until"] and row["unlimited_until"] > time.strftime("%Y-%m-%d"):
|
||||
pass # HOARD subscriber: unlimited, no decrement
|
||||
elif row["free_used"] < CFG["free_monthly"]:
|
||||
c.execute("UPDATE users SET free_used=free_used+1, last_used_at=CURRENT_TIMESTAMP WHERE id=?", (user["id"],))
|
||||
elif row["credits"] > 0:
|
||||
c.execute("UPDATE users SET credits=credits-1, last_used_at=CURRENT_TIMESTAMP WHERE id=?", (user["id"],))
|
||||
@@ -580,7 +589,12 @@ def handle_webhook(body, header_sig_ok):
|
||||
return True
|
||||
if etype == "InvoiceSettled":
|
||||
c.execute("UPDATE payments SET status='settled', settled_at=CURRENT_TIMESTAMP WHERE invoice_id=?", (invoice_id,))
|
||||
c.execute("UPDATE users SET credits=credits+? WHERE id=?", (p["credits"], p["user_id"]))
|
||||
if p["amount_usd"] >= 50: # HOARD = $50/mo unlimited: 30 days from settle
|
||||
import datetime
|
||||
until = (datetime.date.today() + datetime.timedelta(days=30)).isoformat()
|
||||
c.execute("UPDATE users SET unlimited_until=? WHERE id=?", (until, p["user_id"]))
|
||||
else:
|
||||
c.execute("UPDATE users SET credits=credits+? WHERE id=?", (p["credits"], p["user_id"]))
|
||||
else:
|
||||
c.execute("UPDATE payments SET status='processing' WHERE invoice_id=?", (invoice_id,))
|
||||
c.commit()
|
||||
|
||||
20
pages.py
20
pages.py
@@ -75,16 +75,18 @@ NAV = """<a class='logo' href='/'>DRACO<small>book-forged oracle</small></a>
|
||||
|
||||
PAGE_HOME = """
|
||||
<div class='hero'>
|
||||
<span class='badge'>◈ Grounded in real books — not vibes</span>
|
||||
<h1>The smartest coding AI you can <span class='gold'>prove.</span></h1>
|
||||
<p class='dim'>Most AI assistants guess. DRACO retrieves from <b>__STATS__</b> —
|
||||
languages, kernels, networks, exploitation, red-team tradecraft — and shows you the exact
|
||||
books behind every answer. Check the citations. That's the proof.</p>
|
||||
<span class='badge'>◈ THE LARGEST PROVABLE BOOK-GROUNDED AI ON THE INTERNET</span>
|
||||
<h1>Other AIs guess.<br>DRACO <span class='gold'>knows</span> — and proves it.</h1>
|
||||
<p class='dim'>Generic chatbots hallucinate from compressed training data. DRACO retrieves
|
||||
live from <b>__STATS__</b> of actual expert books — languages, kernels, networks,
|
||||
exploitation, red-team tradecraft — and stamps the exact source on every claim.
|
||||
<b class='gold'>No cutoff. No hallucination. Receipts attached.</b></p>
|
||||
<div class='stats'>
|
||||
<div class='stat'><b>{{ books }}</b><span>real books indexed</span></div>
|
||||
<div class='stat'><b>{{ chunks }}</b><span>retrievable passages</span></div>
|
||||
<div class='stat'><b>{{ mb }}M</b><span>chars of expert text</span></div>
|
||||
<div class='stat'><b><2s</b><span>retrieval + answer start</span></div>
|
||||
<div class='stat'><b><2s</b><span>retrieval + answer start</span></div>
|
||||
<div class='stat'><b>100%</b><span>cited or flagged — never silent</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -111,10 +113,10 @@ PAGE_HOME = """
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>◈ Why "book-forged" is different</h2>
|
||||
<h2>◈ Why DRACO embarrasses generic chatbots</h2>
|
||||
<div class='grid'>
|
||||
<div class='card'><b>Every claim has a receipt</b><span>answers cite [n] — click through to the source book in /library</span></div>
|
||||
<div class='card'><b>No 2021 knowledge cutoff</b><span>fundamentals from the canon: K&R, Tanenbaum, the shellcoders' handbook</span></div>
|
||||
<div class='card'><b>Every claim has a receipt</b><span>answers cite [n] with the source book attached — verify in one click, unlike any chatbot's 'trust me'</span></div>
|
||||
<div class='card'><b>Knowledge cutoff: NEVER</b><span>the canon is resident — K&R, Tanenbaum, the shellcoders' handbook — not compressed away in training</span></div>
|
||||
<div class='card'><b>Agentic by design</b><span>MCP server + REST API — summon DRACO from Claude, GPT, or any agent</span></div>
|
||||
<div class='card'><b>Self-hosted, no telemetry</b><span>runs on bare metal; questions never leave the house</span></div>
|
||||
</div>
|
||||
|
||||
12
pages2.py
12
pages2.py
@@ -53,11 +53,17 @@ self-hosted BTCPay — no card processor ever sees you or us.</p>
|
||||
<div class='stat' style='min-width:280px'><b style='color:var(--green)'>FREE</b><span>{{ free_monthly }} API credits / month + {{ free_day }} web questions / day</span></div>
|
||||
<div class='stat' style='min-width:280px'><b>1 credit</b><span>= 1 ask (RAG + citations) or 1 search</span></div>
|
||||
</div>
|
||||
<h2>◈ Credit packs — one-time, never expire</h2>
|
||||
<h2>◈ Pricing — the honest kind</h2>
|
||||
<p class='dim'><b class='gold'>$50/mo HOARD</b> = unlimited: every ask, every search, the whole
|
||||
{{ mb }}M-char library, as hard as you want to run it. Or pay-per-use with packs. Bitcoin only,
|
||||
no subscription trap — HOARD simply expires in 30 days unless you renew.</p>
|
||||
<table>
|
||||
<tr><th>Pack</th><th>Price</th><th>Credits</th><th>$/credit</th><th></th></tr>
|
||||
<tr><th>Tier</th><th>Price</th><th>What you get</th><th></th></tr>
|
||||
{% for name, p in plans.items() %}
|
||||
<tr><td><b>{{ name }}</b></td><td>${{ '%.2f'|format(p.usd) }}</td><td>{{ p.credits }}</td><td>${{ '%.3f'|format(p.usd / p.credits) }}</td>
|
||||
<tr{% if p.usd >= 50 %} style='border:1px solid var(--gold)'{% endif %}>
|
||||
<td><b class='gold'>{{ name }}</b>{% if p.usd >= 50 %} <span class='badge' style='font-size:10px;padding:1px 8px;margin-left:6px'>BEST</span>{% endif %}</td>
|
||||
<td>${{ '%.0f'|format(p.usd) }}{% if p.usd >= 50 %}/mo{% endif %}</td>
|
||||
<td>{% if p.usd >= 50 %}UNLIMITED asks + searches for 30 days. The whole library, unmetered.{% else %}{{ p.credits }} credits (1 = 1 ask or search), never expire.{% endif %}</td>
|
||||
<td><button onclick='buy("{{ name }}")'>BUY ⟶</button></td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user