@anthonyhaussman/opencode-agy-auth 1.2.12 → 1.2.13-alpha.1

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
@@ -268,7 +268,7 @@ function createAgyActivityRequestId() {
268
268
  import os from "os";
269
269
 
270
270
  // src/sdk/agy-cli-version.ts
271
- var AGY_CLI_VERSION = "1.2.12";
271
+ var AGY_CLI_VERSION = "1.2.13";
272
272
 
273
273
  // src/sdk/user-agent.ts
274
274
  var cachedUserAgent = null;
@@ -579,6 +579,12 @@ async function resolveQuotaResetDelay(accessToken, projectId, model, userAgentMo
579
579
  return null;
580
580
  }
581
581
  }
582
+ var retryInternals = {
583
+ parseRetryDelayValue,
584
+ parseRetryDelayFromMessage,
585
+ findResetTimeForModel,
586
+ resolveQuotaResetDelay
587
+ };
582
588
 
583
589
  // src/sdk/retry/helpers.ts
584
590
  var DEFAULT_MAX_ATTEMPTS = 3;
@@ -1575,7 +1581,11 @@ function createOAuthAuthorizeMethod(options) {
1575
1581
  const isHeadless = !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY || process.env.OPENCODE_HEADLESS);
1576
1582
  const authorization = await authorizeAgy();
1577
1583
  if (!isHeadless) {
1578
- openBrowserUrl(authorization.url);
1584
+ if (options?.openBrowser) {
1585
+ options.openBrowser(authorization.url);
1586
+ } else {
1587
+ openBrowserUrl(authorization.url);
1588
+ }
1579
1589
  }
1580
1590
  return {
1581
1591
  url: authorization.url,
@@ -1629,16 +1639,23 @@ function parseOAuthCallbackInput(input) {
1629
1639
  }
1630
1640
  return { code: trimmed };
1631
1641
  }
1642
+ function defaultOpenBrowserLauncher(command, args) {
1643
+ const child = spawn(command, args, {
1644
+ stdio: "ignore",
1645
+ detached: true
1646
+ });
1647
+ child.unref?.();
1648
+ }
1649
+ var openBrowserLauncher = defaultOpenBrowserLauncher;
1632
1650
  function openBrowserUrl(url2) {
1651
+ if ((process.env.NODE_ENV === "test" || process.env.VITEST) && openBrowserLauncher === defaultOpenBrowserLauncher) {
1652
+ return;
1653
+ }
1633
1654
  try {
1634
1655
  const platform2 = process.platform;
1635
1656
  const command = platform2 === "darwin" ? "open" : platform2 === "win32" ? "rundll32" : "xdg-open";
1636
1657
  const args = platform2 === "win32" ? ["url.dll,FileProtocolHandler", url2] : [url2];
1637
- const child = spawn(command, args, {
1638
- stdio: "ignore",
1639
- detached: true
1640
- });
1641
- child.unref?.();
1658
+ openBrowserLauncher(command, args);
1642
1659
  } catch {
1643
1660
  }
1644
1661
  }
