@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.
@@ -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, updated_at, synced_at)
785
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
786
- `).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"] ?? "", now, req.synced_at ?? "");
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, updated_at, synced_at)
794
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
795
- `).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"] ?? "", now, session.synced_at ?? "");
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, incrementalSyncPush, ensureSyncMetaTable, SqliteAdapter } = await import("@hasna/cloud");
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
- let rows = 0;
1281
- if (isCloudIncrementalEnabled()) {
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();