@anthonyhaussman/opencode-agy-auth 1.1.6-alpha.1 → 1.1.6-alpha.2

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/index.js CHANGED
@@ -4,6 +4,104 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
+ // src/plugin/pricing.ts
8
+ import { tmpdir, userInfo } from "os";
9
+ import { join } from "path";
10
+ import { existsSync, readFileSync, writeFileSync, statSync } from "fs";
11
+ var PRICING_API_URL = "https://models.dev/api.json";
12
+ var CACHE_FILE_NAME = "agy-pricing-cache.json";
13
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
14
+ var memoryCache = null;
15
+ function getCachePath() {
16
+ try {
17
+ return join(tmpdir(), `${CACHE_FILE_NAME}-${userInfo().uid}`);
18
+ } catch (err) {
19
+ return join(tmpdir(), CACHE_FILE_NAME);
20
+ }
21
+ }
22
+ function loadCachedPricing() {
23
+ try {
24
+ const cachePath = getCachePath();
25
+ if (!existsSync(cachePath)) return null;
26
+ const stats = statSync(cachePath);
27
+ if (Date.now() - stats.mtimeMs > CACHE_TTL_MS) {
28
+ return null;
29
+ }
30
+ const data = readFileSync(cachePath, "utf-8");
31
+ return JSON.parse(data);
32
+ } catch (err) {
33
+ return null;
34
+ }
35
+ }
36
+ function savePricingCache(data) {
37
+ try {
38
+ const cachePath = getCachePath();
39
+ writeFileSync(cachePath, JSON.stringify(data), "utf-8");
40
+ } catch (err) {
41
+ }
42
+ }
43
+ async function fetchPricing() {
44
+ if (memoryCache) {
45
+ return memoryCache;
46
+ }
47
+ const cached2 = loadCachedPricing();
48
+ if (cached2) {
49
+ memoryCache = cached2;
50
+ return cached2;
51
+ }
52
+ const controller = new AbortController();
53
+ const timeoutId = setTimeout(() => controller.abort(), 2e3);
54
+ try {
55
+ const response = await fetch(PRICING_API_URL, { signal: controller.signal });
56
+ clearTimeout(timeoutId);
57
+ if (!response.ok) {
58
+ return null;
59
+ }
60
+ const data = await response.json();
61
+ if (data) {
62
+ savePricingCache(data);
63
+ memoryCache = data;
64
+ return data;
65
+ }
66
+ } catch (err) {
67
+ clearTimeout(timeoutId);
68
+ }
69
+ return null;
70
+ }
71
+ function determineProvider(modelId) {
72
+ const lower = modelId.toLowerCase();
73
+ if (lower.startsWith("gemini-") || lower.startsWith("gemma-")) return "google";
74
+ if (lower.startsWith("claude-")) return "anthropic";
75
+ if (lower.startsWith("gpt-") || lower.startsWith("o1") || lower.startsWith("o3")) return "openai";
76
+ return null;
77
+ }
78
+ function updateStaticModelsWithPricing(staticModels) {
79
+ fetchPricing().then((pricingData) => {
80
+ if (!pricingData) return;
81
+ for (const [modelId, modelObj] of Object.entries(staticModels)) {
82
+ const provider = determineProvider(modelId);
83
+ if (!provider || !pricingData[provider]?.models) continue;
84
+ let lookupId = modelId;
85
+ if (lookupId.endsWith("-thinking") && !pricingData[provider].models[lookupId]) {
86
+ lookupId = lookupId.replace("-thinking", "");
87
+ }
88
+ const apiModel = pricingData[provider].models[lookupId];
89
+ if (apiModel && apiModel.cost) {
90
+ const apiCost = apiModel.cost;
91
+ modelObj.cost = {
92
+ input: apiCost.input ?? modelObj.cost?.input ?? 0,
93
+ output: apiCost.output ?? modelObj.cost?.output ?? 0,
94
+ cache: {
95
+ read: apiCost.cache_read ?? modelObj.cost?.cache?.read ?? 0,
96
+ write: apiCost.cache_write ?? modelObj.cost?.cache?.write ?? 0
97
+ }
98
+ };
99
+ }
100
+ }
101
+ }).catch(() => {
102
+ });
103
+ }
104
+
7
105
  // src/constants.ts