@@ -15320,6 +15337,12 @@ function formatRelativeResetTime(resetTime) {
15320
15337
 
15321
15338
  // src/plugin/quota.ts
15322
15339
  var AGY_QUOTA_TOOL_NAME = "agy_quota";
15340
+ var AGY_V2_QUOTA_COMMAND = "agy-quota";
15341
+ var AGY_V2_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
15342
+
15343
+ Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
15344
+ Do not call other tools.
15345
+ `;
15323
15346
  function createAgyQuotaTool({
15324
15347
  client,
15325
15348
  getAuthResolver,
@@ -15559,6 +15582,12 @@ function splitModelVariant(modelId) {
15559
15582
 
15560
15583
  // src/plugin/quota-summary.ts
15561
15584
  var AGY_QUOTA_SUMMARY_TOOL_NAME = "agy_quota_summary";
15585
+ var AGY_V2_QUOTA_SUMMARY_COMMAND = "agy-quota-summary";
15586
+ var AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
15587
+
15588
+ Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
15589
+ Do not call other tools.
15590
+ `;
15562
15591
  function createAgyQuotaSummaryTool({
15563
15592
  client,
15564
15593
  getAuthResolver,
@@ -16043,13 +16072,12 @@ var models_default = {
16043
16072
  }
16044
16073
  },
16045
16074
  experimentIds: [
16046
- 106140402,
16075
+ 106329237,
16047
16076
  106760947,
16048
16077
  106519115,
16049
16078
  105979552,
16050
16079
  105979574,
16051
16080
  106015333,
16052
- 106705494,
16053
16081
  106568772,
16054
16082
  105867471,
16055
16083
  106749606,
@@ -16149,7 +16177,7 @@ var models_default = {
16149
16177
  modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16150
16178
  quotaInfo: {
16151
16179
  remainingFraction: 1,
16152
- resetTime: "2026-09-27T22:46:11Z"
16180
+ resetTime: "2026-09-29T10:26:06Z"
16153
16181
  },
16154
16182
  recommended: true,
16155
16183
  supportedMimeTypes: {
@@ -16188,7 +16216,7 @@ var models_default = {
16188
16216
  modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16189
16217
  quotaInfo: {
16190
16218
  remainingFraction: 1,
16191
- resetTime: "2026-09-27T22:46:11Z"
16219
+ resetTime: "2026-09-29T10:26:06Z"
16192
16220
  },
16193
16221
  recommended: true,
16194
16222
  supportedMimeTypes: {
@@ -16224,8 +16252,8 @@ var models_default = {
16224
16252
  },
16225
16253
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16226
16254
  quotaInfo: {
16227
- remainingFraction: 0.9403093,
16228
- resetTime: "2026-09-27T21:20:29Z"
16255
+ remainingFraction: 0.9730856,
16256
+ resetTime: "2026-09-29T10:22:45Z"
16229
16257
  },
16230
16258
  recommended: true,
16231
16259
  supportedMimeTypes: {
@@ -16307,8 +16335,8 @@ var models_default = {
16307
16335
  },
16308
16336
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16309
16337
  quotaInfo: {
16310
- remainingFraction: 0.9403093,
16311
- resetTime: "2026-09-27T21:20:29Z"
16338
+ remainingFraction: 0.9730856,
16339
+ resetTime: "2026-09-29T10:22:45Z"
16312
16340
  },
16313
16341
  recommended: true,
16314
16342
  supportedMimeTypes: {
@@ -16390,8 +16418,8 @@ var models_default = {
16390
16418
  },
16391
16419
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16392
16420
  quotaInfo: {
16393
- remainingFraction: 0.9403093,
16394
- resetTime: "2026-09-27T21:20:29Z"
16421
+ remainingFraction: 0.9730856,
16422
+ resetTime: "2026-09-29T10:22:45Z"
16395
16423
  },
16396
16424
  recommended: true,
16397
16425
  supportedMimeTypes: {
@@ -16470,8 +16498,8 @@ var models_default = {
16470
16498
  },
16471
16499
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16472
16500
  quotaInfo: {
16473
- remainingFraction: 0.9403093,
16474
- resetTime: "2026-09-27T21:20:29Z"
16501
+ remainingFraction: 0.9730856,
16502
+ resetTime: "2026-09-29T10:22:45Z"
16475
16503
  },
16476
16504
  recommended: true,
16477
16505
  requiresImageOutputOutsideFunctionResponses: true,
@@ -16551,8 +16579,8 @@ var models_default = {
16551
16579
  },
16552
16580
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16553
16581
  quotaInfo: {
16554
- remainingFraction: 0.9403093,
16555
- resetTime: "2026-09-27T21:20:29Z"
16582
+ remainingFraction: 0.9730856,
16583
+ resetTime: "2026-09-29T10:22:45Z"
16556
16584
  },
16557
16585
  recommended: true,
16558
16586
  supportedMimeTypes: {
@@ -16656,8 +16684,8 @@ var models_default = {
16656
16684
  },
16657
16685
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16658
16686
  quotaInfo: {
16659
- remainingFraction: 0.9403093,
16660
- resetTime: "2026-09-27T21:20:29Z"
16687
+ remainingFraction: 0.9730856,
16688
+ resetTime: "2026-09-29T10:22:45Z"
16661
16689
  },
16662
16690
  recommended: true,
16663
16691
  supportedMimeTypes: {
@@ -16726,8 +16754,8 @@ var models_default = {
16726
16754
  model: "MODEL_PLACEHOLDER_M21",
16727
16755
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16728
16756
  quotaInfo: {
16729
- remainingFraction: 0.9403093,
16730
- resetTime: "2026-09-27T21:20:29Z"
16757
+ remainingFraction: 0.9730856,
16758
+ resetTime: "2026-09-29T10:22:45Z"
16731
16759
  }
16732
16760
  },
16733
16761
  "gemini-3.1-flash-lite": {
@@ -16745,8 +16773,8 @@ var models_default = {
16745
16773
  },
16746
16774
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16747
16775
  quotaInfo: {
16748
- remainingFraction: 0.9403093,
16749
- resetTime: "2026-09-27T21:20:29Z"
16776
+ remainingFraction: 0.9730856,
16777
+ resetTime: "2026-09-29T10:22:45Z"
16750
16778
  }
16751
16779
  },
16752
16780
  "gemini-3.1-pro-high": {
@@ -16777,8 +16805,8 @@ var models_default = {
16777
16805
  },
16778
16806
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16779
16807
  quotaInfo: {
16780
- remainingFraction: 0.9403093,
16781
- resetTime: "2026-09-27T21:20:29Z"
16808
+ remainingFraction: 0.9730856,
16809
+ resetTime: "2026-09-29T10:22:45Z"
16782
16810
  },
16783
16811
  recommended: true,
16784
16812
  supportedMimeTypes: {
@@ -16868,8 +16896,8 @@ var models_default = {
16868
16896
  },
16869
16897
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16870
16898
  quotaInfo: {
16871
- remainingFraction: 0.9403093,
16872
- resetTime: "2026-09-27T21:20:29Z"
16899
+ remainingFraction: 0.9730856,
16900
+ resetTime: "2026-09-29T10:22:45Z"
16873
16901
  },
16874
16902
  recommended: true,
16875
16903
  supportedMimeTypes: {
@@ -16973,8 +17001,8 @@ var models_default = {
16973
17001
  },
16974
17002
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16975
17003
  quotaInfo: {
16976
- remainingFraction: 0.9403093,
16977
- resetTime: "2026-09-27T21:20:29Z"
17004
+ remainingFraction: 0.9730856,
17005
+ resetTime: "2026-09-29T10:22:45Z"
16978
17006
  },
16979
17007
  recommended: true,
16980
17008
  supportedMimeTypes: {
@@ -17056,8 +17084,8 @@ var models_default = {
17056
17084
  },
17057
17085
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17058
17086
  quotaInfo: {
17059
- remainingFraction: 0.9403093,
17060
- resetTime: "2026-09-27T21:20:29Z"
17087
+ remainingFraction: 0.9730856,
17088
+ resetTime: "2026-09-29T10:22:45Z"
17061
17089
  },
17062
17090
  recommended: true,
17063
17091
  supportedMimeTypes: {
@@ -17163,8 +17191,8 @@ var models_default = {
17163
17191
  },
17164
17192
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17165
17193
  quotaInfo: {
17166
- remainingFraction: 0.9403093,
17167
- resetTime: "2026-09-27T21:20:29Z"
17194
+ remainingFraction: 0.9730856,
17195
+ resetTime: "2026-09-29T10:22:45Z"
17168
17196
  },
17169
17197
  recommended: true,
17170
17198
  supportedMimeTypes: {
@@ -17282,8 +17310,8 @@ var models_default = {
17282
17310
  },
17283
17311
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17284
17312
  quotaInfo: {
17285
- remainingFraction: 0.9403093,
17286
- resetTime: "2026-09-27T21:20:29Z"
17313
+ remainingFraction: 0.9730856,
17314
+ resetTime: "2026-09-29T10:22:45Z"
17287
17315
  },
17288
17316
  recommended: true,
17289
17317
  supportedMimeTypes: {
@@ -17401,8 +17429,8 @@ var models_default = {
17401
17429
  },
17402
17430
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17403
17431
  quotaInfo: {
17404
- remainingFraction: 0.9403093,
17405
- resetTime: "2026-09-27T21:20:29Z"
17432
+ remainingFraction: 0.9730856,
17433
+ resetTime: "2026-09-29T10:22:45Z"
17406
17434
  },
17407
17435
  recommended: true,
17408
17436
  supportedMimeTypes: {
@@ -17520,8 +17548,8 @@ var models_default = {
17520
17548
  },
17521
17549
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17522
17550
  quotaInfo: {
17523
- remainingFraction: 0.9403093,
17524
- resetTime: "2026-09-27T21:20:29Z"
17551
+ remainingFraction: 0.9730856,
17552
+ resetTime: "2026-09-29T10:22:45Z"
17525
17553
  },
17526
17554
  recommended: true,
17527
17555
  supportedMimeTypes: {
@@ -17638,8 +17666,8 @@ var models_default = {
17638
17666
  },
17639
17667
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17640
17668
  quotaInfo: {
17641
- remainingFraction: 0.9403093,
17642
- resetTime: "2026-09-27T21:20:29Z"
17669
+ remainingFraction: 0.9730856,
17670
+ resetTime: "2026-09-29T10:22:45Z"
17643
17671
  },
17644
17672
  recommended: true,
17645
17673
  supportedMimeTypes: {
@@ -17749,8 +17777,8 @@ var models_default = {
17749
17777
  },
17750
17778
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17751
17779
  quotaInfo: {
17752
- remainingFraction: 0.9403093,
17753
- resetTime: "2026-09-27T21:20:29Z"
17780
+ remainingFraction: 0.9730856,
17781
+ resetTime: "2026-09-29T10:22:45Z"
17754
17782
  },
17755
17783
  recommended: true,
17756
17784
  supportedMimeTypes: {
@@ -17862,8 +17890,8 @@ var models_default = {
17862
17890
  },
17863
17891
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17864
17892
  quotaInfo: {
17865
- remainingFraction: 0.9403093,
17866
- resetTime: "2026-09-27T21:20:29Z"
17893
+ remainingFraction: 0.9730856,
17894
+ resetTime: "2026-09-29T10:22:45Z"
17867
17895
  },
17868
17896
  recommended: true,
17869
17897
  supportedMimeTypes: {
@@ -17975,8 +18003,8 @@ var models_default = {
17975
18003
  },
17976
18004
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17977
18005
  quotaInfo: {
17978
- remainingFraction: 0.9403093,
17979
- resetTime: "2026-09-27T21:20:29Z"
18006
+ remainingFraction: 0.9730856,
18007
+ resetTime: "2026-09-29T10:22:45Z"
17980
18008
  },
17981
18009
  recommended: true,
17982
18010
  supportedMimeTypes: {
@@ -18087,8 +18115,8 @@ var models_default = {
18087
18115
  },
18088
18116
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18089
18117
  quotaInfo: {
18090
- remainingFraction: 0.9403093,
18091
- resetTime: "2026-09-27T21:20:29Z"
18118
+ remainingFraction: 0.9730856,
18119
+ resetTime: "2026-09-29T10:22:45Z"
18092
18120
  },
18093
18121
  recommended: true,
18094
18122
  supportedMimeTypes: {
@@ -18198,8 +18226,8 @@ var models_default = {
18198
18226
  },
18199
18227
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18200
18228
  quotaInfo: {
18201
- remainingFraction: 0.9403093,
18202
- resetTime: "2026-09-27T21:20:29Z"
18229
+ remainingFraction: 0.9730856,
18230
+ resetTime: "2026-09-29T10:22:45Z"
18203
18231
  },
18204
18232
  recommended: true,
18205
18233
  supportedMimeTypes: {
@@ -18311,8 +18339,8 @@ var models_default = {
18311
18339
  },
18312
18340
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18313
18341
  quotaInfo: {
18314
- remainingFraction: 0.9403093,
18315
- resetTime: "2026-09-27T21:20:29Z"
18342
+ remainingFraction: 0.9730856,
18343
+ resetTime: "2026-09-29T10:22:45Z"
18316
18344
  },
18317
18345
  recommended: true,
18318
18346
  supportedMimeTypes: {
@@ -18424,8 +18452,8 @@ var models_default = {
18424
18452
  },
18425
18453
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18426
18454
  quotaInfo: {
18427
- remainingFraction: 0.9403093,
18428
- resetTime: "2026-09-27T21:20:29Z"
18455
+ remainingFraction: 0.9730856,
18456
+ resetTime: "2026-09-29T10:22:45Z"
18429
18457
  },
18430
18458
  recommended: true,
18431
18459
  supportedMimeTypes: {
@@ -18536,8 +18564,8 @@ var models_default = {
18536
18564
  },
18537
18565
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18538
18566
  quotaInfo: {
18539
- remainingFraction: 0.9403093,
18540
- resetTime: "2026-09-27T21:20:29Z"
18567
+ remainingFraction: 0.9730856,
18568
+ resetTime: "2026-09-29T10:22:45Z"
18541
18569
  },
18542
18570
  recommended: true,
18543
18571
  supportedMimeTypes: {
@@ -18626,8 +18654,8 @@ var models_default = {
18626
18654
  },
18627
18655
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18628
18656
  quotaInfo: {
18629
- remainingFraction: 0.9403093,
18630
- resetTime: "2026-09-27T21:20:29Z"
18657
+ remainingFraction: 0.9730856,
18658
+ resetTime: "2026-09-29T10:22:45Z"
18631
18659
  },
18632
18660
  recommended: true,
18633
18661
  supportedMimeTypes: {
@@ -18704,7 +18732,7 @@ var models_default = {
18704
18732
  modelProvider: "MODEL_PROVIDER_OPENAI",
18705
18733
  quotaInfo: {
18706
18734
  remainingFraction: 1,
18707
- resetTime: "2026-09-27T22:46:11Z"
18735
+ resetTime: "2026-09-29T10:26:06Z"
18708
18736
  },
18709
18737
  recommended: true,
18710
18738
  supportsThinking: true,
@@ -19776,9 +19804,14 @@ function normalizeToolSchemaTypes(tools, toolMapper) {
19776
19804
  fn.name = toolMapper ? toolMapper.toGemini(fn.name) : sanitizeToolName(fn.name);
19777
19805
  }
19778
19806
  if (fn) {
19807
+ if (!fn.parameters) {
19808
+ fn.parameters = fn.parameters_json_schema ?? fn.parametersJsonSchema;
19809
+ }
19779
19810
  if (!fn.parameters) {
19780
19811
  fn.parameters = { type: "OBJECT", properties: {} };
19781
19812
  }
19813
+ delete fn.parameters_json_schema;
19814
+ delete fn.parametersJsonSchema;
19782
19815
  sanitizeSchema(fn.parameters);
19783
19816
  }
19784
19817
  }
@@ -20203,22 +20236,81 @@ var ChatLoggerImpl = class {
20203
20236
  }
20204
20237
  };
20205
20238
 
20206
- // src/plugin.ts
20207
- var AGY_QUOTA_COMMAND = "agyquota";
20208
- var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
20209
-
20210
- Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
20211
- Do not call other tools.
20212
- `;
20213
- var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
20214
- var AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
20239
+ // src/plugin/headers.ts
20240
+ function getSafeHeader(headers, key) {
20241
+ if (!headers) {
20242
+ return void 0;
20243
+ }
20244
+ const targetKey = key.toLowerCase();
20245
+ if (typeof headers.get === "function") {
20246
+ try {
20247
+ return headers.get(targetKey) || void 0;
20248
+ } catch {
20249
+ }
20250
+ }
20251
+ if (Array.isArray(headers)) {
20252
+ const found = headers.find((item) => {
20253
+ if (Array.isArray(item) && typeof item[0] === "string") {
20254
+ return item[0].toLowerCase() === targetKey;
20255
+ }
20256
+ return false;
20257
+ });
20258
+ return found ? String(found[1]) : void 0;
20259
+ }
20260
+ if (typeof headers === "object") {
20261
+ const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
20262
+ return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
20263
+ }
20264
+ return void 0;
20265
+ }
20266
+ function setSafeHeaders(initHeaders, newHeaders) {
20267
+ if (typeof globalThis.Headers !== "undefined") {
20268
+ const headers = new globalThis.Headers(initHeaders ?? {});
20269
+ for (const [k, v] of Object.entries(newHeaders)) {
20270
+ headers.set(k, v);
20271
+ }
20272
+ return headers;
20273
+ }
20274
+ if (Array.isArray(initHeaders)) {
20275
+ const nextHeaders2 = [...initHeaders];
20276
+ for (const [k, v] of Object.entries(newHeaders)) {
20277
+ const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
20278
+ if (idx !== -1) {
20279
+ nextHeaders2[idx] = [k, v];
20280
+ } else {
20281
+ nextHeaders2.push([k, v]);
20282
+ }
20283
+ }
20284
+ return nextHeaders2;
20285
+ }
20286
+ const nextHeaders = {};
20287
+ if (initHeaders && typeof initHeaders === "object") {
20288
+ for (const [k, v] of Object.entries(initHeaders)) {
20289
+ nextHeaders[k] = String(v);
20290
+ }
20291
+ }
20292
+ for (const [k, v] of Object.entries(newHeaders)) {
20293
+ const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
20294
+ if (existingKey) {
20295
+ nextHeaders[existingKey] = v;
20296
+ } else {
20297
+ nextHeaders[k] = v;
20298
+ }
20299
+ }
20300
+ return nextHeaders;
20301
+ }
20302
+ function toUrlString(value) {
20303
+ if (typeof value === "string") {
20304
+ return value;
20305
+ }
20306
+ const candidate = value.url;
20307
+ if (candidate) {
20308
+ return candidate;
20309
+ }
20310
+ return value.toString();
20311
+ }
20215
20312
 
20216
- Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
20217
- Do not call other tools.
20218
- `;
20219
- var latestAgyAuthResolver;
20220
- var latestAgyConfiguredProjectId;
20221
- var latestAgyUserAgentModel;
20313
+ // src/plugin/tier.ts
20222
20314
  var STATIC_MODELS_SIMPLE = {
20223
20315
  "gemini-3.8-flash": {
20224
20316
  name: "Gemini 3.8 Flash",
@@ -20306,6 +20398,39 @@ var TIER_MAPPING = {
20306
20398
  high: "gemini-3.1-pro-high"
20307
20399
  }
20308
20400
  };
20401
+ function resolveModelTier(baseModelId, headersOrInit) {
20402
+ const parts = baseModelId.split("@");
20403
+ const base = parts[0] || "";
20404
+ const suffixTier = parts[1]?.toLowerCase();
20405
+ const mapping = TIER_MAPPING[base];
20406
+ if (!mapping) {
20407
+ return baseModelId;
20408
+ }
20409
+ const rawHeaders = headersOrInit && typeof headersOrInit === "object" && "headers" in headersOrInit ? headersOrInit.headers : headersOrInit;
20410
+ const headerTier = getSafeHeader(rawHeaders, "x-agy-tier")?.toLowerCase() || null;
20411
+ const requestedTier = headerTier || suffixTier;
20412
+ if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
20413
+ return mapping[requestedTier] || baseModelId;
20414
+ }
20415
+ return mapping["medium"] ?? mapping["high"] ?? baseModelId;
20416
+ }
20417
+
20418
+ // src/plugin.ts
20419
+ var AGY_QUOTA_COMMAND = "agyquota";
20420
+ var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
20421
+
20422
+ Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
20423
+ Do not call other tools.
20424
+ `;
20425
+ var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
20426
+ var AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
20427
+
20428
+ Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
20429
+ Do not call other tools.
20430
+ `;
20431
+ var latestAgyAuthResolver;
20432
+ var latestAgyConfiguredProjectId;
20433
+ var latestAgyUserAgentModel;
20309
20434
  var buildModelFromSimple = (modelId, simple) => {
20310
20435
  const isClaude = modelId.startsWith("claude-");
20311
20436
  const isGpt = modelId.startsWith("gpt-");
@@ -20399,83 +20524,6 @@ var STATIC_MODELS = {};
20399
20524
  for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
20400
20525
  STATIC_MODELS[modelId] = buildModelFromSimple(modelId, simple);
20401
20526
  }
20402
- function getSafeHeader(headers, key) {
20403
- if (!headers) {
20404
- return void 0;
20405
- }
20406
- const targetKey = key.toLowerCase();
20407
- if (typeof headers.get === "function") {
20408
- try {
20409
- return headers.get(targetKey) || void 0;
20410
- } catch {
20411
- }
20412
- }
20413
- if (Array.isArray(headers)) {
20414
- const found = headers.find((item) => {
20415
- if (Array.isArray(item) && typeof item[0] === "string") {
20416
- return item[0].toLowerCase() === targetKey;
20417
- }
20418
- return false;
20419
- });
20420
- return found ? String(found[1]) : void 0;
20421
- }
20422
- if (typeof headers === "object") {
20423
- const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
20424
- return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
20425
- }
20426
- return void 0;
20427
- }
20428
- function setSafeHeaders(initHeaders, newHeaders) {
20429
- if (typeof globalThis.Headers !== "undefined") {
20430
- const headers = new globalThis.Headers(initHeaders ?? {});
20431
- for (const [k, v] of Object.entries(newHeaders)) {
20432
- headers.set(k, v);
20433
- }
20434
- return headers;
20435
- }
20436
- if (Array.isArray(initHeaders)) {
20437
- const nextHeaders2 = [...initHeaders];
20438
- for (const [k, v] of Object.entries(newHeaders)) {
20439
- const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
20440
- if (idx !== -1) {
20441
- nextHeaders2[idx] = [k, v];
20442
- } else {
20443
- nextHeaders2.push([k, v]);
20444
- }
20445
- }
20446
- return nextHeaders2;
20447
- }
20448
- const nextHeaders = {};
20449
- if (initHeaders && typeof initHeaders === "object") {
20450
- for (const [k, v] of Object.entries(initHeaders)) {
20451
- nextHeaders[k] = String(v);
20452
- }
20453
- }
20454
- for (const [k, v] of Object.entries(newHeaders)) {
20455
- const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
20456
- if (existingKey) {
20457
- nextHeaders[existingKey] = v;
20458
- } else {
20459
- nextHeaders[k] = v;
20460
- }
20461
- }
20462
- return nextHeaders;
20463
- }
20464
- function resolveModelTier(baseModelId, init) {
20465
- const parts = baseModelId.split("@");
20466
- const base = parts[0] || "";
20467
- const suffixTier = parts[1]?.toLowerCase();
20468
- const mapping = TIER_MAPPING[base];
20469
- if (!mapping) {
20470
- return baseModelId;
20471
- }
20472
- const headerTier = getSafeHeader(init?.headers, "x-agy-tier")?.toLowerCase() || null;
20473
- const requestedTier = headerTier || suffixTier;
20474
- if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
20475
- return mapping[requestedTier] || baseModelId;
20476
- }
20477
- return mapping["medium"] ?? mapping["high"];
20478
- }
20479
20527
  var AgyCLIOAuthPlugin = async ({ client }) => {
20480
20528
  let latestConfig;
20481
20529
  updateStaticModelsWithPricing(STATIC_MODELS);
@@ -20803,25 +20851,782 @@ async function ensureProjectContextOrThrow(authRecord, client, configuredProject
20803
20851
  throw error45;
20804
20852
  }
20805
20853
  }
20806
- function toUrlString(value) {
20807
- if (typeof value === "string") {
20808
- return value;
20854
+
20855
+ // src/plugin/types.ts
20856
+ function defineOpenCodeV2Plugin(def) {
20857
+ return def;
20858
+ }
20859
+
20860
+ // src/plugin/v2-storage.ts
20861
+ import { closeSync, existsSync as existsSync6, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync5, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync5 } from "fs";
20862
+ import { randomUUID as randomUUID4 } from "crypto";
20863
+ import { homedir as homedir4 } from "os";
20864
+ import { join as join6 } from "path";
20865
+ var storedAuthOverrideForTesting = void 0;
20866
+ function loadStoredAuthFromJson() {
20867
+ if (storedAuthOverrideForTesting !== void 0) {
20868
+ return storedAuthOverrideForTesting;
20869
+ }
20870
+ const authPath = join6(homedir4(), ".local", "share", "opencode", "auth.json");
20871
+ try {
20872
+ if (existsSync6(authPath)) {
20873
+ const content = readFileSync5(authPath, "utf8");
20874
+ const data = JSON.parse(content);
20875
+ return data?.[AGY_PROVIDER_ID];
20876
+ }
20877
+ } catch {
20809
20878
  }
20810
- const candidate = value.url;
20811
- if (candidate) {
20812
- return candidate;
20879
+ return void 0;
20880
+ }
20881
+ function saveStoredAuthToJson(authRecord) {
20882
+ if (process.env.NODE_ENV === "test" || process.env.VITEST || storedAuthOverrideForTesting !== void 0) {
20883
+ return;
20813
20884
  }
20814
- return value.toString();
20885
+ const dirPath = join6(homedir4(), ".local", "share", "opencode");
20886
+ if (!existsSync6(dirPath)) {
20887
+ mkdirSync5(dirPath, { recursive: true });
20888
+ }
20889
+ const authPath = join6(dirPath, "auth.json");
20890
+ const data = existsSync6(authPath) ? JSON.parse(readFileSync5(authPath, "utf8")) : {};
20891
+ data[AGY_PROVIDER_ID] = {
20892
+ type: "oauth",
20893
+ refresh: authRecord.refresh,
20894
+ access: authRecord.access,
20895
+ expires: authRecord.expires
20896
+ };
20897
+ const tempPath = `${authPath}.${process.pid}.${randomUUID4()}.tmp`;
20898
+ let tempFileDescriptor;
20899
+ let ownsTempFile = false;
20900
+ try {
20901
+ tempFileDescriptor = openSync(tempPath, "wx", 384);
20902
+ ownsTempFile = true;
20903
+ writeFileSync5(tempFileDescriptor, JSON.stringify(data, null, 2), {
20904
+ encoding: "utf8"
20905
+ });
20906
+ closeSync(tempFileDescriptor);
20907
+ tempFileDescriptor = void 0;
20908
+ renameSync4(tempPath, authPath);
20909
+ } catch (error45) {
20910
+ if (tempFileDescriptor !== void 0) {
20911
+ try {
20912
+ closeSync(tempFileDescriptor);
20913
+ } catch {
20914
+ }
20915
+ }
20916
+ if (ownsTempFile) {
20917
+ try {
20918
+ unlinkSync4(tempPath);
20919
+ } catch {
20920
+ }
20921
+ }
20922
+ throw error45;
20923
+ }
20924
+ }
20925
+
20926
+ // src/plugin/v2-fetch.ts
20927
+ function createV2FetchInterceptor(getAuthSnapshot) {
20928
+ return async function agyV2Fetch(input, init) {
20929
+ const isGL = isGenerativeLanguageRequest(input);
20930
+ const isInternal = toUrlString(input).includes("cloudcode-pa.googleapis.com");
20931
+ if (!isGL && !isInternal) {
20932
+ return (globalThis.fetch || fetch)(input, init);
20933
+ }
20934
+ let rawAuth = getAuthSnapshot ? await getAuthSnapshot() : void 0;
20935
+ if (!rawAuth) {
20936
+ rawAuth = loadStoredAuthFromJson();
20937
+ }
20938
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
20939
+ return (globalThis.fetch || fetch)(input, init);
20940
+ }
20941
+ let authRecord = resolveCachedAuth(rawAuth);
20942
+ if (accessTokenExpired(authRecord)) {
20943
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
20944
+ } } });
20945
+ if (refreshed) {
20946
+ authRecord = refreshed;
20947
+ }
20948
+ }
20949
+ if (!authRecord.access) {
20950
+ return (globalThis.fetch || fetch)(input, init);
20951
+ }
20952
+ if (isInternal) {
20953
+ const hasAuth = getSafeHeader(init?.headers, "Authorization") !== void 0;
20954
+ if (hasAuth) {
20955
+ return (globalThis.fetch || fetch)(input, init);
20956
+ }
20957
+ const userAgent = buildAgyCliUserAgent();
20958
+ const headers = setSafeHeaders(init?.headers, {
20959
+ Authorization: `Bearer ${authRecord.access}`,
20960
+ "User-Agent": userAgent
20961
+ });
20962
+ return (globalThis.fetch || fetch)(input, {
20963
+ ...init,
20964
+ headers
20965
+ });
20966
+ }
20967
+ const requestTarget = parseGenerativeLanguageRequest(input);
20968
+ const requestUserAgentModel = requestTarget?.effectiveModel;
20969
+ let projectContext;
20970
+ try {
20971
+ projectContext = await ensureProjectContext(
20972
+ authRecord,
20973
+ { auth: { set: async () => {
20974
+ } } },
20975
+ void 0,
20976
+ requestUserAgentModel
20977
+ );
20978
+ } catch {
20979
+ projectContext = {
20980
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
20981
+ auth: authRecord
20982
+ };
20983
+ }
20984
+ const originalRequestedModel = parseGenerativeLanguageRequest(input)?.effectiveModel;
20985
+ let modifiedInput = input;
20986
+ if (isGL && originalRequestedModel) {
20987
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
20988
+ const resolvedBase = resolveModelTier(originalBase, init);
20989
+ if (originalBase !== resolvedBase) {
20990
+ if (typeof modifiedInput === "string") {
20991
+ modifiedInput = modifiedInput.replace(`models/${originalBase}`, `models/${resolvedBase}`);
20992
+ } else if (typeof Request !== "undefined" && modifiedInput instanceof Request) {
20993
+ const newUrl = modifiedInput.url.replace(`models/${originalBase}`, `models/${resolvedBase}`);
20994
+ modifiedInput = new Request(newUrl, modifiedInput);
20995
+ }
20996
+ }
20997
+ }
20998
+ const transformed = prepareAgyRequest(
20999
+ modifiedInput,
21000
+ init,
21001
+ authRecord.access,
21002
+ projectContext.effectiveProjectId,
21003
+ void 0
21004
+ );
21005
+ const chatLogger = createChatLogger();
21006
+ if (chatLogger) {
21007
+ chatLogger.logRequest(
21008
+ toUrlString(transformed.request),
21009
+ transformed.init.method || "GET",
21010
+ transformed.init.headers,
21011
+ transformed.init.body
21012
+ );
21013
+ }
21014
+ const response = await fetchWithRetry(transformed.request, transformed.init);
21015
+ return transformAgyResponse(
21016
+ response,
21017
+ transformed.streaming,
21018
+ null,
21019
+ transformed.requestedModel,
21020
+ transformed.sessionId,
21021
+ chatLogger
21022
+ );
21023
+ };
20815
21024
  }
20816
21025
 
21026
+ // src/plugin/v2-session.ts
21027
+ function createV2HttpRequestHook(state = {}) {
21028
+ return async (event) => {
21029
+ if (!event) return;
21030
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21031
+ const isGL = isGenerativeLanguageRequest(rawUrl);
21032
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21033
+ if (!isGL && !isInternal) {
21034
+ return;
21035
+ }
21036
+ event.headers = event.headers || {};
21037
+ let modelName;
21038
+ let rawAuth = event.auth;
21039
+ if (rawAuth && !rawAuth.type) {
21040
+ const tokenVal = rawAuth.access || rawAuth.token;
21041
+ if (tokenVal || rawAuth.refresh) {
21042
+ rawAuth = { type: "oauth", access: tokenVal, ...rawAuth };
21043
+ }
21044
+ }
21045
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
21046
+ rawAuth = loadStoredAuthFromJson();
21047
+ }
21048
+ let authRecord = rawAuth && isOAuthAuth(rawAuth) ? resolveCachedAuth(rawAuth) : void 0;
21049
+ if (authRecord && accessTokenExpired(authRecord)) {
21050
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
21051
+ } } });
21052
+ if (refreshed) {
21053
+ authRecord = refreshed;
21054
+ try {
21055
+ saveStoredAuthToJson(refreshed);
21056
+ } catch {
21057
+ console.warn("[Agy Auth] Refreshed credentials could not be persisted; the current request will continue.");
21058
+ }
21059
+ }
21060
+ }
21061
+ if (isGL) {
21062
+ const parsed = parseGenerativeLanguageRequest(rawUrl);
21063
+ modelName = parsed?.effectiveModel;
21064
+ if (modelName) {
21065
+ state.lastInterceptedModel = modelName;
21066
+ }
21067
+ if (typeof event.headers.delete === "function") {
21068
+ event.headers.delete("x-goog-api-key");
21069
+ event.headers.delete("api-key");
21070
+ } else {
21071
+ for (const key of Object.keys(event.headers)) {
21072
+ const lower = key.toLowerCase();
21073
+ if (lower === "x-goog-api-key" || lower === "api-key") {
21074
+ delete event.headers[key];
21075
+ }
21076
+ }
21077
+ }
21078
+ if (event.request?.headers) {
21079
+ if (typeof event.request.headers.delete === "function") {
21080
+ event.request.headers.delete("x-goog-api-key");
21081
+ event.request.headers.delete("api-key");
21082
+ } else {
21083
+ for (const key of Object.keys(event.request.headers)) {
21084
+ const lower = key.toLowerCase();
21085
+ if (lower === "x-goog-api-key" || lower === "api-key") {
21086
+ delete event.request.headers[key];
21087
+ }
21088
+ }
21089
+ }
21090
+ }
21091
+ let cleanUrl = rawUrl;
21092
+ try {
21093
+ const parsedUrl = new URL(rawUrl);
21094
+ let urlChanged = false;
21095
+ for (const param of ["key", "x-goog-api-key", "api-key"]) {
21096
+ if (parsedUrl.searchParams.has(param)) {
21097
+ parsedUrl.searchParams.delete(param);
21098
+ urlChanged = true;
21099
+ }
21100
+ }
21101
+ if (urlChanged) {
21102
+ cleanUrl = parsedUrl.toString();
21103
+ }
21104
+ } catch {
21105
+ }
21106
+ if (authRecord && authRecord.access) {
21107
+ let projectContext;
21108
+ try {
21109
+ projectContext = await ensureProjectContext(
21110
+ authRecord,
21111
+ { auth: { set: async () => {
21112
+ } } },
21113
+ void 0,
21114
+ modelName
21115
+ );
21116
+ } catch {
21117
+ projectContext = {
21118
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
21119
+ auth: authRecord
21120
+ };
21121
+ }
21122
+ const originalRequestedModel = modelName;
21123
+ let modifiedUrl = cleanUrl;
21124
+ if (originalRequestedModel) {
21125
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
21126
+ const initHeaders = event.headers instanceof Headers ? event.headers : event.request?.headers;
21127
+ const resolvedBase = resolveModelTier(originalBase, { headers: initHeaders });
21128
+ if (originalBase !== resolvedBase) {
21129
+ modifiedUrl = modifiedUrl.replace(`models/${originalBase}`, `models/${resolvedBase}`);
21130
+ }
21131
+ }
21132
+ let bodyPayload = event.body;
21133
+ if (bodyPayload === void 0 && event.request) {
21134
+ if (typeof event.request.clone === "function") {
21135
+ try {
21136
+ bodyPayload = await event.request.clone().text();
21137
+ } catch {
21138
+ }
21139
+ } else if (event.request.body !== void 0) {
21140
+ bodyPayload = event.request.body;
21141
+ }
21142
+ }
21143
+ let preExistingUserAgent;
21144
+ if (typeof event.headers?.get === "function") {
21145
+ preExistingUserAgent = event.headers.get("user-agent") || event.headers.get("User-Agent") || void 0;
21146
+ } else if (event.headers && typeof event.headers === "object") {
21147
+ preExistingUserAgent = event.headers["user-agent"] || event.headers["User-Agent"] || void 0;
21148
+ }
21149
+ if (!preExistingUserAgent && typeof event.request?.headers?.get === "function") {
21150
+ preExistingUserAgent = event.request.headers.get("user-agent") || event.request.headers.get("User-Agent") || void 0;
21151
+ } else if (!preExistingUserAgent && event.request?.headers && typeof event.request.headers === "object") {
21152
+ preExistingUserAgent = event.request.headers["user-agent"] || event.request.headers["User-Agent"] || void 0;
21153
+ }
21154
+ const method = event.method || event.request?.method || "POST";
21155
+ const requestHeaders = event.headers || event.request?.headers;
21156
+ const transformed = prepareAgyRequest(
21157
+ modifiedUrl,
21158
+ {
21159
+ method,
21160
+ headers: requestHeaders,
21161
+ body: bodyPayload
21162
+ },
21163
+ authRecord.access,
21164
+ projectContext.effectiveProjectId
21165
+ );
21166
+ const targetUrl = toUrlString(transformed.request);
21167
+ if (typeof event.url === "string") {
21168
+ event.url = targetUrl;
21169
+ }
21170
+ if (event.request && typeof event.request === "object") {
21171
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21172
+ event.request = new Request(targetUrl, {
21173
+ method: transformed.init.method,
21174
+ headers: transformed.init.headers,
21175
+ body: transformed.init.body
21176
+ });
21177
+ } else if (typeof event.request.url === "string") {
21178
+ try {
21179
+ event.request.url = targetUrl;
21180
+ } catch {
21181
+ }
21182
+ }
21183
+ }
21184
+ const headerEntries = transformed.init.headers instanceof Headers ? Array.from(transformed.init.headers.entries()) : Object.entries(transformed.init.headers || {});
21185
+ for (const [k, v] of headerEntries) {
21186
+ const lowerK = k.toLowerCase();
21187
+ if (lowerK === "user-agent") {
21188
+ if (preExistingUserAgent) {
21189
+ continue;
21190
+ }
21191
+ if (typeof event.headers?.set === "function") {
21192
+ event.headers.set("User-Agent", v);
21193
+ } else if (event.headers) {
21194
+ event.headers["User-Agent"] = v;
21195
+ }
21196
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21197
+ event.request.headers.set("User-Agent", v);
21198
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21199
+ event.request.headers["User-Agent"] = v;
21200
+ }
21201
+ continue;
21202
+ }
21203
+ if (typeof event.headers?.set === "function") {
21204
+ event.headers.set(k, v);
21205
+ } else if (event.headers) {
21206
+ event.headers[k] = v;
21207
+ }
21208
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21209
+ event.request.headers.set(k, v);
21210
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21211
+ event.request.headers[k] = v;
21212
+ }
21213
+ }
21214
+ if (transformed.init.body !== void 0) {
21215
+ event.body = transformed.init.body;
21216
+ if (event.request && typeof event.request === "object" && !(event.request instanceof Request)) {
21217
+ event.request.body = transformed.init.body;
21218
+ }
21219
+ }
21220
+ } else {
21221
+ if (typeof event.url === "string") {
21222
+ event.url = cleanUrl;
21223
+ }
21224
+ if (event.request && typeof event.request === "object") {
21225
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21226
+ event.request = new Request(cleanUrl, event.request);
21227
+ } else if (typeof event.request.url === "string") {
21228
+ try {
21229
+ event.request.url = cleanUrl;
21230
+ } catch {
21231
+ }
21232
+ }
21233
+ }
21234
+ }
21235
+ }
21236
+ if (authRecord && authRecord.access) {
21237
+ if (typeof event.headers?.set === "function") {
21238
+ event.headers.set("Authorization", `Bearer ${authRecord.access}`);
21239
+ } else if (event.headers) {
21240
+ event.headers["Authorization"] = `Bearer ${authRecord.access}`;
21241
+ }
21242
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21243
+ event.request.headers.set("Authorization", `Bearer ${authRecord.access}`);
21244
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21245
+ event.request.headers["Authorization"] = `Bearer ${authRecord.access}`;
21246
+ }
21247
+ }
21248
+ const userAgent = buildAgyCliUserAgent(modelName);
21249
+ if (typeof event.headers?.set === "function") {
21250
+ if (!event.headers.get("User-Agent") && !event.headers.get("user-agent")) {
21251
+ event.headers.set("User-Agent", userAgent);
21252
+ }
21253
+ } else if (event.headers) {
21254
+ if (!event.headers["User-Agent"] && !event.headers["user-agent"]) {
21255
+ event.headers["User-Agent"] = userAgent;
21256
+ }
21257
+ }
21258
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21259
+ if (!event.request.headers.get("User-Agent") && !event.request.headers.get("user-agent")) {
21260
+ event.request.headers.set("User-Agent", userAgent);
21261
+ }
21262
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21263
+ if (!event.request.headers["User-Agent"] && !event.request.headers["user-agent"]) {
21264
+ event.request.headers["User-Agent"] = userAgent;
21265
+ }
21266
+ }
21267
+ };
21268
+ }
21269
+ function createV2HttpResponseHook(state = {}) {
21270
+ return async (event) => {
21271
+ if (!event || !event.response) return;
21272
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21273
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21274
+ if (isInternal && event.response instanceof Response) {
21275
+ const isStreaming = rawUrl.includes(":streamGenerateCode") || event.response.headers.get("content-type")?.includes("text/event-stream");
21276
+ const parsedModel = parseGenerativeLanguageRequest(rawUrl)?.effectiveModel || state.lastInterceptedModel;
21277
+ const transformed = await transformAgyResponse(
21278
+ event.response,
21279
+ !!isStreaming,
21280
+ null,
21281
+ parsedModel,
21282
+ void 0,
21283
+ void 0
21284
+ );
21285
+ event.response = transformed;
21286
+ }
21287
+ };
21288
+ }
21289
+ function createV2RetryHook() {
21290
+ return async (event) => {
21291
+ if (!event) return;
21292
+ const response = event.response;
21293
+ if (response instanceof Response) {
21294
+ if (response.status === 429 || response.status === 503) {
21295
+ const quota = await classifyQuotaResponse(response);
21296
+ if (quota?.retryDelayMs) {
21297
+ event.retryDelayMs = quota.retryDelayMs;
21298
+ } else {
21299
+ event.retryDelayMs = await resolveRetryDelayMs(response, event.attempt || 1);
21300
+ }
21301
+ }
21302
+ } else if (event.details && Array.isArray(event.details)) {
21303
+ const retryInfo = event.details.find(
21304
+ (d) => d && d["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
21305
+ );
21306
+ if (retryInfo?.retryDelay) {
21307
+ const delayMs = retryInternals.parseRetryDelayValue(retryInfo.retryDelay);
21308
+ if (delayMs !== null) {
21309
+ event.retryDelayMs = delayMs;
21310
+ }
21311
+ }
21312
+ }
21313
+ };
21314
+ }
21315
+ function registerV2SessionHooks(ctx) {
21316
+ const state = {};
21317
+ ctx.session.hook("http.request", createV2HttpRequestHook(state), { providerID: AGY_PROVIDER_ID });
21318
+ ctx.session.hook("http.response", createV2HttpResponseHook(state), { providerID: AGY_PROVIDER_ID });
21319
+ ctx.session.hook("retry", createV2RetryHook(), { providerID: AGY_PROVIDER_ID });
21320
+ }
21321
+
21322
+ // src/plugin/v2.ts
21323
+ async function setupOpenCodeV2(ctx) {
21324
+ const resolveVariants = (modelId) => {
21325
+ const mapping = TIER_MAPPING[modelId];
21326
+ if (!mapping) return void 0;
21327
+ const variants = [];
21328
+ if (mapping.minimal !== void 0) variants.push({ id: "minimal" });
21329
+ if (mapping.low !== void 0) variants.push({ id: "low" });
21330
+ if (mapping.medium !== void 0) variants.push({ id: "medium" });
21331
+ if (mapping.high !== void 0) variants.push({ id: "high" });
21332
+ return variants.length > 0 ? variants : void 0;
21333
+ };
21334
+ const updateProviderRecord = (p) => {
21335
+ p.name = "Antigravity CLI";
21336
+ p.activation = "enabled";
21337
+ p.package = "aisdk:@ai-sdk/google";
21338
+ p.description = "Google Gemini Antigravity Code Assist OAuth provider";
21339
+ p.settings = { ...p.settings || {}, apiKey: "dummy" };
21340
+ p.integrationID = AGY_PROVIDER_ID;
21341
+ };
21342
+ const buildModelRecord = (modelId, simple, existingModel) => {
21343
+ const isClaude = modelId.startsWith("claude-");
21344
+ const isGpt = modelId.startsWith("gpt-");
21345
+ const variants = resolveVariants(modelId);
21346
+ return {
21347
+ id: modelId,
21348
+ providerID: AGY_PROVIDER_ID,
21349
+ name: simple.name,
21350
+ description: simple.description,
21351
+ family: modelId.includes("gemini") ? "gemini" : isClaude ? "claude" : isGpt ? "gpt" : "unknown",
21352
+ reasoning: simple.reasoning,
21353
+ attachment: simple.attachment,
21354
+ tool_call: simple.toolCall,
21355
+ limit: {
21356
+ context: simple.maxTokens,
21357
+ output: simple.maxOutputTokens
21358
+ },
21359
+ cost: simple.cost || { input: 0, output: 0 },
21360
+ ...variants ? { variants } : {},
21361
+ ...existingModel || {}
21362
+ };
21363
+ };
21364
+ const updateModelRecord = (m, modelId, simple) => {
21365
+ m.name = simple.name;
21366
+ m.capabilities = {
21367
+ tools: true,
21368
+ input: ["text", "image"],
21369
+ output: ["text"]
21370
+ };
21371
+ m.limit = {
21372
+ context: simple.maxTokens,
21373
+ output: simple.maxOutputTokens
21374
+ };
21375
+ m.family = "gemini";
21376
+ if (simple.cost) {
21377
+ m.cost = simple.cost;
21378
+ }
21379
+ const variants = resolveVariants(modelId);
21380
+ if (variants) {
21381
+ m.variants = variants;
21382
+ }
21383
+ };
21384
+ if (ctx.provider?.transform) {
21385
+ ctx.provider.transform(async (editor) => {
21386
+ if (!editor) return;
21387
+ if (typeof editor.update === "function") {
21388
+ editor.update(AGY_PROVIDER_ID, updateProviderRecord);
21389
+ } else if (typeof editor.set === "function") {
21390
+ const p = { id: AGY_PROVIDER_ID };
21391
+ updateProviderRecord(p);
21392
+ editor.set(AGY_PROVIDER_ID, p);
21393
+ } else if (typeof editor === "object") {
21394
+ const p = editor[AGY_PROVIDER_ID] || { id: AGY_PROVIDER_ID };
21395
+ updateProviderRecord(p);
21396
+ editor[AGY_PROVIDER_ID] = p;
21397
+ }
21398
+ });
21399
+ }
21400
+ if (ctx.model?.transform) {
21401
+ ctx.model.transform(async (editor) => {
21402
+ if (!editor) return;
21403
+ if (typeof editor.update === "function") {
21404
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21405
+ editor.update(AGY_PROVIDER_ID, modelId, (m) => updateModelRecord(m, modelId, simple));
21406
+ }
21407
+ } else if (typeof editor.set === "function") {
21408
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21409
+ const m = buildModelRecord(modelId, simple);
21410
+ editor.set(`${AGY_PROVIDER_ID}:${modelId}`, m);
21411
+ }
21412
+ } else if (typeof editor === "object") {
21413
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21414
+ const key = `${AGY_PROVIDER_ID}:${modelId}`;
21415
+ editor[key] = buildModelRecord(modelId, simple, editor[key]);
21416
+ }
21417
+ }
21418
+ });
21419
+ }
21420
+ if (ctx.catalog?.transform) {
21421
+ ctx.catalog.transform(async (editor) => {
21422
+ if (!editor) return;
21423
+ if (typeof editor?.provider?.update === "function") {
21424
+ editor.provider.update(AGY_PROVIDER_ID, updateProviderRecord);
21425
+ if (typeof editor?.model?.update === "function") {
21426
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21427
+ editor.model.update(AGY_PROVIDER_ID, modelId, (m) => updateModelRecord(m, modelId, simple));
21428
+ }
21429
+ }
21430
+ return;
21431
+ }
21432
+ const catalog = editor;
21433
+ catalog.providers = catalog.providers || {};
21434
+ catalog.providers[AGY_PROVIDER_ID] = {
21435
+ id: AGY_PROVIDER_ID,
21436
+ name: "Antigravity CLI",
21437
+ npm: "aisdk:@ai-sdk/google",
21438
+ settings: { apiKey: "dummy" },
21439
+ integrationID: AGY_PROVIDER_ID,
21440
+ models: { ...catalog.providers[AGY_PROVIDER_ID]?.models || {} },
21441
+ ...catalog.providers[AGY_PROVIDER_ID]
21442
+ };
21443
+ if (catalog.providers[AGY_PROVIDER_ID].settings) {
21444
+ catalog.providers[AGY_PROVIDER_ID].settings = {
21445
+ ...catalog.providers[AGY_PROVIDER_ID].settings,
21446
+ apiKey: "dummy"
21447
+ };
21448
+ } else {
21449
+ catalog.providers[AGY_PROVIDER_ID].settings = { apiKey: "dummy" };
21450
+ }
21451
+ catalog.providers[AGY_PROVIDER_ID].integrationID = AGY_PROVIDER_ID;
21452
+ const targetModels = catalog.providers[AGY_PROVIDER_ID].models;
21453
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21454
+ targetModels[modelId] = buildModelRecord(modelId, simple, targetModels[modelId]);
21455
+ }
21456
+ });
21457
+ }
21458
+ ctx.tool.transform(async (editor) => {
21459
+ if (!editor) return;
21460
+ const quotaTool = createAgyQuotaTool({
21461
+ client: void 0,
21462
+ getAuthResolver: () => void 0,
21463
+ getConfiguredProjectId: () => void 0,
21464
+ getUserAgentModel: () => void 0
21465
+ });
21466
+ const quotaSummaryTool = createAgyQuotaSummaryTool({
21467
+ client: void 0,
21468
+ getAuthResolver: () => void 0,
21469
+ getConfiguredProjectId: () => void 0,
21470
+ getUserAgentModel: () => void 0
21471
+ });
21472
+ if (typeof editor.add === "function") {
21473
+ editor.add({
21474
+ name: AGY_QUOTA_TOOL_NAME,
21475
+ description: quotaTool.description,
21476
+ input: {},
21477
+ execute: async (args, context) => quotaTool.execute(args, context)
21478
+ });
21479
+ editor.add({
21480
+ name: AGY_QUOTA_SUMMARY_TOOL_NAME,
21481
+ description: quotaSummaryTool.description,
21482
+ input: {},
21483
+ execute: async (args, context) => quotaSummaryTool.execute(args, context)
21484
+ });
21485
+ } else if (typeof editor.set === "function") {
21486
+ editor.set(AGY_QUOTA_TOOL_NAME, quotaTool);
21487
+ editor.set(AGY_QUOTA_SUMMARY_TOOL_NAME, quotaSummaryTool);
21488
+ } else if (editor.tools && typeof editor.tools === "object") {
21489
+ editor.tools[AGY_QUOTA_TOOL_NAME] = quotaTool;
21490
+ editor.tools[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
21491
+ } else if (typeof editor === "object") {
21492
+ editor[AGY_QUOTA_TOOL_NAME] = quotaTool;
21493
+ editor[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
21494
+ }
21495
+ });
21496
+ ctx.command.transform(async (editor) => {
21497
+ if (!editor) return;
21498
+ const commands = {
21499
+ [AGY_V2_QUOTA_COMMAND]: {
21500
+ description: "Show Agy Code Assist quota usage",
21501
+ template: AGY_V2_QUOTA_COMMAND_TEMPLATE
21502
+ },
21503
+ [AGY_V2_QUOTA_SUMMARY_COMMAND]: {
21504
+ description: "Show Agy Code Assist quota summary with weekly and 5-hour limits",
21505
+ template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
21506
+ }
21507
+ };
21508
+ if (typeof editor.add === "function") {
21509
+ editor.add({
21510
+ name: AGY_V2_QUOTA_COMMAND,
21511
+ description: "Display current Antigravity quota usage",
21512
+ template: AGY_V2_QUOTA_COMMAND_TEMPLATE
21513
+ });
21514
+ editor.add({
21515
+ name: AGY_V2_QUOTA_SUMMARY_COMMAND,
21516
+ description: "Display Antigravity quota summary grouped by model family",
21517
+ template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
21518
+ });
21519
+ } else if (typeof editor.set === "function") {
21520
+ editor.set(AGY_V2_QUOTA_COMMAND, commands[AGY_V2_QUOTA_COMMAND]);
21521
+ editor.set(AGY_V2_QUOTA_SUMMARY_COMMAND, commands[AGY_V2_QUOTA_SUMMARY_COMMAND]);
21522
+ } else if (editor.commands && typeof editor.commands === "object") {
21523
+ editor.commands[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
21524
+ editor.commands[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
21525
+ } else if (typeof editor === "object") {
21526
+ editor[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
21527
+ editor[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
21528
+ }
21529
+ });
21530
+ ctx.integration?.transform?.((editor) => {
21531
+ if (!editor) return;
21532
+ editor.update?.(AGY_PROVIDER_ID, (integration) => {
21533
+ integration.name = "Antigravity CLI (plugin)";
21534
+ });
21535
+ editor.method?.update?.({
21536
+ integrationID: AGY_PROVIDER_ID,
21537
+ method: {
21538
+ id: "oauth",
21539
+ type: "oauth",
21540
+ label: "Antigravity CLI (OAuth)"
21541
+ },
21542
+ authorize: async () => {
21543
+ const authorization = await authorizeAgy();
21544
+ return {
21545
+ mode: "code",
21546
+ url: authorization.url,
21547
+ instructions: "Please complete Google account authorization in your browser. After authorization, copy the full redirect URL or code and paste it below:",
21548
+ callback: async (code) => {
21549
+ const trimmed = code.trim();
21550
+ const parsed = parseOAuthCallbackInput(trimmed);
21551
+ const authCode = parsed.code || trimmed;
21552
+ if (!authCode) {
21553
+ return { type: "failed", error: "Missing authorization code in callback input" };
21554
+ }
21555
+ if (parsed.state && parsed.state !== authorization.state) {
21556
+ return { type: "failed", error: "State mismatch in callback input (possible CSRF attempt)" };
21557
+ }
21558
+ const exchangeResult = await exchangeAgyWithVerifier(authCode, authorization.verifier);
21559
+ if (exchangeResult.type !== "success") {
21560
+ return exchangeResult;
21561
+ }
21562
+ const initialRefresh = formatRefreshParts({
21563
+ refreshToken: exchangeResult.refresh
21564
+ });
21565
+ let authRecord = {
21566
+ type: "oauth",
21567
+ refresh: initialRefresh,
21568
+ access: exchangeResult.access,
21569
+ expires: exchangeResult.expires
21570
+ };
21571
+ try {
21572
+ const projectContext = await ensureProjectContext(
21573
+ authRecord,
21574
+ { auth: { set: async () => {
21575
+ } } }
21576
+ );
21577
+ authRecord = {
21578
+ ...authRecord,
21579
+ refresh: projectContext.auth.refresh
21580
+ };
21581
+ } catch {
21582
+ }
21583
+ try {
21584
+ saveStoredAuthToJson(authRecord);
21585
+ } catch {
21586
+ return {
21587
+ type: "failed",
21588
+ error: "Google authentication succeeded but AGY credentials could not be stored. Check filesystem access and retry."
21589
+ };
21590
+ }
21591
+ return {
21592
+ type: "oauth",
21593
+ methodID: "oauth",
21594
+ refresh: authRecord.refresh,
21595
+ access: authRecord.access,
21596
+ expires: authRecord.expires
21597
+ };
21598
+ }
21599
+ };
21600
+ }
21601
+ });
21602
+ });
21603
+ ctx.aisdk?.hook("sdk", async (event) => {
21604
+ if (!event) return;
21605
+ const isMatchingProvider = event.providerID === AGY_PROVIDER_ID || event.model?.providerID === AGY_PROVIDER_ID;
21606
+ if (!isMatchingProvider) return;
21607
+ event.options = event.options || {};
21608
+ event.options.apiKey = "dummy";
21609
+ event.options.fetch = createV2FetchInterceptor();
21610
+ });
21611
+ registerV2SessionHooks(ctx);
21612
+ }
21613
+ var v2PluginDefinition = defineOpenCodeV2Plugin({
21614
+ id: AGY_PROVIDER_ID,
21615
+ setup: setupOpenCodeV2
21616
+ });
21617
+
20817
21618
  // index.ts
20818
- var index_default = {
20819
- id: "@anthonyhaussman/opencode-agy-auth",
21619
+ var dualPlugin = {
21620
+ ...v2PluginDefinition,
20820
21621
  server: AgyCLIOAuthPlugin
20821
21622
  };
21623
+ var index_default = dualPlugin;
20822
21624
  export {
20823
21625
  AgyCLIOAuthPlugin,
20824
21626
  GoogleOAuthPlugin,
20825
- index_default as default
21627
+ index_default as default,
21628
+ defineOpenCodeV2Plugin,
21629
+ setupOpenCodeV2,
21630
+ v2PluginDefinition
20826
21631
  };
20827
21632
  //# sourceMappingURL=index.js.map