sandoichi 0.4.0 → 0.4.1
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/README.md +4 -4
- package/package.json +1 -1
- package/src/statusline.mjs +8 -19
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# sandoichi
|
|
2
2
|
|
|
3
|
-
`sandoichi` is Sando's optional JavaScript library. The
|
|
3
|
+
`sandoichi` is Sando's optional JavaScript library. The marketplace plugin is the main product. Install the plugin through the Claude Code or Codex marketplace.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm install sandoichi
|
|
@@ -24,12 +24,12 @@ Project-specific detectors can be declared in `.sando/redaction.json`:
|
|
|
24
24
|
|
|
25
25
|
Built-ins stay enabled. Profiles are declarative and local to the current project; invalid profiles fail visibly.
|
|
26
26
|
|
|
27
|
-
The library requires Node.js `>=22.22.0 <23` and has no runtime dependencies. Installing it does not install or enable the plugin. The plugin
|
|
27
|
+
The library requires Node.js `>=22.22.0 <23` and has no runtime dependencies. Installing it does not install or enable the plugin. The plugin remains the supported host surface; this package exports the context/history runtime, provider usage report, paired accounting, and explicit proxy API only.
|
|
28
28
|
|
|
29
|
-
`computeWeightedUsage` and `summarizePairedSessions` keep mechanical reduction, weighted estimates, provider-reported cost, and paired-session evidence
|
|
29
|
+
`computeWeightedUsage` and `summarizePairedSessions` keep mechanical reduction, weighted estimates, provider-reported cost, and paired-session evidence separate. The benchmark report adds explicit replay counterfactuals. The library does not install hooks, register MCP servers, or make routing/backoff decisions for a host.
|
|
30
30
|
|
|
31
31
|
For plugin installation, see the [main project README](https://github.com/yuzushi-dev/Sando#readme).
|
|
32
32
|
|
|
33
33
|
Telemetry is off by default. An interactive npm install asks once for consent; see the [full disclosure](https://github.com/yuzushi-dev/Sando/blob/main/TELEMETRY.md).
|
|
34
34
|
|
|
35
|
-
MIT.
|
|
35
|
+
License: MIT.
|
package/package.json
CHANGED
package/src/statusline.mjs
CHANGED
|
@@ -38,10 +38,12 @@ function readMetricsSnapshot(metricsPath, { host, sessionId, model } = {}) {
|
|
|
38
38
|
const providerSavings = report.cumulative.providerReportedSavingsTokens;
|
|
39
39
|
const source = hasProvider && !hasEstimate && providerSavings !== null
|
|
40
40
|
? 'provider-reported' : 'estimate';
|
|
41
|
+
const estimatedInputTokens = records.reduce((total, item) => total + item.estimatedInputTokens, 0);
|
|
41
42
|
const latest = [...records].sort((left, right) => left.at.localeCompare(right.at)).at(-1);
|
|
42
43
|
return {
|
|
43
44
|
updatedAt: latestAt(records), source,
|
|
44
45
|
model: model ?? latest?.model,
|
|
46
|
+
estimatedInputTokens,
|
|
45
47
|
savedTokens: source === 'provider-reported'
|
|
46
48
|
? providerSavings : report.cumulative.estimatedTransformSavingsTokens,
|
|
47
49
|
};
|
|
@@ -80,23 +82,10 @@ function compactTokens(value) {
|
|
|
80
82
|
return `${Number((value / 1_000_000).toFixed(2))}M`;
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|| !Number.isSafeInteger(providerUsage?.turnCount) || providerUsage.turnCount <= 0) return '🥪 —';
|
|
90
|
-
const parts = [
|
|
91
|
-
`${compactTokens(providerUsage.totalTokens)} provider tokens`,
|
|
92
|
-
compactTurns(providerUsage.turnCount),
|
|
93
|
-
];
|
|
94
|
-
if (Number.isFinite(providerUsage.weightedCostUnits) && providerUsage.weightedCostUnits >= 0) {
|
|
95
|
-
parts.push(`${compactTokens(Math.round(providerUsage.weightedCostUnits))} cost units`);
|
|
96
|
-
}
|
|
97
|
-
if (Number.isFinite(totalCostUsd) && totalCostUsd >= 0) {
|
|
98
|
-
const effectiveRate = totalCostUsd / providerUsage.totalTokens;
|
|
99
|
-
parts.push(`$${totalCostUsd.toFixed(2)}`, `$${(effectiveRate * 1_000_000).toFixed(2)}/M`);
|
|
100
|
-
}
|
|
101
|
-
return `🥪 ${parts.join(' · ')}`;
|
|
85
|
+
export function renderStatusLine({ metrics } = {}) {
|
|
86
|
+
if (!Number.isSafeInteger(metrics?.savedTokens) || metrics.savedTokens < 0
|
|
87
|
+
|| !Number.isSafeInteger(metrics?.estimatedInputTokens) || metrics.estimatedInputTokens <= 0) return '🥪 —';
|
|
88
|
+
const percentage = Math.round(metrics.savedTokens / metrics.estimatedInputTokens * 100);
|
|
89
|
+
const estimate = metrics.source === 'estimate' ? '~' : '';
|
|
90
|
+
return `🥪 saved ${estimate}${compactTokens(metrics.savedTokens)} ctx tok (${percentage}%)`;
|
|
102
91
|
}
|