@hasna/economy 0.2.21 → 0.2.22
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/LICENSE +1 -2
- package/README.md +5 -13
- package/dist/cli/commands/extras.d.ts.map +1 -1
- package/dist/cli/index.js +536 -88
- package/dist/db/database.d.ts +4 -2
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/pg-migrations.d.ts.map +1 -1
- package/dist/index.js +401 -34
- package/dist/ingest/claude.d.ts.map +1 -1
- package/dist/ingest/codex.d.ts.map +1 -1
- package/dist/ingest/cursor.d.ts.map +1 -1
- package/dist/ingest/gemini.d.ts.map +1 -1
- package/dist/ingest/hermes.d.ts.map +1 -1
- package/dist/ingest/opencode.d.ts.map +1 -1
- package/dist/ingest/pi.d.ts.map +1 -1
- package/dist/lib/accounts.d.ts +11 -0
- package/dist/lib/accounts.d.ts.map +1 -0
- package/dist/lib/cloud-sync.d.ts.map +1 -1
- package/dist/lib/savings.d.ts.map +1 -1
- package/dist/mcp/index.js +901 -582
- package/dist/otel/index.js +77 -26
- package/dist/server/index.js +476 -89
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/types/index.d.ts +43 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +9 -4
- package/dist/mcp/http.d.ts +0 -13
- package/dist/mcp/http.d.ts.map +0 -1
- package/dist/mcp/server.d.ts +0 -4
- package/dist/mcp/server.d.ts.map +0 -1
package/dist/otel/index.js
CHANGED
|
@@ -583,7 +583,12 @@ function initSchema(db) {
|
|
|
583
583
|
duration_ms INTEGER DEFAULT 0,
|
|
584
584
|
timestamp TEXT NOT NULL,
|
|
585
585
|
source_request_id TEXT,
|
|
586
|
-
machine_id TEXT DEFAULT ''
|
|
586
|
+
machine_id TEXT DEFAULT '',
|
|
587
|
+
account_key TEXT DEFAULT '',
|
|
588
|
+
account_tool TEXT DEFAULT '',
|
|
589
|
+
account_name TEXT DEFAULT '',
|
|
590
|
+
account_email TEXT DEFAULT '',
|
|
591
|
+
account_source TEXT DEFAULT ''
|
|
587
592
|
);
|
|
588
593
|
|
|
589
594
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
@@ -596,7 +601,12 @@ function initSchema(db) {
|
|
|
596
601
|
total_cost_usd REAL DEFAULT 0,
|
|
597
602
|
total_tokens INTEGER DEFAULT 0,
|
|
598
603
|
request_count INTEGER DEFAULT 0,
|
|
599
|
-
machine_id TEXT DEFAULT ''
|
|
604
|
+
machine_id TEXT DEFAULT '',
|
|
605
|
+
account_key TEXT DEFAULT '',
|
|
606
|
+
account_tool TEXT DEFAULT '',
|
|
607
|
+
account_name TEXT DEFAULT '',
|
|
608
|
+
account_email TEXT DEFAULT '',
|
|
609
|
+
account_source TEXT DEFAULT ''
|
|
600
610
|
);
|
|
601
611
|
|
|
602
612
|
CREATE TABLE IF NOT EXISTS projects (
|
|
@@ -751,6 +761,11 @@ function initSchema(db) {
|
|
|
751
761
|
if (!cols.some((c) => c.name === "synced_at")) {
|
|
752
762
|
db.exec(`ALTER TABLE requests ADD COLUMN synced_at TEXT DEFAULT ''`);
|
|
753
763
|
}
|
|
764
|
+
for (const column of ["account_key", "account_tool", "account_name", "account_email", "account_source"]) {
|
|
765
|
+
if (!cols.some((c) => c.name === column)) {
|
|
766
|
+
db.exec(`ALTER TABLE requests ADD COLUMN ${column} TEXT DEFAULT ''`);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
754
769
|
const sessionCols = db.prepare(`PRAGMA table_info(sessions)`).all();
|
|
755
770
|
if (!sessionCols.some((c) => c.name === "attribution_tag")) {
|
|
756
771
|
db.exec(`ALTER TABLE sessions ADD COLUMN attribution_tag TEXT DEFAULT ''`);
|
|
@@ -762,6 +777,11 @@ function initSchema(db) {
|
|
|
762
777
|
if (!sessionCols.some((c) => c.name === "synced_at")) {
|
|
763
778
|
db.exec(`ALTER TABLE sessions ADD COLUMN synced_at TEXT DEFAULT ''`);
|
|
764
779
|
}
|
|
780
|
+
for (const column of ["account_key", "account_tool", "account_name", "account_email", "account_source"]) {
|
|
781
|
+
if (!sessionCols.some((c) => c.name === column)) {
|
|
782
|
+
db.exec(`ALTER TABLE sessions ADD COLUMN ${column} TEXT DEFAULT ''`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
765
785
|
const pricingCols = db.prepare(`PRAGMA table_info(model_pricing)`).all();
|
|
766
786
|
if (!pricingCols.some((c) => c.name === "cache_write_1h_per_1m")) {
|
|
767
787
|
db.exec(`ALTER TABLE model_pricing ADD COLUMN cache_write_1h_per_1m REAL NOT NULL DEFAULT 0`);
|
|
@@ -772,6 +792,8 @@ function initSchema(db) {
|
|
|
772
792
|
db.exec(`
|
|
773
793
|
CREATE INDEX IF NOT EXISTS idx_requests_machine ON requests(machine_id);
|
|
774
794
|
CREATE INDEX IF NOT EXISTS idx_sessions_machine ON sessions(machine_id);
|
|
795
|
+
CREATE INDEX IF NOT EXISTS idx_requests_account ON requests(account_key);
|
|
796
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_account ON sessions(account_key);
|
|
775
797
|
`);
|
|
776
798
|
}
|
|
777
799
|
function upsertRequest(db, req) {
|
|
@@ -781,18 +803,20 @@ function upsertRequest(db, req) {
|
|
|
781
803
|
(id, agent, session_id, model, input_tokens, output_tokens,
|
|
782
804
|
cache_read_tokens, cache_create_tokens, cache_create_5m_tokens,
|
|
783
805
|
cache_create_1h_tokens, cost_usd, cost_basis, duration_ms, timestamp,
|
|
784
|
-
source_request_id, machine_id, attribution_tag,
|
|
785
|
-
|
|
786
|
-
|
|
806
|
+
source_request_id, machine_id, attribution_tag, account_key, account_tool,
|
|
807
|
+
account_name, account_email, account_source, updated_at, synced_at)
|
|
808
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
809
|
+
`).run(req.id, req.agent, req.session_id, req.model, req.input_tokens, req.output_tokens, req.cache_read_tokens, req.cache_create_tokens, req.cache_create_5m_tokens ?? req.cache_create_tokens, req.cache_create_1h_tokens ?? 0, req.cost_usd, req.cost_basis ?? "estimated", req.duration_ms, req.timestamp, req.source_request_id, req.machine_id ?? "", req.attribution_tag ?? process.env["ECONOMY_TAG"] ?? "", req.account_key ?? "", req.account_tool ?? "", req.account_name ?? "", req.account_email ?? "", req.account_source ?? "", now, req.synced_at ?? "");
|
|
787
810
|
}
|
|
788
811
|
function upsertSession(db, session) {
|
|
789
812
|
const now = session.updated_at ?? new Date().toISOString();
|
|
790
813
|
db.prepare(`
|
|
791
814
|
INSERT OR REPLACE INTO sessions
|
|
792
815
|
(id, agent, project_path, project_name, started_at, ended_at,
|
|
793
|
-
total_cost_usd, total_tokens, request_count, machine_id, attribution_tag,
|
|
794
|
-
|
|
795
|
-
|
|
816
|
+
total_cost_usd, total_tokens, request_count, machine_id, attribution_tag,
|
|
817
|
+
account_key, account_tool, account_name, account_email, account_source, updated_at, synced_at)
|
|
818
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
819
|
+
`).run(session.id, session.agent, session.project_path, session.project_name, session.started_at, session.ended_at ?? null, session.total_cost_usd, session.total_tokens, session.request_count, session.machine_id ?? "", session.attribution_tag ?? process.env["ECONOMY_TAG"] ?? "", session.account_key ?? "", session.account_tool ?? "", session.account_name ?? "", session.account_email ?? "", session.account_source ?? "", now, session.synced_at ?? "");
|
|
796
820
|
}
|
|
797
821
|
function rollupSession(db, sessionId) {
|
|
798
822
|
db.prepare(`
|
|
@@ -803,9 +827,24 @@ function rollupSession(db, sessionId) {
|
|
|
803
827
|
ended_at = (SELECT MAX(timestamp) FROM requests WHERE session_id = ?),
|
|
804
828
|
started_at = CASE WHEN started_at = '' OR started_at IS NULL
|
|
805
829
|
THEN (SELECT MIN(timestamp) FROM requests WHERE session_id = ?)
|
|
806
|
-
ELSE started_at END
|
|
830
|
+
ELSE started_at END,
|
|
831
|
+
account_key = CASE WHEN account_key = '' OR account_key IS NULL
|
|
832
|
+
THEN COALESCE((SELECT account_key FROM requests WHERE session_id = ? AND account_key != '' ORDER BY timestamp DESC LIMIT 1), '')
|
|
833
|
+
ELSE account_key END,
|
|
834
|
+
account_tool = CASE WHEN account_tool = '' OR account_tool IS NULL
|
|
835
|
+
THEN COALESCE((SELECT account_tool FROM requests WHERE session_id = ? AND account_tool != '' ORDER BY timestamp DESC LIMIT 1), '')
|
|
836
|
+
ELSE account_tool END,
|
|
837
|
+
account_name = CASE WHEN account_name = '' OR account_name IS NULL
|
|
838
|
+
THEN COALESCE((SELECT account_name FROM requests WHERE session_id = ? AND account_name != '' ORDER BY timestamp DESC LIMIT 1), '')
|
|
839
|
+
ELSE account_name END,
|
|
840
|
+
account_email = CASE WHEN account_email = '' OR account_email IS NULL
|
|
841
|
+
THEN COALESCE((SELECT account_email FROM requests WHERE session_id = ? AND account_email != '' ORDER BY timestamp DESC LIMIT 1), '')
|
|
842
|
+
ELSE account_email END,
|
|
843
|
+
account_source = CASE WHEN account_source = '' OR account_source IS NULL
|
|
844
|
+
THEN COALESCE((SELECT account_source FROM requests WHERE session_id = ? AND account_source != '' ORDER BY timestamp DESC LIMIT 1), '')
|
|
845
|
+
ELSE account_source END
|
|
807
846
|
WHERE id = ?
|
|
808
|
-
`).run(sessionId, sessionId, sessionId, sessionId, sessionId, sessionId);
|
|
847
|
+
`).run(sessionId, sessionId, sessionId, sessionId, sessionId, sessionId, sessionId, sessionId, sessionId, sessionId, sessionId);
|
|
809
848
|
}
|
|
810
849
|
function upsertModelPricing(db, p) {
|
|
811
850
|
db.prepare(`
|
|
@@ -863,7 +902,12 @@ var init_pg_migrations = __esm(() => {
|
|
|
863
902
|
duration_ms INTEGER DEFAULT 0,
|
|
864
903
|
timestamp TEXT NOT NULL,
|
|
865
904
|
source_request_id TEXT,
|
|
866
|
-
machine_id TEXT DEFAULT ''
|
|
905
|
+
machine_id TEXT DEFAULT '',
|
|
906
|
+
account_key TEXT DEFAULT '',
|
|
907
|
+
account_tool TEXT DEFAULT '',
|
|
908
|
+
account_name TEXT DEFAULT '',
|
|
909
|
+
account_email TEXT DEFAULT '',
|
|
910
|
+
account_source TEXT DEFAULT ''
|
|
867
911
|
)`,
|
|
868
912
|
`CREATE TABLE IF NOT EXISTS sessions (
|
|
869
913
|
id TEXT PRIMARY KEY,
|
|
@@ -875,7 +919,12 @@ var init_pg_migrations = __esm(() => {
|
|
|
875
919
|
total_cost_usd REAL DEFAULT 0,
|
|
876
920
|
total_tokens INTEGER DEFAULT 0,
|
|
877
921
|
request_count INTEGER DEFAULT 0,
|
|
878
|
-
machine_id TEXT DEFAULT ''
|
|
922
|
+
machine_id TEXT DEFAULT '',
|
|
923
|
+
account_key TEXT DEFAULT '',
|
|
924
|
+
account_tool TEXT DEFAULT '',
|
|
925
|
+
account_name TEXT DEFAULT '',
|
|
926
|
+
account_email TEXT DEFAULT '',
|
|
927
|
+
account_source TEXT DEFAULT ''
|
|
879
928
|
)`,
|
|
880
929
|
`CREATE TABLE IF NOT EXISTS projects (
|
|
881
930
|
id TEXT PRIMARY KEY,
|
|
@@ -996,13 +1045,25 @@ var init_pg_migrations = __esm(() => {
|
|
|
996
1045
|
)`,
|
|
997
1046
|
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS cost_basis TEXT DEFAULT 'estimated'`,
|
|
998
1047
|
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS attribution_tag TEXT DEFAULT ''`,
|
|
1048
|
+
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS account_key TEXT DEFAULT ''`,
|
|
1049
|
+
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS account_tool TEXT DEFAULT ''`,
|
|
1050
|
+
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS account_name TEXT DEFAULT ''`,
|
|
1051
|
+
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS account_email TEXT DEFAULT ''`,
|
|
1052
|
+
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS account_source TEXT DEFAULT ''`,
|
|
999
1053
|
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS updated_at TEXT DEFAULT ''`,
|
|
1000
1054
|
`ALTER TABLE requests ADD COLUMN IF NOT EXISTS synced_at TEXT DEFAULT ''`,
|
|
1001
1055
|
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS attribution_tag TEXT DEFAULT ''`,
|
|
1056
|
+
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS account_key TEXT DEFAULT ''`,
|
|
1057
|
+
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS account_tool TEXT DEFAULT ''`,
|
|
1058
|
+
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS account_name TEXT DEFAULT ''`,
|
|
1059
|
+
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS account_email TEXT DEFAULT ''`,
|
|
1060
|
+
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS account_source TEXT DEFAULT ''`,
|
|
1002
1061
|
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS updated_at TEXT DEFAULT ''`,
|
|
1003
1062
|
`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS synced_at TEXT DEFAULT ''`,
|
|
1004
1063
|
`CREATE INDEX IF NOT EXISTS idx_usage_agent_date ON usage_snapshots(agent, date)`,
|
|
1005
|
-
`CREATE INDEX IF NOT EXISTS idx_savings_date ON savings_daily(date)
|
|
1064
|
+
`CREATE INDEX IF NOT EXISTS idx_savings_date ON savings_daily(date)`,
|
|
1065
|
+
`CREATE INDEX IF NOT EXISTS idx_requests_account ON requests(account_key)`,
|
|
1066
|
+
`CREATE INDEX IF NOT EXISTS idx_sessions_account ON sessions(account_key)`
|
|
1006
1067
|
];
|
|
1007
1068
|
});
|
|
1008
1069
|
|
|
@@ -1268,24 +1329,14 @@ async function runCloudMigrations(cloud) {
|
|
|
1268
1329
|
await cloud.run(sql);
|
|
1269
1330
|
}
|
|
1270
1331
|
}
|
|
1271
|
-
function isCloudIncrementalEnabled() {
|
|
1272
|
-
return process.env["ECONOMY_CLOUD_INCREMENTAL"] === "1" || process.env["ECONOMY_CLOUD_INCREMENTAL"] === "true";
|
|
1273
|
-
}
|
|
1274
1332
|
async function cloudPush(opts) {
|
|
1275
|
-
const { syncPush,
|
|
1333
|
+
const { syncPush, SqliteAdapter } = await import("@hasna/cloud");
|
|
1276
1334
|
const cloud = await getCloudPg();
|
|
1277
1335
|
const local = new SqliteAdapter(getDbPath());
|
|
1278
1336
|
await runCloudMigrations(cloud);
|
|
1279
1337
|
const tables = opts?.tables ?? [...CLOUD_TABLES];
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
ensureSyncMetaTable(local);
|
|
1283
|
-
const results = incrementalSyncPush(local, cloud, tables, { conflictColumn: "updated_at" });
|
|
1284
|
-
rows = results.reduce((s, r) => s + r.synced_rows, 0);
|
|
1285
|
-
} else {
|
|
1286
|
-
const results = await syncPush(local, cloud, { tables, conflictColumn: "updated_at" });
|
|
1287
|
-
rows = results.reduce((s, r) => s + r.rowsWritten, 0);
|
|
1288
|
-
}
|
|
1338
|
+
const results = await syncPush(local, cloud, { tables, conflictColumn: "updated_at" });
|
|
1339
|
+
const rows = results.reduce((s, r) => s + r.rowsWritten, 0);
|
|
1289
1340
|
touchMachineRegistry(local, "push");
|
|
1290
1341
|
local.close();
|
|
1291
1342
|
await cloud.close();
|