tokmon 0.28.1 → 0.28.3
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 +156 -234
- package/THIRD_PARTY_NOTICES.md +62 -0
- package/dist/{bootstrap-ink-L7QSJBMS.js → bootstrap-ink-WG4WG3R2.js} +1579 -1135
- package/dist/chunk-7CH6S7BR.js +447 -0
- package/dist/{chunk-CVKCVHS7.js → chunk-CFKUZCMB.js} +70 -310
- package/dist/chunk-HNWEJ6MS.js +1094 -0
- package/dist/chunk-JZSZEHVD.js +406 -0
- package/dist/{chunk-S33XIUAW.js → chunk-P57DVFNH.js} +277 -49
- package/dist/{chunk-4HU4EI5T.js → chunk-P5JN5DDX.js} +25 -46
- package/dist/chunk-TN6V7XSL.js +512 -0
- package/dist/chunk-USKOQIE3.js +278 -0
- package/dist/chunk-UYPDMVW5.js +21 -0
- package/dist/{cli-command-75LP4IDS.js → cli-command-MD3RJRP4.js} +249 -15
- package/dist/cli.js +6 -6
- package/dist/{config-HXFJTNLM.js → config-3DGZ47F7.js} +23 -3
- package/dist/daemon-EMOA36WB.js +377 -0
- package/dist/daemon-handle-JHE5MKMI.js +11 -0
- package/dist/server-EPSH52DR.js +12 -0
- package/dist/web/assets/{Area-CMXvOw33.js → Area-stRnp8Km.js} +1 -1
- package/dist/web/assets/analytics-moZZt9L_.js +2 -0
- package/dist/web/assets/breakdown-km9w7myU.js +4 -0
- package/dist/web/assets/button-DrX04Cc2.js +1 -0
- package/dist/web/assets/{chart-cZoLgpmG.js → chart-D0CtuL2k.js} +1 -1
- package/dist/web/assets/explore-B11uNJV1.js +22 -0
- package/dist/web/assets/index-RDhXsCNG.js +83 -0
- package/dist/web/assets/index-ZmOS8p9O.css +1 -0
- package/dist/web/assets/models-DYbZnY34.js +2 -0
- package/dist/web/assets/overview-CruICbfJ.js +2 -0
- package/dist/web/assets/panel-xckM3_GC.js +1 -0
- package/dist/web/assets/settings-sheet-G-BTSIF6.js +1 -0
- package/dist/web/assets/share-sheet-weIdd4DW.js +2 -0
- package/dist/web/assets/timeline-BHgniliZ.js +1 -0
- package/dist/web/index.html +30 -4
- package/package.json +13 -4
- package/site/THIRD_PARTY_NOTICES.md +83 -0
- package/site/public/fonts/OFL.txt +93 -0
- package/dist/chunk-3RTWFGGD.js +0 -275
- package/dist/chunk-FMP3P2WV.js +0 -299
- package/dist/chunk-HP5UZCXP.js +0 -436
- package/dist/chunk-SMPY52EV.js +0 -125
- package/dist/chunk-XDA5RJST.js +0 -193
- package/dist/daemon-CL4FJW26.js +0 -219
- package/dist/daemon-handle-QQLJE46Y.js +0 -10
- package/dist/server-EUO7CWYH.js +0 -11
- package/dist/web/assets/analytics-DqdZXOJL.js +0 -2
- package/dist/web/assets/breakdown-kOSSJ3mI.js +0 -4
- package/dist/web/assets/explore-vcsM8K9I.js +0 -22
- package/dist/web/assets/index-BErCXT7f.css +0 -1
- package/dist/web/assets/index-DH3dOnbg.js +0 -83
- package/dist/web/assets/models-B5ikm83_.js +0 -2
- package/dist/web/assets/overview-DD1kP8CP.js +0 -2
- package/dist/web/assets/panel-DTQBwExW.js +0 -1
- package/dist/web/assets/primitives-C36qJlA2.js +0 -1
- package/dist/web/assets/settings-sheet-_i2zTQjf.js +0 -1
- package/dist/web/assets/share-sheet-BLHmrFbm.js +0 -2
- package/dist/web/assets/timeline-B4uG-Emo.js +0 -1
- package/dist/web/assets/use-dialog-trap-bfaXEMz9.js +0 -1
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
envDir,
|
|
6
6
|
expandHome,
|
|
7
7
|
isValidTimezone
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HNWEJ6MS.js";
|
|
9
9
|
|
|
10
10
|
// src/async.ts
|
|
11
11
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
@@ -20,13 +20,6 @@ function withTimeout(promise, ms = DEFAULT_TIMEOUT_MS) {
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
// src/providers/usage-core.ts
|
|
24
|
-
import { readFileSync, readdirSync } from "fs";
|
|
25
|
-
import { readdir as readdir2 } from "fs/promises";
|
|
26
|
-
import { dirname, join as join2, relative } from "path";
|
|
27
|
-
import { createHash as createHash2 } from "crypto";
|
|
28
|
-
import { fileURLToPath } from "url";
|
|
29
|
-
|
|
30
23
|
// src/tz.ts
|
|
31
24
|
function systemTimezone() {
|
|
32
25
|
try {
|
|
@@ -120,14 +113,17 @@ function startOfWeek(ts, tz) {
|
|
|
120
113
|
const offset = p.weekday === 0 ? 6 : p.weekday - 1;
|
|
121
114
|
return instantFromTz(p.y, p.m, p.d - offset, 0, 0, 0, tz);
|
|
122
115
|
}
|
|
123
|
-
function monthsAgoStart(ts, months, tz) {
|
|
124
|
-
const p = tzParts(ts, tz);
|
|
125
|
-
return instantFromTz(p.y, p.m - months, 1, 0, 0, 0, tz);
|
|
126
|
-
}
|
|
127
116
|
function weekKey(ts, tz) {
|
|
128
117
|
return dayKey(startOfWeek(ts, tz), tz);
|
|
129
118
|
}
|
|
130
119
|
|
|
120
|
+
// src/providers/usage-core.ts
|
|
121
|
+
import { readFileSync, readdirSync } from "fs";
|
|
122
|
+
import { readdir as readdir2 } from "fs/promises";
|
|
123
|
+
import { dirname, join as join2, relative } from "path";
|
|
124
|
+
import { createHash as createHash2 } from "crypto";
|
|
125
|
+
import { fileURLToPath } from "url";
|
|
126
|
+
|
|
131
127
|
// src/providers/_shared/metric.ts
|
|
132
128
|
var finite = (value, fallback = 0) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
133
129
|
var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
@@ -395,7 +391,7 @@ async function mapLimit(items, limit, fn) {
|
|
|
395
391
|
}
|
|
396
392
|
|
|
397
393
|
// src/providers/usage-core.ts
|
|
398
|
-
var SPARK_DAYS =
|
|
394
|
+
var SPARK_DAYS = 30;
|
|
399
395
|
var DAY_MS = 864e5;
|
|
400
396
|
var PRUNE_AGE_MS = 230 * DAY_MS;
|
|
401
397
|
var stores = /* @__PURE__ */ new Map();
|
|
@@ -560,8 +556,8 @@ function dashboardSince(tz) {
|
|
|
560
556
|
const now = Date.now();
|
|
561
557
|
return Math.min(startOfMonth(now, tz), startOfWeek(now, tz), now - SPARK_DAYS * DAY_MS);
|
|
562
558
|
}
|
|
563
|
-
function tableSince(
|
|
564
|
-
return
|
|
559
|
+
function tableSince(_tz) {
|
|
560
|
+
return 0;
|
|
565
561
|
}
|
|
566
562
|
function cleanEntry(e) {
|
|
567
563
|
return {
|
|
@@ -596,6 +592,7 @@ function summarize(entries, tz) {
|
|
|
596
592
|
const byDay = /* @__PURE__ */ new Map();
|
|
597
593
|
let oldestToday = now;
|
|
598
594
|
let hadToday = false;
|
|
595
|
+
let lastActivityAt = null;
|
|
599
596
|
const add = (s, e) => {
|
|
600
597
|
s.cost += e.cost;
|
|
601
598
|
s.tokens += e.input + e.output + e.cacheCreate + e.cacheRead;
|
|
@@ -605,6 +602,9 @@ function summarize(entries, tz) {
|
|
|
605
602
|
};
|
|
606
603
|
for (const raw of entries) {
|
|
607
604
|
const e = cleanEntry(raw);
|
|
605
|
+
if (e.ts > 0 && (lastActivityAt === null || e.ts > lastActivityAt)) {
|
|
606
|
+
lastActivityAt = Math.floor(e.ts);
|
|
607
|
+
}
|
|
608
608
|
if (e.ts >= monthStart) add(month, e);
|
|
609
609
|
if (e.ts >= weekStart) add(week, e);
|
|
610
610
|
if (e.ts >= todayStart) {
|
|
@@ -619,7 +619,7 @@ function summarize(entries, tz) {
|
|
|
619
619
|
const rawBurnRate = hadToday ? today.cost / hrs : 0;
|
|
620
620
|
const burnRate = Number.isFinite(rawBurnRate) ? rawBurnRate : 0;
|
|
621
621
|
const series = lastDayKeys(now, tz, SPARK_DAYS).map((k) => byDay.get(k) ?? 0);
|
|
622
|
-
return { today, week, month, burnRate, series };
|
|
622
|
+
return { today, week, month, burnRate, series, lastActivityAt };
|
|
623
623
|
}
|
|
624
624
|
function groupBy(entries, keyFn) {
|
|
625
625
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -739,243 +739,6 @@ function coalesceTables(list) {
|
|
|
739
739
|
return mergeTables(list);
|
|
740
740
|
}
|
|
741
741
|
|
|
742
|
-
// src/rpc/contract.ts
|
|
743
|
-
import { Schema } from "effect";
|
|
744
|
-
import * as Rpc from "effect/unstable/rpc/Rpc";
|
|
745
|
-
import * as RpcGroup from "effect/unstable/rpc/RpcGroup";
|
|
746
|
-
var TOKMON_WS_PATH = "/ws";
|
|
747
|
-
var TOKMON_PROTOCOL_VERSION = 3;
|
|
748
|
-
var TOKMON_CAPABILITIES = ["config-cas", "config-revision", "allowed-hosts"];
|
|
749
|
-
var TOKMON_WS_METHODS = {
|
|
750
|
-
getConfig: "tokmon.getConfig",
|
|
751
|
-
setConfig: "tokmon.setConfig",
|
|
752
|
-
refresh: "tokmon.refresh",
|
|
753
|
-
browseFs: "tokmon.browseFs",
|
|
754
|
-
snapshot: "tokmon.snapshot",
|
|
755
|
-
config: "tokmon.config"
|
|
756
|
-
};
|
|
757
|
-
var RefreshScopeSchema = Schema.Literals([
|
|
758
|
-
"all",
|
|
759
|
-
"summary",
|
|
760
|
-
"table",
|
|
761
|
-
"billing",
|
|
762
|
-
"peak"
|
|
763
|
-
]);
|
|
764
|
-
var ProviderIdSchema = Schema.Literals(PROVIDER_IDS);
|
|
765
|
-
var NonNegativeIntegerSchema = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
766
|
-
var PositiveFiniteSchema = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(1));
|
|
767
|
-
var AccountSchema = Schema.Struct({
|
|
768
|
-
id: Schema.String,
|
|
769
|
-
providerId: ProviderIdSchema,
|
|
770
|
-
name: Schema.String,
|
|
771
|
-
homeDir: Schema.String,
|
|
772
|
-
color: Schema.optionalKey(Schema.String)
|
|
773
|
-
});
|
|
774
|
-
var ConfigSchema = Schema.Struct({
|
|
775
|
-
revision: NonNegativeIntegerSchema,
|
|
776
|
-
interval: PositiveFiniteSchema,
|
|
777
|
-
billingInterval: PositiveFiniteSchema,
|
|
778
|
-
clearScreen: Schema.Boolean,
|
|
779
|
-
privacyMode: Schema.Boolean,
|
|
780
|
-
privacyToggleKey: Schema.String,
|
|
781
|
-
timezone: Schema.NullOr(Schema.String),
|
|
782
|
-
accounts: Schema.Array(AccountSchema),
|
|
783
|
-
activeAccountId: Schema.NullOr(Schema.String),
|
|
784
|
-
disabledProviders: Schema.Array(ProviderIdSchema),
|
|
785
|
-
onboarded: Schema.Boolean,
|
|
786
|
-
dashboardLayout: Schema.Literals(["grid", "single"]),
|
|
787
|
-
defaultFocus: Schema.Literals(["all", "last"]),
|
|
788
|
-
ascii: Schema.Literals(["auto", "on", "off"]),
|
|
789
|
-
allowNetworkAccess: Schema.Boolean,
|
|
790
|
-
allowedHosts: Schema.Array(Schema.String),
|
|
791
|
-
resetDisplay: Schema.Literals(["relative", "absolute"]),
|
|
792
|
-
knownProviders: Schema.Array(ProviderIdSchema)
|
|
793
|
-
});
|
|
794
|
-
var ProtocolInfoSchema = Schema.Struct({
|
|
795
|
-
version: Schema.Literal(TOKMON_PROTOCOL_VERSION),
|
|
796
|
-
// Capabilities are additive within a protocol version. Older clients must
|
|
797
|
-
// preserve forward compatibility when a newer daemon advertises one they do
|
|
798
|
-
// not understand yet.
|
|
799
|
-
capabilities: Schema.Array(Schema.String)
|
|
800
|
-
});
|
|
801
|
-
var ConfigStateSchema = Schema.Struct({
|
|
802
|
-
protocol: ProtocolInfoSchema,
|
|
803
|
-
config: ConfigSchema
|
|
804
|
-
});
|
|
805
|
-
var ConfigUpdateRequestSchema = Schema.Struct({
|
|
806
|
-
expectedRevision: NonNegativeIntegerSchema,
|
|
807
|
-
config: ConfigSchema
|
|
808
|
-
});
|
|
809
|
-
var ConfigUpdateConflictSchema = Schema.Struct({
|
|
810
|
-
kind: Schema.Literal("conflict"),
|
|
811
|
-
state: ConfigStateSchema
|
|
812
|
-
});
|
|
813
|
-
var ConfigPersistenceFailureSchema = Schema.Struct({
|
|
814
|
-
kind: Schema.Literal("persistence"),
|
|
815
|
-
message: Schema.String
|
|
816
|
-
});
|
|
817
|
-
var FsEntrySchema = Schema.Struct({
|
|
818
|
-
name: Schema.String,
|
|
819
|
-
path: Schema.String,
|
|
820
|
-
dir: Schema.Boolean
|
|
821
|
-
});
|
|
822
|
-
var FsListingSchema = Schema.Struct({
|
|
823
|
-
path: Schema.String,
|
|
824
|
-
parent: Schema.NullOr(Schema.String),
|
|
825
|
-
entries: Schema.Array(FsEntrySchema)
|
|
826
|
-
});
|
|
827
|
-
var UsageSummarySchema = Schema.Struct({
|
|
828
|
-
cost: Schema.Finite,
|
|
829
|
-
tokens: Schema.Finite,
|
|
830
|
-
input: Schema.Finite,
|
|
831
|
-
cacheRead: Schema.Finite,
|
|
832
|
-
cacheSavings: Schema.Finite
|
|
833
|
-
});
|
|
834
|
-
var ModelDetailSchema = Schema.Struct({
|
|
835
|
-
name: Schema.String,
|
|
836
|
-
input: Schema.Finite,
|
|
837
|
-
output: Schema.Finite,
|
|
838
|
-
cacheCreate: Schema.Finite,
|
|
839
|
-
cacheRead: Schema.Finite,
|
|
840
|
-
cacheSavings: Schema.Finite,
|
|
841
|
-
cost: Schema.Finite,
|
|
842
|
-
count: Schema.Finite
|
|
843
|
-
});
|
|
844
|
-
var TableRowSchema = Schema.Struct({
|
|
845
|
-
label: Schema.String,
|
|
846
|
-
models: Schema.Array(Schema.String),
|
|
847
|
-
input: Schema.Finite,
|
|
848
|
-
output: Schema.Finite,
|
|
849
|
-
cacheCreate: Schema.Finite,
|
|
850
|
-
cacheRead: Schema.Finite,
|
|
851
|
-
cacheSavings: Schema.Finite,
|
|
852
|
-
total: Schema.Finite,
|
|
853
|
-
cost: Schema.Finite,
|
|
854
|
-
count: Schema.Finite,
|
|
855
|
-
breakdown: Schema.Array(ModelDetailSchema)
|
|
856
|
-
});
|
|
857
|
-
var DashboardDataSchema = Schema.Struct({
|
|
858
|
-
today: UsageSummarySchema,
|
|
859
|
-
week: UsageSummarySchema,
|
|
860
|
-
month: UsageSummarySchema,
|
|
861
|
-
burnRate: Schema.Finite,
|
|
862
|
-
series: Schema.Array(Schema.Finite)
|
|
863
|
-
});
|
|
864
|
-
var TableDataSchema = Schema.Struct({
|
|
865
|
-
daily: Schema.Array(TableRowSchema),
|
|
866
|
-
weekly: Schema.Array(TableRowSchema),
|
|
867
|
-
monthly: Schema.Array(TableRowSchema)
|
|
868
|
-
});
|
|
869
|
-
var MetricFormatSchema = Schema.Union([
|
|
870
|
-
Schema.Struct({ kind: Schema.Literal("percent") }),
|
|
871
|
-
Schema.Struct({ kind: Schema.Literal("dollars"), currency: Schema.optionalKey(Schema.String) }),
|
|
872
|
-
Schema.Struct({ kind: Schema.Literal("count"), suffix: Schema.optionalKey(Schema.String) })
|
|
873
|
-
]);
|
|
874
|
-
var MetricSchema = Schema.Struct({
|
|
875
|
-
label: Schema.String,
|
|
876
|
-
used: Schema.Finite,
|
|
877
|
-
limit: Schema.NullOr(Schema.Finite),
|
|
878
|
-
format: MetricFormatSchema,
|
|
879
|
-
resetsAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
880
|
-
primary: Schema.optionalKey(Schema.Boolean)
|
|
881
|
-
});
|
|
882
|
-
var BillingResultSchema = Schema.Struct({
|
|
883
|
-
plan: Schema.NullOr(Schema.String),
|
|
884
|
-
metrics: Schema.Array(MetricSchema),
|
|
885
|
-
error: Schema.NullOr(Schema.String),
|
|
886
|
-
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
887
|
-
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
888
|
-
activity: Schema.optionalKey(Schema.NullOr(Schema.Struct({
|
|
889
|
-
series: Schema.Array(Schema.Finite),
|
|
890
|
-
summary: Schema.String
|
|
891
|
-
}))),
|
|
892
|
-
modelSpend: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Struct({
|
|
893
|
-
name: Schema.String,
|
|
894
|
-
usd: Schema.Finite,
|
|
895
|
-
requests: Schema.Finite
|
|
896
|
-
})))),
|
|
897
|
-
asOfMs: Schema.optionalKey(Schema.Finite)
|
|
898
|
-
});
|
|
899
|
-
var WebAccountSchema = Schema.Struct({
|
|
900
|
-
id: Schema.String,
|
|
901
|
-
providerId: ProviderIdSchema,
|
|
902
|
-
name: Schema.String,
|
|
903
|
-
color: Schema.String,
|
|
904
|
-
homeDir: Schema.NullOr(Schema.String),
|
|
905
|
-
hasUsage: Schema.Boolean,
|
|
906
|
-
hasBilling: Schema.Boolean,
|
|
907
|
-
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
908
|
-
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
909
|
-
plan: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
910
|
-
dashboard: Schema.NullOr(DashboardDataSchema),
|
|
911
|
-
table: Schema.NullOr(TableDataSchema),
|
|
912
|
-
billing: Schema.NullOr(BillingResultSchema),
|
|
913
|
-
summaryState: Schema.Literals(["pending", "ready", "error"]),
|
|
914
|
-
billingState: Schema.Literals(["pending", "ready", "error"]),
|
|
915
|
-
tableState: Schema.Literals(["pending", "ready", "error"]),
|
|
916
|
-
summaryUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
917
|
-
billingUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
918
|
-
tableUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema))
|
|
919
|
-
});
|
|
920
|
-
var WebSnapshotSchema = Schema.Struct({
|
|
921
|
-
version: Schema.String,
|
|
922
|
-
generatedAt: NonNegativeIntegerSchema,
|
|
923
|
-
tz: Schema.String,
|
|
924
|
-
intervalMs: PositiveFiniteSchema,
|
|
925
|
-
billingIntervalMs: Schema.optionalKey(PositiveFiniteSchema),
|
|
926
|
-
providers: Schema.Array(Schema.Struct({
|
|
927
|
-
id: ProviderIdSchema,
|
|
928
|
-
name: Schema.String,
|
|
929
|
-
color: Schema.String
|
|
930
|
-
})),
|
|
931
|
-
accounts: Schema.Array(WebAccountSchema),
|
|
932
|
-
seeded: Schema.Boolean,
|
|
933
|
-
peak: Schema.NullOr(Schema.Struct({
|
|
934
|
-
state: Schema.Literals(["peak", "off-peak", "weekend"]),
|
|
935
|
-
label: Schema.String,
|
|
936
|
-
// The upstream clock is only normalized to a finite number; do not make
|
|
937
|
-
// the wire contract narrower than the producer's declared type.
|
|
938
|
-
minutesUntilChange: Schema.NullOr(Schema.Finite),
|
|
939
|
-
changesAt: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
940
|
-
}))
|
|
941
|
-
});
|
|
942
|
-
var EmptyPayloadSchema = Schema.Struct({});
|
|
943
|
-
var GetConfigRpc = Rpc.make(TOKMON_WS_METHODS.getConfig, {
|
|
944
|
-
payload: EmptyPayloadSchema,
|
|
945
|
-
success: ConfigStateSchema
|
|
946
|
-
});
|
|
947
|
-
var SetConfigRpc = Rpc.make(TOKMON_WS_METHODS.setConfig, {
|
|
948
|
-
payload: ConfigUpdateRequestSchema,
|
|
949
|
-
success: ConfigStateSchema,
|
|
950
|
-
error: Schema.Union([ConfigUpdateConflictSchema, ConfigPersistenceFailureSchema])
|
|
951
|
-
});
|
|
952
|
-
var RefreshRpc = Rpc.make(TOKMON_WS_METHODS.refresh, {
|
|
953
|
-
payload: Schema.Struct({ scope: RefreshScopeSchema }),
|
|
954
|
-
success: Schema.Void
|
|
955
|
-
});
|
|
956
|
-
var BrowseFsRpc = Rpc.make(TOKMON_WS_METHODS.browseFs, {
|
|
957
|
-
payload: Schema.Struct({ path: Schema.String }),
|
|
958
|
-
success: FsListingSchema
|
|
959
|
-
});
|
|
960
|
-
var SnapshotRpc = Rpc.make(TOKMON_WS_METHODS.snapshot, {
|
|
961
|
-
payload: EmptyPayloadSchema,
|
|
962
|
-
success: WebSnapshotSchema,
|
|
963
|
-
stream: true
|
|
964
|
-
});
|
|
965
|
-
var ConfigRpc = Rpc.make(TOKMON_WS_METHODS.config, {
|
|
966
|
-
payload: EmptyPayloadSchema,
|
|
967
|
-
success: ConfigStateSchema,
|
|
968
|
-
stream: true
|
|
969
|
-
});
|
|
970
|
-
var TokmonRpcGroup = RpcGroup.make(
|
|
971
|
-
GetConfigRpc,
|
|
972
|
-
SetConfigRpc,
|
|
973
|
-
RefreshRpc,
|
|
974
|
-
BrowseFsRpc,
|
|
975
|
-
SnapshotRpc,
|
|
976
|
-
ConfigRpc
|
|
977
|
-
);
|
|
978
|
-
|
|
979
742
|
// src/shared/format.ts
|
|
980
743
|
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
981
744
|
function formatCurrency(value, opts = {}) {
|
|
@@ -984,7 +747,10 @@ function formatCurrency(value, opts = {}) {
|
|
|
984
747
|
const abs = Math.abs(value);
|
|
985
748
|
if (abs >= 1e5) return `${sign}$${(value / 1e3).toFixed(0)}k`;
|
|
986
749
|
if (abs >= 1e4) return `${sign}$${(value / 1e3).toFixed(1)}k`;
|
|
987
|
-
if (abs >= 1)
|
|
750
|
+
if (abs >= 1) {
|
|
751
|
+
const polarity = value < 0 ? "-" : "";
|
|
752
|
+
return `${sign}${polarity}$${abs.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
753
|
+
}
|
|
988
754
|
if (abs >= 0.01) return `${sign}$${value.toFixed(3)}`;
|
|
989
755
|
if (abs === 0) return "$0.00";
|
|
990
756
|
return `${sign}$${value.toFixed(4)}`;
|
|
@@ -1021,17 +787,22 @@ function formatShortDate(label, opts = {}) {
|
|
|
1021
787
|
const day = Number(match[3]);
|
|
1022
788
|
return `${MONTHS[Number(match[2]) - 1]} ${opts.padDay ? day.toString().padStart(2, " ") : day}`;
|
|
1023
789
|
}
|
|
790
|
+
function resetParts(diffMs) {
|
|
791
|
+
if (!Number.isFinite(diffMs) || diffMs <= 0) return null;
|
|
792
|
+
const totalMinutes = Math.max(1, Math.ceil(diffMs / 6e4));
|
|
793
|
+
return {
|
|
794
|
+
days: Math.floor(totalMinutes / (24 * 60)),
|
|
795
|
+
hours: Math.floor(totalMinutes % (24 * 60) / 60),
|
|
796
|
+
minutes: totalMinutes % 60,
|
|
797
|
+
totalMinutes
|
|
798
|
+
};
|
|
799
|
+
}
|
|
1024
800
|
function formatResetIn(iso, now = Date.now()) {
|
|
1025
|
-
const
|
|
1026
|
-
if (!
|
|
1027
|
-
|
|
1028
|
-
if (
|
|
1029
|
-
|
|
1030
|
-
const mins = minutes % 60;
|
|
1031
|
-
if (hours < 24) return `${hours}h ${mins}m`;
|
|
1032
|
-
const days = Math.floor(hours / 24);
|
|
1033
|
-
const hrs = hours % 24;
|
|
1034
|
-
return `${days}d ${hrs}h`;
|
|
801
|
+
const parts = resetParts(new Date(iso).getTime() - now);
|
|
802
|
+
if (!parts) return "now";
|
|
803
|
+
if (parts.days > 0) return `${parts.days}d ${parts.hours}h`;
|
|
804
|
+
if (parts.hours > 0) return `${parts.hours}h ${parts.minutes}m`;
|
|
805
|
+
return `${parts.minutes}m`;
|
|
1035
806
|
}
|
|
1036
807
|
function formatResetAt(iso, display, now = Date.now(), tz) {
|
|
1037
808
|
const timestamp = Date.parse(iso);
|
|
@@ -1506,7 +1277,19 @@ function limitMetric(entry, primary) {
|
|
|
1506
1277
|
if (used === void 0) return null;
|
|
1507
1278
|
const label = limitLabel(o);
|
|
1508
1279
|
if (!label) return null;
|
|
1509
|
-
|
|
1280
|
+
const scope = recordValue(o.scope);
|
|
1281
|
+
const model = recordValue(scope?.model);
|
|
1282
|
+
const modelId = nonEmptyString(model?.id);
|
|
1283
|
+
const kind = nonEmptyString(o.kind)?.toLowerCase() ?? "";
|
|
1284
|
+
const scopedModel = kind === "weekly_scoped" || kind.startsWith("weekly_model");
|
|
1285
|
+
const role = kind === "session" || nonEmptyString(o.group)?.toLowerCase() === "session" ? "session" : kind === "weekly_all" ? "weekly" : modelId || scopedModel ? "model" : "other";
|
|
1286
|
+
return {
|
|
1287
|
+
...percentMetric(label, used, resetFrom(o.resets_at), primary),
|
|
1288
|
+
key: modelId ? `model:${modelId}` : kind || label.toLowerCase(),
|
|
1289
|
+
role,
|
|
1290
|
+
modelId: modelId ?? (scopedModel ? label.toLowerCase().replace(/\s+/g, "-") : null),
|
|
1291
|
+
active: boolValue(o.is_active)
|
|
1292
|
+
};
|
|
1510
1293
|
}
|
|
1511
1294
|
function limitMetrics(limits) {
|
|
1512
1295
|
if (!Array.isArray(limits)) return [];
|
|
@@ -1533,7 +1316,12 @@ function topLevelUsageMetrics(data) {
|
|
|
1533
1316
|
const window = recordValue(value);
|
|
1534
1317
|
if (!window || numberValue(window.utilization) === void 0) continue;
|
|
1535
1318
|
const metric = usageMetric(usageLabelFromKey(key), window, key === "five_hour" ? true : void 0);
|
|
1536
|
-
if (metric) metrics.push(
|
|
1319
|
+
if (metric) metrics.push({
|
|
1320
|
+
...metric,
|
|
1321
|
+
key,
|
|
1322
|
+
role: key === "five_hour" ? "session" : key === "seven_day" ? "weekly" : key.startsWith("seven_day_") ? "model" : "other",
|
|
1323
|
+
modelId: key.startsWith("seven_day_") ? key.slice("seven_day_".length) : null
|
|
1324
|
+
});
|
|
1537
1325
|
}
|
|
1538
1326
|
return metrics;
|
|
1539
1327
|
}
|
|
@@ -1576,6 +1364,8 @@ async function claudeBilling(account) {
|
|
|
1576
1364
|
if (usedCredits !== void 0 && (usedCredits > 0 || monthlyLimit !== void 0 && monthlyLimit > 0)) {
|
|
1577
1365
|
const scale = decimalScale(data.extra_usage?.decimal_places);
|
|
1578
1366
|
metrics.push({
|
|
1367
|
+
key: "extra_usage",
|
|
1368
|
+
role: "unbounded",
|
|
1579
1369
|
label: "Extra",
|
|
1580
1370
|
used: finite(usedCredits) / scale,
|
|
1581
1371
|
limit: monthlyLimit !== void 0 && monthlyLimit > 0 ? monthlyLimit / scale : null,
|
|
@@ -1727,13 +1517,14 @@ function timestampSecond(value) {
|
|
|
1727
1517
|
const ts = timestampMs(value);
|
|
1728
1518
|
return ts === null ? null : new Date(ts).toISOString().slice(0, 19);
|
|
1729
1519
|
}
|
|
1730
|
-
async function
|
|
1520
|
+
async function hasForkedHistory(path) {
|
|
1731
1521
|
let handle = null;
|
|
1732
1522
|
try {
|
|
1733
1523
|
handle = await openFile(path, "r");
|
|
1734
1524
|
const buffer = Buffer.alloc(16 * 1024);
|
|
1735
1525
|
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
1736
|
-
|
|
1526
|
+
const prefix = buffer.subarray(0, bytesRead).toString("utf8");
|
|
1527
|
+
return prefix.includes("thread_spawn") && /"forked_from_id"\s*:\s*"[^"]+"/.test(prefix);
|
|
1737
1528
|
} catch {
|
|
1738
1529
|
return false;
|
|
1739
1530
|
} finally {
|
|
@@ -1741,32 +1532,11 @@ async function hasThreadSpawn(path) {
|
|
|
1741
1532
|
});
|
|
1742
1533
|
}
|
|
1743
1534
|
}
|
|
1744
|
-
|
|
1745
|
-
if (
|
|
1746
|
-
|
|
1747
|
-
const
|
|
1748
|
-
|
|
1749
|
-
});
|
|
1750
|
-
const rl = createInterface2({ input, crlfDelay: Infinity });
|
|
1751
|
-
try {
|
|
1752
|
-
for await (const rawLine of rl) {
|
|
1753
|
-
if (!rawLine.includes("token_count")) continue;
|
|
1754
|
-
try {
|
|
1755
|
-
const line = rawLine.charCodeAt(0) === 65279 ? rawLine.slice(1) : rawLine;
|
|
1756
|
-
const obj = JSON.parse(line);
|
|
1757
|
-
if ((obj?.payload?.type ?? obj?.type) !== "token_count") continue;
|
|
1758
|
-
const info = obj?.payload?.info;
|
|
1759
|
-
if (!normalizeUsage(info?.last_token_usage) && !normalizeUsage(info?.total_token_usage)) continue;
|
|
1760
|
-
const second = timestampSecond(obj.timestamp ?? obj?.payload?.timestamp);
|
|
1761
|
-
if (!second) continue;
|
|
1762
|
-
if (!first) first = second;
|
|
1763
|
-
else return first === second ? second : null;
|
|
1764
|
-
} catch {
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1767
|
-
} catch {
|
|
1768
|
-
}
|
|
1769
|
-
return null;
|
|
1535
|
+
function isLiveTaskStart(obj) {
|
|
1536
|
+
if ((obj?.payload?.type ?? obj?.type) !== "task_started") return false;
|
|
1537
|
+
const eventSecond = timestampSecond(obj?.timestamp ?? obj?.payload?.timestamp);
|
|
1538
|
+
const startedSecond = timestampSecond(obj?.payload?.started_at);
|
|
1539
|
+
return eventSecond !== null && eventSecond === startedSecond;
|
|
1770
1540
|
}
|
|
1771
1541
|
function findUsage(obj) {
|
|
1772
1542
|
return normalizeUsage(obj?.usage) ?? normalizeUsage(obj?.payload?.usage) ?? normalizeUsage(obj?.payload?.info?.usage) ?? normalizeUsage(obj?.result?.usage) ?? normalizeUsage(obj?.response?.usage) ?? normalizeUsage(obj?.token_usage) ?? normalizeUsage(obj);
|
|
@@ -1779,19 +1549,22 @@ async function parseFile2(path) {
|
|
|
1779
1549
|
let model = "gpt-5";
|
|
1780
1550
|
let prevTotal = null;
|
|
1781
1551
|
let prevSig = null;
|
|
1782
|
-
|
|
1783
|
-
let skipReplay = replaySecond !== null;
|
|
1552
|
+
let skipReplay = await hasForkedHistory(path);
|
|
1784
1553
|
const input = createReadStream2(path);
|
|
1785
1554
|
input.on("error", () => {
|
|
1786
1555
|
});
|
|
1787
1556
|
const rl = createInterface2({ input, crlfDelay: Infinity });
|
|
1788
1557
|
try {
|
|
1789
1558
|
for await (const rawLine of rl) {
|
|
1790
|
-
if (!rawLine.includes("token_count") && !rawLine.includes("turn_context") && !rawLine.includes('"usage"') && !rawLine.includes("input_tokens") && !rawLine.includes("prompt_tokens")) continue;
|
|
1559
|
+
if (!rawLine.includes("token_count") && !rawLine.includes("task_started") && !rawLine.includes("turn_context") && !rawLine.includes('"usage"') && !rawLine.includes("input_tokens") && !rawLine.includes("prompt_tokens")) continue;
|
|
1791
1560
|
try {
|
|
1792
1561
|
const line = rawLine.charCodeAt(0) === 65279 ? rawLine.slice(1) : rawLine;
|
|
1793
1562
|
const obj = JSON.parse(line);
|
|
1794
1563
|
const payloadType = obj?.payload?.type ?? obj?.type;
|
|
1564
|
+
if (skipReplay) {
|
|
1565
|
+
if (isLiveTaskStart(obj)) skipReplay = false;
|
|
1566
|
+
continue;
|
|
1567
|
+
}
|
|
1795
1568
|
if (payloadType === "turn_context") {
|
|
1796
1569
|
const m2 = extractModel(obj);
|
|
1797
1570
|
if (typeof m2 === "string" && m2.trim()) model = m2;
|
|
@@ -1827,14 +1600,6 @@ async function parseFile2(path) {
|
|
|
1827
1600
|
const total = normalizeUsage(info?.total_token_usage);
|
|
1828
1601
|
const last = normalizeUsage(info?.last_token_usage);
|
|
1829
1602
|
const tsValue = obj.timestamp ?? obj?.payload?.timestamp;
|
|
1830
|
-
if (skipReplay && replaySecond) {
|
|
1831
|
-
const second = timestampSecond(tsValue);
|
|
1832
|
-
if (second === replaySecond) {
|
|
1833
|
-
if (total) prevTotal = total;
|
|
1834
|
-
continue;
|
|
1835
|
-
}
|
|
1836
|
-
if (second) skipReplay = false;
|
|
1837
|
-
}
|
|
1838
1603
|
const sig = eventSig(last, total);
|
|
1839
1604
|
if (sig === prevSig) continue;
|
|
1840
1605
|
prevSig = sig;
|
|
@@ -4622,11 +4387,6 @@ async function detectProviders() {
|
|
|
4622
4387
|
}
|
|
4623
4388
|
|
|
4624
4389
|
export {
|
|
4625
|
-
TOKMON_WS_PATH,
|
|
4626
|
-
TOKMON_PROTOCOL_VERSION,
|
|
4627
|
-
TOKMON_CAPABILITIES,
|
|
4628
|
-
TOKMON_WS_METHODS,
|
|
4629
|
-
TokmonRpcGroup,
|
|
4630
4390
|
withTimeout,
|
|
4631
4391
|
systemTimezone,
|
|
4632
4392
|
resolveTimezone,
|