@megasaver/cli 1.2.1 → 1.3.0
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/dist-bundle/mega.mjs +447 -261
- package/package.json +1 -1
package/dist-bundle/mega.mjs
CHANGED
|
@@ -14,9 +14,9 @@ import 'module';
|
|
|
14
14
|
import { homedir } from 'os';
|
|
15
15
|
import { access, mkdir, writeFile, lstat, readFile, constants, stat, rename, rm, chmod, readdir } from 'fs/promises';
|
|
16
16
|
import { execFileSync, spawn } from 'child_process';
|
|
17
|
+
import { once } from 'events';
|
|
17
18
|
import { createServer } from 'http';
|
|
18
19
|
import { StringDecoder } from 'string_decoder';
|
|
19
|
-
import { once } from 'events';
|
|
20
20
|
|
|
21
21
|
const require$1 = createRequire(import.meta.url);
|
|
22
22
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
@@ -234724,6 +234724,48 @@ function classifyObservation(input) {
|
|
|
234724
234724
|
const returnedTokens = eligibility === "eligible" ? input.returnedTokens : input.rawTokens;
|
|
234725
234725
|
return { rawTokens: input.rawTokens, returnedTokens, eligibility, mediation: input.mediation };
|
|
234726
234726
|
}
|
|
234727
|
+
function sumBytesSavedSince(events, sinceMs) {
|
|
234728
|
+
let total = 0;
|
|
234729
|
+
for (const e2 of events) {
|
|
234730
|
+
const t2 = Date.parse(e2.createdAt);
|
|
234731
|
+
if (Number.isFinite(t2) && t2 >= sinceMs && Number.isFinite(e2.bytesSaved)) {
|
|
234732
|
+
total += e2.bytesSaved;
|
|
234733
|
+
}
|
|
234734
|
+
}
|
|
234735
|
+
return total;
|
|
234736
|
+
}
|
|
234737
|
+
function proxyUsageSavings(input) {
|
|
234738
|
+
const saved = Math.max(0, Math.round(input.savedTokens));
|
|
234739
|
+
let inputTokens = 0;
|
|
234740
|
+
let outputTokens = 0;
|
|
234741
|
+
let cacheReadTokens = 0;
|
|
234742
|
+
let cacheCreationTokens = 0;
|
|
234743
|
+
for (const u3 of input.usage) {
|
|
234744
|
+
inputTokens += u3.inputTokens;
|
|
234745
|
+
outputTokens += u3.outputTokens;
|
|
234746
|
+
cacheReadTokens += u3.cacheReadTokens;
|
|
234747
|
+
cacheCreationTokens += u3.cacheCreationTokens;
|
|
234748
|
+
}
|
|
234749
|
+
const newContextTokens = inputTokens + cacheCreationTokens;
|
|
234750
|
+
const totalContextTokens = newContextTokens + cacheReadTokens;
|
|
234751
|
+
const shareOf = (actual) => {
|
|
234752
|
+
const wouldHave = saved + actual;
|
|
234753
|
+
return wouldHave === 0 ? 0 : saved / wouldHave;
|
|
234754
|
+
};
|
|
234755
|
+
return {
|
|
234756
|
+
savedTokens: saved,
|
|
234757
|
+
proxyCalls: input.usage.length,
|
|
234758
|
+
inputTokens,
|
|
234759
|
+
cacheCreationTokens,
|
|
234760
|
+
cacheReadTokens,
|
|
234761
|
+
outputTokens,
|
|
234762
|
+
newContextTokens,
|
|
234763
|
+
totalContextTokens,
|
|
234764
|
+
savedShareOfNewContext: shareOf(newContextTokens),
|
|
234765
|
+
savedShareOfTotalContext: shareOf(totalContextTokens),
|
|
234766
|
+
reliable: newContextTokens > 0 && saved <= newContextTokens
|
|
234767
|
+
};
|
|
234768
|
+
}
|
|
234727
234769
|
|
|
234728
234770
|
// ../../packages/content-store/dist/index.js
|
|
234729
234771
|
init_dist();
|
|
@@ -240563,18 +240605,413 @@ var auditSessionCommand = defineCommand({
|
|
|
240563
240605
|
}
|
|
240564
240606
|
});
|
|
240565
240607
|
|
|
240608
|
+
// ../../packages/llm-proxy/dist/index.js
|
|
240609
|
+
init_zod();
|
|
240610
|
+
var proxyUsageEventSchema = external_exports.object({
|
|
240611
|
+
id: external_exports.string().min(1),
|
|
240612
|
+
ts: external_exports.string().datetime({ offset: true }),
|
|
240613
|
+
model: external_exports.string(),
|
|
240614
|
+
inputTokens: external_exports.number().int().nonnegative(),
|
|
240615
|
+
outputTokens: external_exports.number().int().nonnegative(),
|
|
240616
|
+
cacheReadTokens: external_exports.number().int().nonnegative(),
|
|
240617
|
+
cacheCreationTokens: external_exports.number().int().nonnegative(),
|
|
240618
|
+
messageCount: external_exports.number().int().nonnegative(),
|
|
240619
|
+
stream: external_exports.boolean()
|
|
240620
|
+
}).strict();
|
|
240621
|
+
function asObject(value) {
|
|
240622
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
240623
|
+
}
|
|
240624
|
+
function int(value) {
|
|
240625
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
240626
|
+
}
|
|
240627
|
+
function parseJson2(text) {
|
|
240628
|
+
try {
|
|
240629
|
+
return JSON.parse(text);
|
|
240630
|
+
} catch {
|
|
240631
|
+
return null;
|
|
240632
|
+
}
|
|
240633
|
+
}
|
|
240634
|
+
function usageFromRaw(usage) {
|
|
240635
|
+
return {
|
|
240636
|
+
inputTokens: int(usage.input_tokens),
|
|
240637
|
+
outputTokens: int(usage.output_tokens),
|
|
240638
|
+
cacheReadTokens: int(usage.cache_read_input_tokens),
|
|
240639
|
+
cacheCreationTokens: int(usage.cache_creation_input_tokens)
|
|
240640
|
+
};
|
|
240641
|
+
}
|
|
240642
|
+
function countRequestMessages(bodyText) {
|
|
240643
|
+
const obj = asObject(parseJson2(bodyText));
|
|
240644
|
+
if (obj === null) return { model: "", messageCount: 0 };
|
|
240645
|
+
const model = typeof obj.model === "string" ? obj.model : "";
|
|
240646
|
+
const messageCount = Array.isArray(obj.messages) ? obj.messages.length : 0;
|
|
240647
|
+
return { model, messageCount };
|
|
240648
|
+
}
|
|
240649
|
+
function parseUsageFromJson(bodyText) {
|
|
240650
|
+
const obj = asObject(parseJson2(bodyText));
|
|
240651
|
+
const usage = obj && asObject(obj.usage);
|
|
240652
|
+
return usage ? usageFromRaw(usage) : null;
|
|
240653
|
+
}
|
|
240654
|
+
function consumeSseLine(line2, acc) {
|
|
240655
|
+
const trimmed = line2.trim();
|
|
240656
|
+
if (!trimmed.startsWith("data:")) return false;
|
|
240657
|
+
const payload = trimmed.slice("data:".length).trim();
|
|
240658
|
+
if (payload.length === 0 || payload === "[DONE]") return false;
|
|
240659
|
+
const event = asObject(parseJson2(payload));
|
|
240660
|
+
if (event === null) return false;
|
|
240661
|
+
if (event.type === "message_start") {
|
|
240662
|
+
const message = asObject(event.message);
|
|
240663
|
+
const usage = message && asObject(message.usage);
|
|
240664
|
+
if (usage) {
|
|
240665
|
+
const u3 = usageFromRaw(usage);
|
|
240666
|
+
acc.inputTokens = u3.inputTokens;
|
|
240667
|
+
acc.cacheReadTokens = u3.cacheReadTokens;
|
|
240668
|
+
acc.cacheCreationTokens = u3.cacheCreationTokens;
|
|
240669
|
+
acc.outputTokens = u3.outputTokens;
|
|
240670
|
+
return true;
|
|
240671
|
+
}
|
|
240672
|
+
} else if (event.type === "message_delta") {
|
|
240673
|
+
const usage = asObject(event.usage);
|
|
240674
|
+
if (usage) {
|
|
240675
|
+
acc.outputTokens = int(usage.output_tokens);
|
|
240676
|
+
return true;
|
|
240677
|
+
}
|
|
240678
|
+
}
|
|
240679
|
+
return false;
|
|
240680
|
+
}
|
|
240681
|
+
function createSseUsageScanner() {
|
|
240682
|
+
let leftover = "";
|
|
240683
|
+
let seen = false;
|
|
240684
|
+
const acc = {
|
|
240685
|
+
inputTokens: 0,
|
|
240686
|
+
outputTokens: 0,
|
|
240687
|
+
cacheReadTokens: 0,
|
|
240688
|
+
cacheCreationTokens: 0
|
|
240689
|
+
};
|
|
240690
|
+
return {
|
|
240691
|
+
push(chunk) {
|
|
240692
|
+
leftover += chunk;
|
|
240693
|
+
const lines = leftover.split("\n");
|
|
240694
|
+
leftover = lines.pop() ?? "";
|
|
240695
|
+
for (const line2 of lines) {
|
|
240696
|
+
if (consumeSseLine(line2, acc)) seen = true;
|
|
240697
|
+
}
|
|
240698
|
+
},
|
|
240699
|
+
result() {
|
|
240700
|
+
if (leftover.length > 0 && consumeSseLine(leftover, acc)) seen = true;
|
|
240701
|
+
leftover = "";
|
|
240702
|
+
return seen ? acc : null;
|
|
240703
|
+
}
|
|
240704
|
+
};
|
|
240705
|
+
}
|
|
240706
|
+
var STRIP_REQUEST = /* @__PURE__ */ new Set([
|
|
240707
|
+
"host",
|
|
240708
|
+
"connection",
|
|
240709
|
+
"content-length",
|
|
240710
|
+
"transfer-encoding",
|
|
240711
|
+
"keep-alive",
|
|
240712
|
+
"proxy-connection"
|
|
240713
|
+
]);
|
|
240714
|
+
var STRIP_RESPONSE = /* @__PURE__ */ new Set([
|
|
240715
|
+
"content-encoding",
|
|
240716
|
+
"content-length",
|
|
240717
|
+
"transfer-encoding",
|
|
240718
|
+
"connection"
|
|
240719
|
+
]);
|
|
240720
|
+
var MAX_JSON_CAPTURE_BYTES = 5e6;
|
|
240721
|
+
var MAX_REQUEST_BYTES = 5e7;
|
|
240722
|
+
async function readBody(req) {
|
|
240723
|
+
const chunks = [];
|
|
240724
|
+
let total = 0;
|
|
240725
|
+
for await (const chunk of req) {
|
|
240726
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
240727
|
+
total += buf.length;
|
|
240728
|
+
if (total > MAX_REQUEST_BYTES) return null;
|
|
240729
|
+
chunks.push(buf);
|
|
240730
|
+
}
|
|
240731
|
+
return Buffer.concat(chunks);
|
|
240732
|
+
}
|
|
240733
|
+
function filterRequestHeaders(headers) {
|
|
240734
|
+
const out = {};
|
|
240735
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
240736
|
+
if (value === void 0 || STRIP_REQUEST.has(key.toLowerCase())) continue;
|
|
240737
|
+
out[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
240738
|
+
}
|
|
240739
|
+
return out;
|
|
240740
|
+
}
|
|
240741
|
+
function responseHeaders(headers) {
|
|
240742
|
+
const out = {};
|
|
240743
|
+
headers.forEach((value, key) => {
|
|
240744
|
+
if (!STRIP_RESPONSE.has(key.toLowerCase())) out[key] = value;
|
|
240745
|
+
});
|
|
240746
|
+
return out;
|
|
240747
|
+
}
|
|
240748
|
+
function createProxyHandler(deps) {
|
|
240749
|
+
const { upstreamBaseUrl, onUsage, now, newId } = deps;
|
|
240750
|
+
const doFetch = deps.upstreamFetch ?? fetch;
|
|
240751
|
+
return async (req, res) => {
|
|
240752
|
+
const path2 = req.url ?? "/";
|
|
240753
|
+
const method = req.method ?? "GET";
|
|
240754
|
+
const bodyBuf = await readBody(req);
|
|
240755
|
+
if (bodyBuf === null) {
|
|
240756
|
+
res.writeHead(413, { "content-type": "text/plain; charset=utf-8" });
|
|
240757
|
+
res.end("mega proxy: request body too large");
|
|
240758
|
+
return;
|
|
240759
|
+
}
|
|
240760
|
+
const headers = filterRequestHeaders(req.headers);
|
|
240761
|
+
const init2 = bodyBuf.length > 0 ? { method, headers, body: bodyBuf } : { method, headers };
|
|
240762
|
+
let upstream;
|
|
240763
|
+
try {
|
|
240764
|
+
upstream = await doFetch(`${upstreamBaseUrl}${path2}`, init2);
|
|
240765
|
+
} catch {
|
|
240766
|
+
res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
|
|
240767
|
+
res.end("mega proxy: upstream request failed");
|
|
240768
|
+
return;
|
|
240769
|
+
}
|
|
240770
|
+
const respHeaders = responseHeaders(upstream.headers);
|
|
240771
|
+
res.writeHead(upstream.status, respHeaders);
|
|
240772
|
+
const contentType = String(respHeaders["content-type"] ?? "");
|
|
240773
|
+
const stream = contentType.includes("event-stream");
|
|
240774
|
+
const scanner = stream ? createSseUsageScanner() : null;
|
|
240775
|
+
const decoder = new TextDecoder();
|
|
240776
|
+
const jsonCaptured = [];
|
|
240777
|
+
let jsonLen = 0;
|
|
240778
|
+
if (upstream.body) {
|
|
240779
|
+
const reader = upstream.body.getReader();
|
|
240780
|
+
for (; ; ) {
|
|
240781
|
+
const { done, value } = await reader.read();
|
|
240782
|
+
if (done) break;
|
|
240783
|
+
const buf = Buffer.from(value);
|
|
240784
|
+
if (!res.write(buf)) await once(res, "drain");
|
|
240785
|
+
if (scanner) {
|
|
240786
|
+
scanner.push(decoder.decode(value, { stream: true }));
|
|
240787
|
+
} else if (jsonLen < MAX_JSON_CAPTURE_BYTES) {
|
|
240788
|
+
jsonCaptured.push(buf);
|
|
240789
|
+
jsonLen += buf.length;
|
|
240790
|
+
}
|
|
240791
|
+
}
|
|
240792
|
+
}
|
|
240793
|
+
res.end();
|
|
240794
|
+
try {
|
|
240795
|
+
if (method === "POST" && path2.startsWith("/v1/messages") && onUsage) {
|
|
240796
|
+
const { model, messageCount } = countRequestMessages(bodyBuf.toString("utf8"));
|
|
240797
|
+
const usage = scanner ? scanner.result() : parseUsageFromJson(Buffer.concat(jsonCaptured).toString("utf8"));
|
|
240798
|
+
if (usage) {
|
|
240799
|
+
onUsage({
|
|
240800
|
+
id: newId(),
|
|
240801
|
+
ts: now(),
|
|
240802
|
+
model,
|
|
240803
|
+
inputTokens: usage.inputTokens,
|
|
240804
|
+
outputTokens: usage.outputTokens,
|
|
240805
|
+
cacheReadTokens: usage.cacheReadTokens,
|
|
240806
|
+
cacheCreationTokens: usage.cacheCreationTokens,
|
|
240807
|
+
messageCount,
|
|
240808
|
+
stream
|
|
240809
|
+
});
|
|
240810
|
+
}
|
|
240811
|
+
}
|
|
240812
|
+
} catch {
|
|
240813
|
+
}
|
|
240814
|
+
};
|
|
240815
|
+
}
|
|
240816
|
+
var LOOPBACK_HOST = "127.0.0.1";
|
|
240817
|
+
function startProxyServer(opts) {
|
|
240818
|
+
const host = LOOPBACK_HOST;
|
|
240819
|
+
const handler = createProxyHandler({
|
|
240820
|
+
upstreamBaseUrl: opts.upstreamBaseUrl,
|
|
240821
|
+
...opts.upstreamFetch ? { upstreamFetch: opts.upstreamFetch } : {},
|
|
240822
|
+
...opts.onUsage ? { onUsage: opts.onUsage } : {},
|
|
240823
|
+
now: opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()),
|
|
240824
|
+
newId: opts.newId ?? (() => randomUUID())
|
|
240825
|
+
});
|
|
240826
|
+
const server2 = createServer((req, res) => {
|
|
240827
|
+
void handler(req, res).catch(() => {
|
|
240828
|
+
if (!res.headersSent) res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
|
|
240829
|
+
res.end();
|
|
240830
|
+
});
|
|
240831
|
+
});
|
|
240832
|
+
return new Promise((resolve8, reject) => {
|
|
240833
|
+
server2.once("error", reject);
|
|
240834
|
+
server2.listen(opts.port, host, () => {
|
|
240835
|
+
server2.removeListener("error", reject);
|
|
240836
|
+
const addr = server2.address();
|
|
240837
|
+
const port = typeof addr === "object" && addr !== null ? addr.port : opts.port;
|
|
240838
|
+
resolve8({
|
|
240839
|
+
url: `http://${host}:${port}`,
|
|
240840
|
+
port,
|
|
240841
|
+
close: () => new Promise((res) => {
|
|
240842
|
+
server2.close(() => res());
|
|
240843
|
+
})
|
|
240844
|
+
});
|
|
240845
|
+
});
|
|
240846
|
+
});
|
|
240847
|
+
}
|
|
240848
|
+
function usagePath(storeRoot) {
|
|
240849
|
+
return join(storeRoot, "proxy-usage", "usage.jsonl");
|
|
240850
|
+
}
|
|
240851
|
+
function isErrno5(e2) {
|
|
240852
|
+
return e2 instanceof Error && "code" in e2;
|
|
240853
|
+
}
|
|
240854
|
+
async function appendProxyUsage(input) {
|
|
240855
|
+
const event = proxyUsageEventSchema.parse(input.event);
|
|
240856
|
+
const path2 = usagePath(input.storeRoot);
|
|
240857
|
+
mkdirSync(dirname$1(path2), { recursive: true });
|
|
240858
|
+
appendFileSync(path2, `${JSON.stringify(event)}
|
|
240859
|
+
`);
|
|
240860
|
+
}
|
|
240861
|
+
async function listProxyUsage(input) {
|
|
240862
|
+
let raw;
|
|
240863
|
+
try {
|
|
240864
|
+
raw = readFileSync(usagePath(input.storeRoot), "utf8");
|
|
240865
|
+
} catch (e2) {
|
|
240866
|
+
if (isErrno5(e2) && e2.code === "ENOENT") return [];
|
|
240867
|
+
throw e2;
|
|
240868
|
+
}
|
|
240869
|
+
const out = [];
|
|
240870
|
+
for (const line2 of raw.split("\n")) {
|
|
240871
|
+
const trimmed = line2.trim();
|
|
240872
|
+
if (trimmed.length === 0) continue;
|
|
240873
|
+
out.push(proxyUsageEventSchema.parse(JSON.parse(trimmed)));
|
|
240874
|
+
}
|
|
240875
|
+
return out;
|
|
240876
|
+
}
|
|
240877
|
+
|
|
240878
|
+
// src/commands/audit/usage.ts
|
|
240879
|
+
init_dist();
|
|
240880
|
+
function readWorkspaceSavedTokensSince(storeRoot, workspaceKey, sinceMs) {
|
|
240881
|
+
const dir = join(storeRoot, "stats", workspaceKey);
|
|
240882
|
+
let names;
|
|
240883
|
+
try {
|
|
240884
|
+
names = readdirSync(dir);
|
|
240885
|
+
} catch {
|
|
240886
|
+
return 0;
|
|
240887
|
+
}
|
|
240888
|
+
const events = [];
|
|
240889
|
+
for (const name of names) {
|
|
240890
|
+
if (!name.endsWith(".events.jsonl")) continue;
|
|
240891
|
+
let raw;
|
|
240892
|
+
try {
|
|
240893
|
+
raw = readFileSync(join(dir, name), "utf8");
|
|
240894
|
+
} catch {
|
|
240895
|
+
continue;
|
|
240896
|
+
}
|
|
240897
|
+
for (const line2 of raw.split("\n")) {
|
|
240898
|
+
const trimmed = line2.trim();
|
|
240899
|
+
if (trimmed.length === 0) continue;
|
|
240900
|
+
let ev;
|
|
240901
|
+
try {
|
|
240902
|
+
ev = JSON.parse(trimmed);
|
|
240903
|
+
} catch {
|
|
240904
|
+
continue;
|
|
240905
|
+
}
|
|
240906
|
+
if (typeof ev === "object" && ev !== null && typeof ev.createdAt === "string" && typeof ev.bytesSaved === "number") {
|
|
240907
|
+
const e2 = ev;
|
|
240908
|
+
events.push({ createdAt: e2.createdAt, bytesSaved: e2.bytesSaved });
|
|
240909
|
+
}
|
|
240910
|
+
}
|
|
240911
|
+
}
|
|
240912
|
+
return tokensFromBytes(sumBytesSavedSince(events, sinceMs));
|
|
240913
|
+
}
|
|
240914
|
+
function renderUsageReport(m2) {
|
|
240915
|
+
const pct = (n3) => `${(n3 * 100).toFixed(1)}%`;
|
|
240916
|
+
const n2 = (x2) => x2.toLocaleString("en-US");
|
|
240917
|
+
if (m2.proxyCalls === 0) {
|
|
240918
|
+
return [
|
|
240919
|
+
"No proxy usage recorded yet.",
|
|
240920
|
+
"Run `mega proxy start`, point your agent at it (export ANTHROPIC_BASE_URL),",
|
|
240921
|
+
"then this reports savings against your real Claude token usage."
|
|
240922
|
+
].join("\n");
|
|
240923
|
+
}
|
|
240924
|
+
const rawLines = [
|
|
240925
|
+
`saved (tool output): ~${n2(m2.savedTokens)} tokens (est, bytes/4)`,
|
|
240926
|
+
`real new context: ${n2(m2.newContextTokens)} tokens (input + cache-creation)`,
|
|
240927
|
+
`real cache re-reads: ${n2(m2.cacheReadTokens)} tokens`,
|
|
240928
|
+
`real output: ${n2(m2.outputTokens)} tokens`,
|
|
240929
|
+
`proxy calls: ${n2(m2.proxyCalls)}`
|
|
240930
|
+
];
|
|
240931
|
+
if (!m2.reliable) {
|
|
240932
|
+
return [
|
|
240933
|
+
...rawLines,
|
|
240934
|
+
"",
|
|
240935
|
+
"% suppressed: not enough matched proxy coverage for a trustworthy ratio",
|
|
240936
|
+
"(tokens saved exceed the new context the proxy measured \u2014 the proxy saw only",
|
|
240937
|
+
"part of your traffic, so any % would overstate the saving). Route your agent",
|
|
240938
|
+
"through `mega proxy` for your whole workload, then re-run for a real figure."
|
|
240939
|
+
].join("\n");
|
|
240940
|
+
}
|
|
240941
|
+
return [
|
|
240942
|
+
...rawLines,
|
|
240943
|
+
"",
|
|
240944
|
+
`saved of new context: ${pct(m2.savedShareOfNewContext)} (saved / (saved + new context))`,
|
|
240945
|
+
`saved of total processed: ${pct(m2.savedShareOfTotalContext)} (adds cache re-reads)`,
|
|
240946
|
+
"",
|
|
240947
|
+
"Scope: savings are windowed to the period since your first recorded proxy",
|
|
240948
|
+
"call, to match the usage denominator. One-shot estimate (a floor): a saved",
|
|
240949
|
+
"token also avoids cache re-reads on every later turn, so real impact is larger."
|
|
240950
|
+
].join("\n");
|
|
240951
|
+
}
|
|
240952
|
+
async function runAuditUsage(input) {
|
|
240953
|
+
const workspaceKey = encodeWorkspaceKey(input.cwd);
|
|
240954
|
+
const readSaved = input.readSaved ?? readWorkspaceSavedTokensSince;
|
|
240955
|
+
const listUsage = input.listUsage ?? listProxyUsage;
|
|
240956
|
+
let usage = [];
|
|
240957
|
+
try {
|
|
240958
|
+
usage = await listUsage({ storeRoot: input.storeRoot });
|
|
240959
|
+
} catch {
|
|
240960
|
+
}
|
|
240961
|
+
const sinceMs = usage.reduce((min, u3) => {
|
|
240962
|
+
const t2 = Date.parse(u3.ts);
|
|
240963
|
+
return Number.isFinite(t2) ? Math.min(min, t2) : min;
|
|
240964
|
+
}, Number.POSITIVE_INFINITY);
|
|
240965
|
+
let savedTokens = 0;
|
|
240966
|
+
if (usage.length > 0) {
|
|
240967
|
+
try {
|
|
240968
|
+
savedTokens = readSaved(input.storeRoot, workspaceKey, sinceMs);
|
|
240969
|
+
} catch {
|
|
240970
|
+
}
|
|
240971
|
+
}
|
|
240972
|
+
const savings = proxyUsageSavings({ savedTokens, usage });
|
|
240973
|
+
return input.json ? JSON.stringify(savings) : renderUsageReport(savings);
|
|
240974
|
+
}
|
|
240975
|
+
var auditUsageCommand = defineCommand({
|
|
240976
|
+
meta: {
|
|
240977
|
+
name: "usage",
|
|
240978
|
+
description: "Estimated savings vs your real total Claude usage (needs `mega proxy`)."
|
|
240979
|
+
},
|
|
240980
|
+
args: {
|
|
240981
|
+
store: { type: "string", description: "Override store directory." },
|
|
240982
|
+
json: { type: "boolean", default: false, description: "Emit JSON output." }
|
|
240983
|
+
},
|
|
240984
|
+
async run({ args }) {
|
|
240985
|
+
const storeEnv = readStoreEnv(typeof args.store === "string" ? args.store : void 0);
|
|
240986
|
+
let storeRoot;
|
|
240987
|
+
try {
|
|
240988
|
+
storeRoot = resolveStorePath(storeEnv);
|
|
240989
|
+
} catch {
|
|
240990
|
+
storeRoot = "";
|
|
240991
|
+
}
|
|
240992
|
+
const out = await runAuditUsage({
|
|
240993
|
+
storeRoot,
|
|
240994
|
+
cwd: process.cwd(),
|
|
240995
|
+
json: args.json ?? false
|
|
240996
|
+
});
|
|
240997
|
+
process.stdout.write(`${out}
|
|
240998
|
+
`);
|
|
240999
|
+
}
|
|
241000
|
+
});
|
|
241001
|
+
|
|
240566
241002
|
// src/commands/audit/index.ts
|
|
240567
241003
|
var auditCommand = defineCommand({
|
|
240568
241004
|
meta: {
|
|
240569
241005
|
name: "audit",
|
|
240570
|
-
description: "Token-savings dashboard: report, last, session, export, honest."
|
|
241006
|
+
description: "Token-savings dashboard: report, last, session, export, honest, usage."
|
|
240571
241007
|
},
|
|
240572
241008
|
subCommands: {
|
|
240573
241009
|
report: auditReportCommand,
|
|
240574
241010
|
last: auditLastCommand,
|
|
240575
241011
|
session: auditSessionCommand,
|
|
240576
241012
|
export: auditExportCommand,
|
|
240577
|
-
honest: auditHonestCommand
|
|
241013
|
+
honest: auditHonestCommand,
|
|
241014
|
+
usage: auditUsageCommand
|
|
240578
241015
|
}
|
|
240579
241016
|
});
|
|
240580
241017
|
|
|
@@ -242788,20 +243225,20 @@ var TOOL_CATEGORY = {
|
|
|
242788
243225
|
};
|
|
242789
243226
|
new Set(Object.keys(TOOL_CATEGORY));
|
|
242790
243227
|
var HOOK_LOG_RELATIVE_PATH = join(".megasaver", "hooks", "claude-tool-calls.jsonl");
|
|
242791
|
-
function
|
|
243228
|
+
function asObject2(value) {
|
|
242792
243229
|
return typeof value === "object" && value !== null ? value : null;
|
|
242793
243230
|
}
|
|
242794
243231
|
function asString(value) {
|
|
242795
243232
|
return typeof value === "string" ? value : void 0;
|
|
242796
243233
|
}
|
|
242797
243234
|
function buildHookLine(payload, now) {
|
|
242798
|
-
const record2 =
|
|
243235
|
+
const record2 = asObject2(payload);
|
|
242799
243236
|
if (record2 === null) return null;
|
|
242800
243237
|
const tool = asString(record2.tool_name);
|
|
242801
243238
|
if (tool === void 0) return null;
|
|
242802
243239
|
const category = TOOL_CATEGORY[tool];
|
|
242803
243240
|
if (category === void 0) return null;
|
|
242804
|
-
const input =
|
|
243241
|
+
const input = asObject2(record2.tool_input);
|
|
242805
243242
|
const filePath = input ? asString(input.file_path) ?? asString(input.path) : void 0;
|
|
242806
243243
|
const sessionId = asString(record2.session_id);
|
|
242807
243244
|
const line2 = {
|
|
@@ -247502,8 +247939,8 @@ var ZodNumber2 = /* @__PURE__ */ $constructor("ZodNumber", (inst, def) => {
|
|
|
247502
247939
|
inst.lt = (value, params) => inst.check(_lt(value, params));
|
|
247503
247940
|
inst.lte = (value, params) => inst.check(_lte(value, params));
|
|
247504
247941
|
inst.max = (value, params) => inst.check(_lte(value, params));
|
|
247505
|
-
inst.int = (params) => inst.check(
|
|
247506
|
-
inst.safe = (params) => inst.check(
|
|
247942
|
+
inst.int = (params) => inst.check(int2(params));
|
|
247943
|
+
inst.safe = (params) => inst.check(int2(params));
|
|
247507
247944
|
inst.positive = (params) => inst.check(_gt(0, params));
|
|
247508
247945
|
inst.nonnegative = (params) => inst.check(_gte(0, params));
|
|
247509
247946
|
inst.negative = (params) => inst.check(_lt(0, params));
|
|
@@ -247525,7 +247962,7 @@ var ZodNumberFormat = /* @__PURE__ */ $constructor("ZodNumberFormat", (inst, def
|
|
|
247525
247962
|
$ZodNumberFormat.init(inst, def);
|
|
247526
247963
|
ZodNumber2.init(inst, def);
|
|
247527
247964
|
});
|
|
247528
|
-
function
|
|
247965
|
+
function int2(params) {
|
|
247529
247966
|
return _int(ZodNumberFormat, params);
|
|
247530
247967
|
}
|
|
247531
247968
|
var ZodBoolean2 = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
|
|
@@ -257154,257 +257591,6 @@ var projectCommand = defineCommand({
|
|
|
257154
257591
|
}
|
|
257155
257592
|
});
|
|
257156
257593
|
|
|
257157
|
-
// ../../packages/llm-proxy/dist/index.js
|
|
257158
|
-
init_zod();
|
|
257159
|
-
var proxyUsageEventSchema = external_exports.object({
|
|
257160
|
-
id: external_exports.string().min(1),
|
|
257161
|
-
ts: external_exports.string().datetime({ offset: true }),
|
|
257162
|
-
model: external_exports.string(),
|
|
257163
|
-
inputTokens: external_exports.number().int().nonnegative(),
|
|
257164
|
-
outputTokens: external_exports.number().int().nonnegative(),
|
|
257165
|
-
cacheReadTokens: external_exports.number().int().nonnegative(),
|
|
257166
|
-
cacheCreationTokens: external_exports.number().int().nonnegative(),
|
|
257167
|
-
messageCount: external_exports.number().int().nonnegative(),
|
|
257168
|
-
stream: external_exports.boolean()
|
|
257169
|
-
}).strict();
|
|
257170
|
-
function asObject2(value) {
|
|
257171
|
-
return typeof value === "object" && value !== null ? value : null;
|
|
257172
|
-
}
|
|
257173
|
-
function int2(value) {
|
|
257174
|
-
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
257175
|
-
}
|
|
257176
|
-
function parseJson2(text) {
|
|
257177
|
-
try {
|
|
257178
|
-
return JSON.parse(text);
|
|
257179
|
-
} catch {
|
|
257180
|
-
return null;
|
|
257181
|
-
}
|
|
257182
|
-
}
|
|
257183
|
-
function usageFromRaw(usage) {
|
|
257184
|
-
return {
|
|
257185
|
-
inputTokens: int2(usage.input_tokens),
|
|
257186
|
-
outputTokens: int2(usage.output_tokens),
|
|
257187
|
-
cacheReadTokens: int2(usage.cache_read_input_tokens),
|
|
257188
|
-
cacheCreationTokens: int2(usage.cache_creation_input_tokens)
|
|
257189
|
-
};
|
|
257190
|
-
}
|
|
257191
|
-
function countRequestMessages(bodyText) {
|
|
257192
|
-
const obj = asObject2(parseJson2(bodyText));
|
|
257193
|
-
if (obj === null) return { model: "", messageCount: 0 };
|
|
257194
|
-
const model = typeof obj.model === "string" ? obj.model : "";
|
|
257195
|
-
const messageCount = Array.isArray(obj.messages) ? obj.messages.length : 0;
|
|
257196
|
-
return { model, messageCount };
|
|
257197
|
-
}
|
|
257198
|
-
function parseUsageFromJson(bodyText) {
|
|
257199
|
-
const obj = asObject2(parseJson2(bodyText));
|
|
257200
|
-
const usage = obj && asObject2(obj.usage);
|
|
257201
|
-
return usage ? usageFromRaw(usage) : null;
|
|
257202
|
-
}
|
|
257203
|
-
function consumeSseLine(line2, acc) {
|
|
257204
|
-
const trimmed = line2.trim();
|
|
257205
|
-
if (!trimmed.startsWith("data:")) return false;
|
|
257206
|
-
const payload = trimmed.slice("data:".length).trim();
|
|
257207
|
-
if (payload.length === 0 || payload === "[DONE]") return false;
|
|
257208
|
-
const event = asObject2(parseJson2(payload));
|
|
257209
|
-
if (event === null) return false;
|
|
257210
|
-
if (event.type === "message_start") {
|
|
257211
|
-
const message = asObject2(event.message);
|
|
257212
|
-
const usage = message && asObject2(message.usage);
|
|
257213
|
-
if (usage) {
|
|
257214
|
-
const u3 = usageFromRaw(usage);
|
|
257215
|
-
acc.inputTokens = u3.inputTokens;
|
|
257216
|
-
acc.cacheReadTokens = u3.cacheReadTokens;
|
|
257217
|
-
acc.cacheCreationTokens = u3.cacheCreationTokens;
|
|
257218
|
-
acc.outputTokens = u3.outputTokens;
|
|
257219
|
-
return true;
|
|
257220
|
-
}
|
|
257221
|
-
} else if (event.type === "message_delta") {
|
|
257222
|
-
const usage = asObject2(event.usage);
|
|
257223
|
-
if (usage) {
|
|
257224
|
-
acc.outputTokens = int2(usage.output_tokens);
|
|
257225
|
-
return true;
|
|
257226
|
-
}
|
|
257227
|
-
}
|
|
257228
|
-
return false;
|
|
257229
|
-
}
|
|
257230
|
-
function createSseUsageScanner() {
|
|
257231
|
-
let leftover = "";
|
|
257232
|
-
let seen = false;
|
|
257233
|
-
const acc = {
|
|
257234
|
-
inputTokens: 0,
|
|
257235
|
-
outputTokens: 0,
|
|
257236
|
-
cacheReadTokens: 0,
|
|
257237
|
-
cacheCreationTokens: 0
|
|
257238
|
-
};
|
|
257239
|
-
return {
|
|
257240
|
-
push(chunk) {
|
|
257241
|
-
leftover += chunk;
|
|
257242
|
-
const lines = leftover.split("\n");
|
|
257243
|
-
leftover = lines.pop() ?? "";
|
|
257244
|
-
for (const line2 of lines) {
|
|
257245
|
-
if (consumeSseLine(line2, acc)) seen = true;
|
|
257246
|
-
}
|
|
257247
|
-
},
|
|
257248
|
-
result() {
|
|
257249
|
-
if (leftover.length > 0 && consumeSseLine(leftover, acc)) seen = true;
|
|
257250
|
-
leftover = "";
|
|
257251
|
-
return seen ? acc : null;
|
|
257252
|
-
}
|
|
257253
|
-
};
|
|
257254
|
-
}
|
|
257255
|
-
var STRIP_REQUEST = /* @__PURE__ */ new Set([
|
|
257256
|
-
"host",
|
|
257257
|
-
"connection",
|
|
257258
|
-
"content-length",
|
|
257259
|
-
"transfer-encoding",
|
|
257260
|
-
"keep-alive",
|
|
257261
|
-
"proxy-connection"
|
|
257262
|
-
]);
|
|
257263
|
-
var STRIP_RESPONSE = /* @__PURE__ */ new Set([
|
|
257264
|
-
"content-encoding",
|
|
257265
|
-
"content-length",
|
|
257266
|
-
"transfer-encoding",
|
|
257267
|
-
"connection"
|
|
257268
|
-
]);
|
|
257269
|
-
var MAX_JSON_CAPTURE_BYTES = 5e6;
|
|
257270
|
-
var MAX_REQUEST_BYTES = 5e7;
|
|
257271
|
-
async function readBody(req) {
|
|
257272
|
-
const chunks = [];
|
|
257273
|
-
let total = 0;
|
|
257274
|
-
for await (const chunk of req) {
|
|
257275
|
-
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
257276
|
-
total += buf.length;
|
|
257277
|
-
if (total > MAX_REQUEST_BYTES) return null;
|
|
257278
|
-
chunks.push(buf);
|
|
257279
|
-
}
|
|
257280
|
-
return Buffer.concat(chunks);
|
|
257281
|
-
}
|
|
257282
|
-
function filterRequestHeaders(headers) {
|
|
257283
|
-
const out = {};
|
|
257284
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
257285
|
-
if (value === void 0 || STRIP_REQUEST.has(key.toLowerCase())) continue;
|
|
257286
|
-
out[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
257287
|
-
}
|
|
257288
|
-
return out;
|
|
257289
|
-
}
|
|
257290
|
-
function responseHeaders(headers) {
|
|
257291
|
-
const out = {};
|
|
257292
|
-
headers.forEach((value, key) => {
|
|
257293
|
-
if (!STRIP_RESPONSE.has(key.toLowerCase())) out[key] = value;
|
|
257294
|
-
});
|
|
257295
|
-
return out;
|
|
257296
|
-
}
|
|
257297
|
-
function createProxyHandler(deps) {
|
|
257298
|
-
const { upstreamBaseUrl, onUsage, now, newId } = deps;
|
|
257299
|
-
const doFetch = deps.upstreamFetch ?? fetch;
|
|
257300
|
-
return async (req, res) => {
|
|
257301
|
-
const path2 = req.url ?? "/";
|
|
257302
|
-
const method = req.method ?? "GET";
|
|
257303
|
-
const bodyBuf = await readBody(req);
|
|
257304
|
-
if (bodyBuf === null) {
|
|
257305
|
-
res.writeHead(413, { "content-type": "text/plain; charset=utf-8" });
|
|
257306
|
-
res.end("mega proxy: request body too large");
|
|
257307
|
-
return;
|
|
257308
|
-
}
|
|
257309
|
-
const headers = filterRequestHeaders(req.headers);
|
|
257310
|
-
const init2 = bodyBuf.length > 0 ? { method, headers, body: bodyBuf } : { method, headers };
|
|
257311
|
-
let upstream;
|
|
257312
|
-
try {
|
|
257313
|
-
upstream = await doFetch(`${upstreamBaseUrl}${path2}`, init2);
|
|
257314
|
-
} catch {
|
|
257315
|
-
res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
|
|
257316
|
-
res.end("mega proxy: upstream request failed");
|
|
257317
|
-
return;
|
|
257318
|
-
}
|
|
257319
|
-
const respHeaders = responseHeaders(upstream.headers);
|
|
257320
|
-
res.writeHead(upstream.status, respHeaders);
|
|
257321
|
-
const contentType = String(respHeaders["content-type"] ?? "");
|
|
257322
|
-
const stream = contentType.includes("event-stream");
|
|
257323
|
-
const scanner = stream ? createSseUsageScanner() : null;
|
|
257324
|
-
const decoder = new TextDecoder();
|
|
257325
|
-
const jsonCaptured = [];
|
|
257326
|
-
let jsonLen = 0;
|
|
257327
|
-
if (upstream.body) {
|
|
257328
|
-
const reader = upstream.body.getReader();
|
|
257329
|
-
for (; ; ) {
|
|
257330
|
-
const { done, value } = await reader.read();
|
|
257331
|
-
if (done) break;
|
|
257332
|
-
const buf = Buffer.from(value);
|
|
257333
|
-
if (!res.write(buf)) await once(res, "drain");
|
|
257334
|
-
if (scanner) {
|
|
257335
|
-
scanner.push(decoder.decode(value, { stream: true }));
|
|
257336
|
-
} else if (jsonLen < MAX_JSON_CAPTURE_BYTES) {
|
|
257337
|
-
jsonCaptured.push(buf);
|
|
257338
|
-
jsonLen += buf.length;
|
|
257339
|
-
}
|
|
257340
|
-
}
|
|
257341
|
-
}
|
|
257342
|
-
res.end();
|
|
257343
|
-
try {
|
|
257344
|
-
if (method === "POST" && path2.startsWith("/v1/messages") && onUsage) {
|
|
257345
|
-
const { model, messageCount } = countRequestMessages(bodyBuf.toString("utf8"));
|
|
257346
|
-
const usage = scanner ? scanner.result() : parseUsageFromJson(Buffer.concat(jsonCaptured).toString("utf8"));
|
|
257347
|
-
if (usage) {
|
|
257348
|
-
onUsage({
|
|
257349
|
-
id: newId(),
|
|
257350
|
-
ts: now(),
|
|
257351
|
-
model,
|
|
257352
|
-
inputTokens: usage.inputTokens,
|
|
257353
|
-
outputTokens: usage.outputTokens,
|
|
257354
|
-
cacheReadTokens: usage.cacheReadTokens,
|
|
257355
|
-
cacheCreationTokens: usage.cacheCreationTokens,
|
|
257356
|
-
messageCount,
|
|
257357
|
-
stream
|
|
257358
|
-
});
|
|
257359
|
-
}
|
|
257360
|
-
}
|
|
257361
|
-
} catch {
|
|
257362
|
-
}
|
|
257363
|
-
};
|
|
257364
|
-
}
|
|
257365
|
-
var LOOPBACK_HOST = "127.0.0.1";
|
|
257366
|
-
function startProxyServer(opts) {
|
|
257367
|
-
const host = LOOPBACK_HOST;
|
|
257368
|
-
const handler = createProxyHandler({
|
|
257369
|
-
upstreamBaseUrl: opts.upstreamBaseUrl,
|
|
257370
|
-
...opts.upstreamFetch ? { upstreamFetch: opts.upstreamFetch } : {},
|
|
257371
|
-
...opts.onUsage ? { onUsage: opts.onUsage } : {},
|
|
257372
|
-
now: opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()),
|
|
257373
|
-
newId: opts.newId ?? (() => randomUUID())
|
|
257374
|
-
});
|
|
257375
|
-
const server2 = createServer((req, res) => {
|
|
257376
|
-
void handler(req, res).catch(() => {
|
|
257377
|
-
if (!res.headersSent) res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
|
|
257378
|
-
res.end();
|
|
257379
|
-
});
|
|
257380
|
-
});
|
|
257381
|
-
return new Promise((resolve8, reject) => {
|
|
257382
|
-
server2.once("error", reject);
|
|
257383
|
-
server2.listen(opts.port, host, () => {
|
|
257384
|
-
server2.removeListener("error", reject);
|
|
257385
|
-
const addr = server2.address();
|
|
257386
|
-
const port = typeof addr === "object" && addr !== null ? addr.port : opts.port;
|
|
257387
|
-
resolve8({
|
|
257388
|
-
url: `http://${host}:${port}`,
|
|
257389
|
-
port,
|
|
257390
|
-
close: () => new Promise((res) => {
|
|
257391
|
-
server2.close(() => res());
|
|
257392
|
-
})
|
|
257393
|
-
});
|
|
257394
|
-
});
|
|
257395
|
-
});
|
|
257396
|
-
}
|
|
257397
|
-
function usagePath(storeRoot) {
|
|
257398
|
-
return join(storeRoot, "proxy-usage", "usage.jsonl");
|
|
257399
|
-
}
|
|
257400
|
-
async function appendProxyUsage(input) {
|
|
257401
|
-
const event = proxyUsageEventSchema.parse(input.event);
|
|
257402
|
-
const path2 = usagePath(input.storeRoot);
|
|
257403
|
-
mkdirSync(dirname$1(path2), { recursive: true });
|
|
257404
|
-
appendFileSync(path2, `${JSON.stringify(event)}
|
|
257405
|
-
`);
|
|
257406
|
-
}
|
|
257407
|
-
|
|
257408
257594
|
// src/commands/proxy/start.ts
|
|
257409
257595
|
var DEFAULT_PORT = 8787;
|
|
257410
257596
|
var DEFAULT_UPSTREAM = "https://api.anthropic.com";
|
|
@@ -259572,7 +259758,7 @@ var toolsCommand = defineCommand({
|
|
|
259572
259758
|
});
|
|
259573
259759
|
|
|
259574
259760
|
// src/main.ts
|
|
259575
|
-
var version2 = "1.
|
|
259761
|
+
var version2 = "1.3.0" ;
|
|
259576
259762
|
var mainCommand = defineCommand({
|
|
259577
259763
|
meta: {
|
|
259578
259764
|
name: "mega",
|