8
106
  var AGY_PROVIDER_ID = "google-agy";
9
107
  var AGY_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
@@ -147,7 +245,7 @@ async function exchangeAgyWithVerifierInternal(code, verifier) {
147
245
  Authorization: `Bearer ${tokenPayload.access_token}`
148
246
  }
149
247
  });
150
- const userInfo = userInfoResponse.ok ? await userInfoResponse.json() : {};
248
+ const userInfo2 = userInfoResponse.ok ? await userInfoResponse.json() : {};
151
249
  const refreshToken = tokenPayload.refresh_token;
152
250
  if (!refreshToken) {
153
251
  return { type: "failed", error: "Missing refresh token in response" };
@@ -157,7 +255,7 @@ async function exchangeAgyWithVerifierInternal(code, verifier) {
157
255
  refresh: refreshToken,
158
256
  access: tokenPayload.access_token,
159
257
  expires: Date.now() + tokenPayload.expires_in * 1e3,
160
- email: userInfo.email
258
+ email: userInfo2.email
161
259
  };
162
260
  }
163
261
 
@@ -559,29 +657,29 @@ function clampDelay(delayMs) {
559
657
  }
560
658
 
561
659
  // src/sdk/retry/cooldown-store.ts
562
- import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, unlinkSync } from "fs";
563
- import { join, dirname } from "path";
564
- import { homedir, tmpdir } from "os";
660
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync, unlinkSync } from "fs";
661
+ import { join as join2, dirname } from "path";
662
+ import { homedir, tmpdir as tmpdir2 } from "os";
565
663
  var WRITE_THROTTLE_MS = 5e3;
566
664
  function getConfigDir() {
567
665
  const platform2 = process.platform;
568
666
  if (platform2 === "win32") {
569
- return join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "opencode");
667
+ return join2(process.env.APPDATA || join2(homedir(), "AppData", "Roaming"), "opencode");
570
668
  }
571
- const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
572
- return join(xdgConfig, "opencode");
669
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
670
+ return join2(xdgConfig, "opencode");
573
671
  }
574
672
  function getCooldownFilePath() {
575
- return join(getConfigDir(), "antigravity-retry-cooldowns.json");
673
+ return join2(getConfigDir(), "antigravity-retry-cooldowns.json");
576
674
  }
