@goodandready/dsh-cost-meter 0.8.22 → 0.8.24
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/client.js +26 -1
- package/lib/index.js +9 -8
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1184,7 +1184,6 @@ window.__ModuleLoader__.load({
|
|
|
1184
1184
|
const useProjection = props.useProjection
|
|
1185
1185
|
const usage = useProjection ? useProjection('tokenUsage') : undefined
|
|
1186
1186
|
const byModel = useProjection ? useProjection('costByModel') : undefined
|
|
1187
|
-
const turns = (byModel?.turns && byModel.turns.length > 0) ? byModel.turns : (state?.turns || [])
|
|
1188
1187
|
const [state, setState] = React.useState(null)
|
|
1189
1188
|
const [open, setOpen] = React.useState(false)
|
|
1190
1189
|
const [now, setNow] = React.useState(() => new Date())
|
|
@@ -1250,6 +1249,7 @@ window.__ModuleLoader__.load({
|
|
|
1250
1249
|
|
|
1251
1250
|
if (!state) return null
|
|
1252
1251
|
|
|
1252
|
+
const turns = (byModel?.turns && byModel.turns.length > 0) ? byModel.turns : (state.turns || [])
|
|
1253
1253
|
const stored = (settingsSnap && settingsSnap.value) || {}
|
|
1254
1254
|
const currency = stored.currency !== undefined ? String(stored.currency) : (state.currency || '$')
|
|
1255
1255
|
const fx = stored.usdRate !== undefined && !isNaN(Number(stored.usdRate)) ? Number(stored.usdRate) : (Number(state.usdRate) || 1)
|
|
@@ -1472,6 +1472,31 @@ window.__ModuleLoader__.load({
|
|
|
1472
1472
|
budgetExceeded ? h('div', { key: 'budget-warn', className: 'dcm-alert dcm-alert-err', style: { marginTop: 6, padding: '6px 10px', fontSize: 11 } },
|
|
1473
1473
|
t('budget.exceeded', { limit: money(budgetThreshold * fx, currency) })) : null,
|
|
1474
1474
|
|
|
1475
|
+
renderSparkline(turns, {
|
|
1476
|
+
h,
|
|
1477
|
+
currency,
|
|
1478
|
+
fx,
|
|
1479
|
+
activeRate: active,
|
|
1480
|
+
t,
|
|
1481
|
+
}),
|
|
1482
|
+
|
|
1483
|
+
(() => {
|
|
1484
|
+
const proj = calculateBurnRateAndProjection(turns, total / fx)
|
|
1485
|
+
const burnRate = proj.burnRatePerHourUsd * fx
|
|
1486
|
+
const projectedTotal = proj.projectedCostUsd * fx
|
|
1487
|
+
if (burnRate <= 0) return null
|
|
1488
|
+
return h('div', { key: 'proj-box', className: 'dcm-proj-box' }, [
|
|
1489
|
+
h('span', { key: 'burn', className: 'dcm-proj-item' }, [
|
|
1490
|
+
h('span', null, t('projection.burn_rate') + ' '),
|
|
1491
|
+
h('span', { className: 'dcm-proj-val' }, money(burnRate, currency) + t('projection.per_hour')),
|
|
1492
|
+
]),
|
|
1493
|
+
h('span', { key: 'proj', className: 'dcm-proj-item' }, [
|
|
1494
|
+
h('span', null, t('projection.projected') + ' '),
|
|
1495
|
+
h('span', { className: 'dcm-proj-val' }, '≈ ' + money(projectedTotal, currency)),
|
|
1496
|
+
]),
|
|
1497
|
+
])
|
|
1498
|
+
})(),
|
|
1499
|
+
|
|
1475
1500
|
h('hr', { key: 'hr1', className: 'dcm-hr' }),
|
|
1476
1501
|
|
|
1477
1502
|
h('div', { key: 'rates', className: flat ? 'dcm-panel-grid-flat' : 'dcm-panel-grid' }, [
|
package/lib/index.js
CHANGED
|
@@ -68,8 +68,11 @@ export function isTrustedCaller(request, ctx = null) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
const remote = request.socket?.remoteAddress || request.connection?.remoteAddress
|
|
71
|
+
const loopback = isLoopback(remote)
|
|
72
|
+
if (ctx && !conn && !loopback) return false
|
|
73
|
+
|
|
71
74
|
const site = request.headers?.['sec-fetch-site']
|
|
72
|
-
if (site === 'cross-site') return false
|
|
75
|
+
if (site === 'cross-site' || site === 'same-site') return false
|
|
73
76
|
|
|
74
77
|
const host = request.headers?.['host']
|
|
75
78
|
const origin = request.headers?.['origin']
|
|
@@ -78,11 +81,11 @@ export function isTrustedCaller(request, ctx = null) {
|
|
|
78
81
|
const url = new URL(origin)
|
|
79
82
|
if (url.protocol === 'http:' || url.protocol === 'https:') {
|
|
80
83
|
if (host && url.host.toLowerCase() === host.toLowerCase()) return true
|
|
81
|
-
if (isLoopback(url.hostname) &&
|
|
84
|
+
if (isLoopback(url.hostname) && loopback) return true
|
|
82
85
|
return false
|
|
83
86
|
}
|
|
84
87
|
// Non-http/https origin (e.g. dsh-app://app in DSH Desktop)
|
|
85
|
-
if (
|
|
88
|
+
if (loopback) return true
|
|
86
89
|
return false
|
|
87
90
|
} catch {
|
|
88
91
|
return false
|
|
@@ -95,20 +98,18 @@ export function isTrustedCaller(request, ctx = null) {
|
|
|
95
98
|
const url = new URL(referer)
|
|
96
99
|
if (url.protocol === 'http:' || url.protocol === 'https:') {
|
|
97
100
|
if (host && url.host.toLowerCase() === host.toLowerCase()) return true
|
|
98
|
-
if (isLoopback(url.hostname) &&
|
|
101
|
+
if (isLoopback(url.hostname) && loopback) return true
|
|
99
102
|
return false
|
|
100
103
|
}
|
|
101
104
|
// Non-http/https referer (e.g. dsh-app://app/ in DSH Desktop)
|
|
102
|
-
if (
|
|
105
|
+
if (loopback) return true
|
|
103
106
|
return false
|
|
104
107
|
} catch {
|
|
105
108
|
return false
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
if (
|
|
110
|
-
if (site === 'same-origin') return true
|
|
111
|
-
if (isLoopback(remote)) return true
|
|
112
|
+
if (loopback) return true
|
|
112
113
|
|
|
113
114
|
return false
|
|
114
115
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-cost-meter",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.24",
|
|
4
4
|
"description": "DeepSeek Harness plugin: a session cost chip in the conversation header - live token usage by bucket, peak/off-peak tariff, and a countdown to the next tariff switch.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|