openzoo 0.48.85 → 0.48.87
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.
- package/lib/grokui.mjs +22 -3
- package/lib/proxy.js +3 -1
- package/package.json +2 -2
package/lib/grokui.mjs
CHANGED
|
@@ -2840,6 +2840,7 @@ const APP_HTML = `<!doctype html>
|
|
|
2840
2840
|
</div>
|
|
2841
2841
|
<div id="hud">
|
|
2842
2842
|
<div class="htitle">YOUR WALLET · THIS SESSION</div>
|
|
2843
|
+
<div class="hrow"><span>prepaid credit</span><span id="hCredit" class="hlime">—</span></div>
|
|
2843
2844
|
<div class="hrow"><span>you've paid</span><span id="hYouSpent">—</span></div>
|
|
2844
2845
|
<div class="hrow"><span>our cost (cogs)</span><span id="hYouCogs">—</span></div>
|
|
2845
2846
|
<div class="hrow"><span>margin</span><span id="hYouMargin" class="hlime">—</span></div>
|
|
@@ -3132,6 +3133,15 @@ const APP_HTML = `<!doctype html>
|
|
|
3132
3133
|
walletBody.appendChild(p);
|
|
3133
3134
|
return;
|
|
3134
3135
|
}
|
|
3136
|
+
if (w.creditUsd != null && w.creditUsd !== '') {
|
|
3137
|
+
const c = document.createElement('div');
|
|
3138
|
+
c.className = 'wbal';
|
|
3139
|
+
c.style.color = '#b8f240';
|
|
3140
|
+
c.style.fontSize = '18px';
|
|
3141
|
+
c.style.fontWeight = '700';
|
|
3142
|
+
c.textContent = 'Prepaid credit $' + (Number(w.creditUsd) || 0).toFixed(2);
|
|
3143
|
+
walletBody.appendChild(c);
|
|
3144
|
+
}
|
|
3135
3145
|
if (w.solana) walletBody.appendChild(walletRow('Solana', w.solana));
|
|
3136
3146
|
if (w.evm) walletBody.appendChild(walletRow('Base / RH', w.evm));
|
|
3137
3147
|
if (w.balances) {
|
|
@@ -3918,7 +3928,6 @@ const APP_HTML = `<!doctype html>
|
|
|
3918
3928
|
|
|
3919
3929
|
const hudBtn = document.getElementById('hudBtn');
|
|
3920
3930
|
const hud = document.getElementById('hud');
|
|
3921
|
-
const chatHeader = document.getElementById('chatHeader');
|
|
3922
3931
|
const mainEl = document.getElementById('main');
|
|
3923
3932
|
// Pin the cost card just under the header. #chatHeader wraps, so a fixed
|
|
3924
3933
|
// 40px sat on top of the spend dials. Measure the live bottom each time
|
|
@@ -3940,6 +3949,8 @@ const APP_HTML = `<!doctype html>
|
|
|
3940
3949
|
// straight to localhost:8402 would work fine, but routing it through
|
|
3941
3950
|
// our own backend keeps one fetch path if that ever needs to change.
|
|
3942
3951
|
const you = await (await fetch(API + '/hud-summary')).json();
|
|
3952
|
+
const creditEl = document.getElementById('hCredit');
|
|
3953
|
+
if (creditEl) creditEl.textContent = (you.creditUsd == null) ? '—' : usd(Number(you.creditUsd) || 0);
|
|
3943
3954
|
const spent = Number(you.spentUsd) || 0;
|
|
3944
3955
|
const cogs = Number(you.cogsUsd) || 0;
|
|
3945
3956
|
const direct = Number(you.directUsd) || 0;
|
|
@@ -4008,6 +4019,10 @@ const server = http.createServer((req, res) => {
|
|
|
4008
4019
|
let w = { error: 'proxy unreachable' };
|
|
4009
4020
|
try { w = await (await fetch(`${PROXY}/wallet`)).json(); }
|
|
4010
4021
|
catch { /* proxy not up yet — say so rather than render an empty modal */ }
|
|
4022
|
+
try {
|
|
4023
|
+
const { creditBalance } = await import('./info.js');
|
|
4024
|
+
w.creditUsd = await creditBalance();
|
|
4025
|
+
} catch { /* leave credit off if the gateway is down */ }
|
|
4011
4026
|
res.writeHead(200, { 'content-type': 'application/json' });
|
|
4012
4027
|
res.end(JSON.stringify(w));
|
|
4013
4028
|
})();
|
|
@@ -4063,9 +4078,13 @@ const server = http.createServer((req, res) => {
|
|
|
4063
4078
|
|
|
4064
4079
|
if (req.method === 'GET' && req.url === '/hud-summary') {
|
|
4065
4080
|
(async () => {
|
|
4066
|
-
let you = { spentUsd: 0, cogsUsd: 0, directUsd: 0, paidCalls: 0 };
|
|
4067
|
-
try { you = await (await fetch('http://127.0.0.1:8402/v1/session')).json(); }
|
|
4081
|
+
let you = { spentUsd: 0, cogsUsd: 0, directUsd: 0, paidCalls: 0, creditUsd: null };
|
|
4082
|
+
try { you = { ...you, ...(await (await fetch('http://127.0.0.1:8402/v1/session')).json()) }; }
|
|
4068
4083
|
catch { /* local proxy not running — HUD shows zeros rather than guessing */ }
|
|
4084
|
+
try {
|
|
4085
|
+
const { creditBalance } = await import('./info.js');
|
|
4086
|
+
you.creditUsd = await creditBalance();
|
|
4087
|
+
} catch { /* credit is advisory */ }
|
|
4069
4088
|
res.writeHead(200, { 'content-type': 'application/json' });
|
|
4070
4089
|
res.end(JSON.stringify(you));
|
|
4071
4090
|
})();
|
package/lib/proxy.js
CHANGED
|
@@ -856,8 +856,9 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
856
856
|
// whichever surface happens to be asking. Local-only, no auth needed:
|
|
857
857
|
// it's a number, not a capability.
|
|
858
858
|
if (req.method === 'GET' && (req.url || '').split('?')[0] === '/v1/session') {
|
|
859
|
+
refreshCredit();
|
|
859
860
|
res.writeHead(200, { 'content-type': 'application/json' });
|
|
860
|
-
res.end(JSON.stringify({ spentUsd: sessionSpent, cogsUsd: sessionCogs, directUsd: sessionDirect, paidCalls }));
|
|
861
|
+
res.end(JSON.stringify({ spentUsd: sessionSpent, cogsUsd: sessionCogs, directUsd: sessionDirect, paidCalls, creditUsd }));
|
|
861
862
|
return;
|
|
862
863
|
}
|
|
863
864
|
|
|
@@ -874,6 +875,7 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
874
875
|
// caller can tell a genuinely empty wallet from a transient 402
|
|
875
876
|
balances: balanceLine(lastSnap || []) || null,
|
|
876
877
|
funded: (lastSnap || []).some((b) => b.ui > 0),
|
|
878
|
+
creditUsd,
|
|
877
879
|
}));
|
|
878
880
|
return;
|
|
879
881
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.48.
|
|
4
|
-
"description": "Local x402-paying proxy + MCP server for openzoo.fun
|
|
3
|
+
"version": "0.48.87",
|
|
4
|
+
"description": "Local x402-paying proxy + MCP server for openzoo.fun \u2014 point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|