577
675
  function loadCooldowns() {
578
676
  const result = /* @__PURE__ */ new Map();
579
677
  try {
580
678
  const filePath = getCooldownFilePath();
581
- if (!existsSync(filePath)) {
679
+ if (!existsSync2(filePath)) {
582
680
  return result;
583
681
  }
584
- const content = readFileSync(filePath, "utf-8");
682
+ const content = readFileSync2(filePath, "utf-8");
585
683
  const data = JSON.parse(content);
586
684
  if (data.version !== "1.0") {
587
685
  return result;
@@ -600,7 +698,7 @@ function saveCooldowns(entries) {
600
698
  try {
601
699
  const filePath = getCooldownFilePath();
602
700
  const dir = dirname(filePath);
603
- if (!existsSync(dir)) {
701
+ if (!existsSync2(dir)) {
604
702
  mkdirSync(dir, { recursive: true });
605
703
  }
606
704
  const now = Date.now();
@@ -615,12 +713,12 @@ function saveCooldowns(entries) {
615
713
  entries: serializable,
616
714
  updatedAt: now
617
715
  };
618
- const tmpPath = join(tmpdir(), `antigravity-cooldowns-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
619
- writeFileSync(tmpPath, JSON.stringify(data), "utf-8");
716
+ const tmpPath = join2(tmpdir2(), `antigravity-cooldowns-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
717
+ writeFileSync2(tmpPath, JSON.stringify(data), "utf-8");
620
718
  try {
621
719
  renameSync(tmpPath, filePath);
622
720
  } catch {
623
- writeFileSync(filePath, readFileSync(tmpPath));
721
+ writeFileSync2(filePath, readFileSync2(tmpPath));
624
722
  try {
625
723
  unlinkSync(tmpPath);
626
724
  } catch {
@@ -1458,33 +1556,33 @@ function openBrowserUrl(url2) {
1458
1556
  import { createHash } from "crypto";
1459
1557
 
1460
1558
  // src/sdk/cache/signature-cache.ts
1461
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, appendFileSync } from "fs";
1462
- import { join as join2, dirname as dirname2 } from "path";
1463
- import { homedir as homedir2, tmpdir as tmpdir2 } from "os";
1559
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3, renameSync as renameSync2, unlinkSync as unlinkSync2, appendFileSync } from "fs";
1560
+ import { join as join3, dirname as dirname2 } from "path";
1561
+ import { homedir as homedir2, tmpdir as tmpdir3 } from "os";
1464
1562
  function getConfigDir2() {
1465
1563
  const platform2 = process.platform;
1466
1564
  if (platform2 === "win32") {
1467
- return join2(process.env.APPDATA || join2(homedir2(), "AppData", "Roaming"), "opencode");
1565
+ return join3(process.env.APPDATA || join3(homedir2(), "AppData", "Roaming"), "opencode");
1468
1566
  }
1469
- const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir2(), ".config");
1470
- return join2(xdgConfig, "opencode");
1567
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
1568
+ return join3(xdgConfig, "opencode");
1471
1569
  }
1472
1570
  function getCacheFilePath() {
1473
- return join2(getConfigDir2(), "antigravity-signature-cache.json");
1571
+ return join3(getConfigDir2(), "antigravity-signature-cache.json");
1474
1572
  }
1475
1573
  function ensureGitignoreSync(configDir) {
1476
- const gitignorePath = join2(configDir, ".gitignore");
1574
+ const gitignorePath = join3(configDir, ".gitignore");
1477
1575
  const entries = [".gitignore", "antigravity-signature-cache.json"];
1478
1576
  try {
1479
1577
  let content = "";
1480
- if (existsSync2(gitignorePath)) {
1481
- content = readFileSync2(gitignorePath, "utf-8");
1578
+ if (existsSync3(gitignorePath)) {
1579
+ content = readFileSync3(gitignorePath, "utf-8");
1482
1580
  }
1483
1581
  const existingLines = content.split("\n").map((line) => line.trim());
1484
1582
  const missing = entries.filter((e) => !existingLines.includes(e));
1485
1583
  if (missing.length === 0) return;
1486
1584
  if (content === "") {
1487
- writeFileSync2(gitignorePath, missing.join("\n") + "\n", "utf-8");
1585
+ writeFileSync3(gitignorePath, missing.join("\n") + "\n", "utf-8");
1488
1586
  } else {
1489
1587
  const suffix = content.endsWith("\n") ? "" : "\n";
1490
1588
  appendFileSync(gitignorePath, suffix + missing.join("\n") + "\n", "utf-8");
@@ -1660,10 +1758,10 @@ var SignatureCache = class {
1660
1758
  */
1661
1759
  loadFromDisk() {
1662
1760
  try {
1663
- if (!existsSync2(this.cacheFilePath)) {
1761
+ if (!existsSync3(this.cacheFilePath)) {
1664
1762
  return;
1665
1763
  }
1666
- const content = readFileSync2(this.cacheFilePath, "utf-8");
1764
+ const content = readFileSync3(this.cacheFilePath, "utf-8");
1667
1765
  const data = JSON.parse(content);
1668
1766
  if (data.version !== "1.0") {
1669
1767
  return;
@@ -1691,15 +1789,15 @@ var SignatureCache = class {
1691
1789
  saveToDisk() {
1692
1790
  try {
1693
1791
  const dir = dirname2(this.cacheFilePath);
1694
- if (!existsSync2(dir)) {
1792
+ if (!existsSync3(dir)) {
1695
1793
  mkdirSync2(dir, { recursive: true });
1696
1794
  }
1697
1795
  ensureGitignoreSync(dir);
1698
1796
  const now = Date.now();
1699
1797
  let existingEntries = {};
1700
- if (existsSync2(this.cacheFilePath)) {
1798
+ if (existsSync3(this.cacheFilePath)) {
1701
1799
  try {
1702
- const content = readFileSync2(this.cacheFilePath, "utf-8");
1800
+ const content = readFileSync3(this.cacheFilePath, "utf-8");
1703
1801
  const data = JSON.parse(content);
1704
1802
  existingEntries = data.entries || {};
1705
1803
  } catch {
@@ -1735,12 +1833,12 @@ var SignatureCache = class {
1735
1833
  last_write: now
1736
1834
  }
1737
1835
  };
1738
- const tmpPath = join2(tmpdir2(), `antigravity-cache-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
1739
- writeFileSync2(tmpPath, JSON.stringify(cacheData, null, 2), "utf-8");
1836
+ const tmpPath = join3(tmpdir3(), `antigravity-cache-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
1837
+ writeFileSync3(tmpPath, JSON.stringify(cacheData, null, 2), "utf-8");
1740
1838
  try {
1741
1839
  renameSync2(tmpPath, this.cacheFilePath);
1742
1840
  } catch {
1743
- writeFileSync2(this.cacheFilePath, readFileSync2(tmpPath));
1841
+ writeFileSync3(this.cacheFilePath, readFileSync3(tmpPath));
1744
1842
  try {
1745
1843
  unlinkSync2(tmpPath);
1746
1844
  } catch {
@@ -1894,9 +1992,9 @@ function getLatestSignature(sessionId) {
1894
1992
  }
1895
1993
 
1896
1994
  // src/sdk/request/turn-state-tracker.ts
1897
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync3 } from "fs";
1898
- import { join as join3, dirname as dirname3 } from "path";
1899
- import { homedir as homedir3, tmpdir as tmpdir3 } from "os";
1995
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync4, renameSync as renameSync3, unlinkSync as unlinkSync3 } from "fs";
1996
+ import { join as join4, dirname as dirname3 } from "path";
1997
+ import { homedir as homedir3, tmpdir as tmpdir4 } from "os";
1900
1998
 
1901
1999
  // src/sdk/request/thinking.ts
1902
2000
  import { createHash as createHash2 } from "crypto";
@@ -2319,22 +2417,22 @@ var WRITE_THROTTLE_MS2 = 5e3;
2319
2417
  function getConfigDir3() {
2320
2418
  const platform2 = process.platform;
2321
2419
  if (platform2 === "win32") {
2322
- return join3(process.env.APPDATA || join3(homedir3(), "AppData", "Roaming"), "opencode");
2420
+ return join4(process.env.APPDATA || join4(homedir3(), "AppData", "Roaming"), "opencode");
2323
2421
  }
2324
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir3(), ".config");
2325
- return join3(xdgConfig, "opencode");
2422
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join4(homedir3(), ".config");
2423
+ return join4(xdgConfig, "opencode");
2326
2424
  }
2327
2425
  function getTurnStateFilePath() {
2328
- return join3(getConfigDir3(), "antigravity-turn-states.json");
2426
+ return join4(getConfigDir3(), "antigravity-turn-states.json");
2329
2427
  }
2330
2428
  function loadTurnStatesFromDisk() {
2331
2429
  const result = /* @__PURE__ */ new Map();
2332
2430
  try {
2333
2431
  const filePath = getTurnStateFilePath();
2334
- if (!existsSync3(filePath)) {
2432
+ if (!existsSync4(filePath)) {
2335
2433
  return result;
2336
2434
  }
2337
- const content = readFileSync3(filePath, "utf-8");
2435
+ const content = readFileSync4(filePath, "utf-8");
2338
2436
  const data = JSON.parse(content);
2339
2437
  if (data.version !== "1.0") {
2340
2438
  return result;
@@ -2354,7 +2452,7 @@ function saveTurnStatesToDisk(entries) {
2354
2452
  try {
2355
2453
  const filePath = getTurnStateFilePath();
2356
2454
  const dir = dirname3(filePath);
2357
- if (!existsSync3(dir)) {
2455
+ if (!existsSync4(dir)) {
2358
2456
  mkdirSync3(dir, { recursive: true });
2359
2457
  }
2360
2458
  const now = Date.now();
@@ -2370,12 +2468,12 @@ function saveTurnStatesToDisk(entries) {
2370
2468
  entries: serializable,
2371
2469
  updatedAt: now
2372
2470
  };
2373
- const tmpPath = join3(tmpdir3(), `antigravity-turn-states-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
2374
- writeFileSync3(tmpPath, JSON.stringify(data), "utf-8");
2471
+ const tmpPath = join4(tmpdir4(), `antigravity-turn-states-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
2472
+ writeFileSync4(tmpPath, JSON.stringify(data), "utf-8");
2375
2473
  try {
2376
2474
  renameSync3(tmpPath, filePath);
2377
2475
  } catch {
2378
- writeFileSync3(filePath, readFileSync3(tmpPath));
2476
+ writeFileSync4(filePath, readFileSync4(tmpPath));
2379
2477
  try {
2380
2478
  unlinkSync3(tmpPath);
2381
2479
  } catch {
@@ -17869,20 +17967,20 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
17869
17967
  }
17870
17968
 
17871
17969
  // src/sdk/chat-logger.ts
17872
- import { createWriteStream, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
17873
- import { join as join4 } from "path";
17970
+ import { createWriteStream, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
17971
+ import { join as join5 } from "path";
17874
17972
  import { cwd } from "process";
17875
17973
  function createChatLogger() {
17876
17974
  if (process.env.AGY_LOG !== "1") {
17877
17975
  return null;
17878
17976
  }
17879
17977
  try {
17880
- const logDir = join4(cwd(), "agy_chat_log");
17881
- if (!existsSync4(logDir)) {
17978
+ const logDir = join5(cwd(), "agy_chat_log");
17979
+ if (!existsSync5(logDir)) {
17882
17980
  mkdirSync4(logDir, { recursive: true });
17883
17981
  }
17884
17982
  const timestamp = Date.now();
17885
- const logFile = join4(logDir, `${timestamp}.log`);
17983
+ const logFile = join5(logDir, `${timestamp}.log`);
17886
17984
  const stream = createWriteStream(logFile, { flags: "w", encoding: "utf8" });
17887
17985
  return new ChatLoggerImpl(stream);
17888
17986
  } catch (error45) {
@@ -18231,6 +18329,7 @@ function resolveModelTier(baseModelId, init) {
18231
18329
  }
18232
18330
  var AgyCLIOAuthPlugin = async ({ client }) => {
18233
18331
  let latestConfig;
18332
+ updateStaticModelsWithPricing(STATIC_MODELS);
18234
18333
  const getModelsList = (provider) => {
18235
18334
  const userModels = provider.models || {};
18236
18335
  const clonedStaticModels = JSON.parse(JSON.stringify(STATIC_MODELS));
@@ -18491,7 +18590,13 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
18491
18590
  }
18492
18591
  };
18493
18592
  }
18494
- return getModelsList(provider);
18593
+ const models = getModelsList(provider);
18594
+ for (const [modelId, model] of Object.entries(models)) {
18595
+ if (STATIC_MODELS[modelId] && STATIC_MODELS[modelId].cost) {
18596
+ model.cost = STATIC_MODELS[modelId].cost;
18597
+ }
18598
+ }
18599
+ return models;
18495
18600
  }
18496
18601
  }
18497
18602
  };