@anthonyhaussman/opencode-agy-auth 1.2.13 → 1.2.14-alpha.0

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.13";
271
+ var AGY_CLI_VERSION = "1.2.14";
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,
@@ -16058,8 +16087,6 @@ var models_default = {
16058
16087
  106143956,
16059
16088
  105856899,
16060
16089
  106064030,
16061
- 106264162,
16062
- 106711598,
16063
16090
  106106760,
16064
16091
  106021688,
16065
16092
  105887299,
@@ -16082,7 +16109,6 @@ var models_default = {
16082
16109
  106121399,
16083
16110
  106100654,
16084
16111
  106064028,
16085
- 106264150,
16086
16112
  105906495,
16087
16113
  106283614,
16088
16114
  106640124,
@@ -16148,7 +16174,7 @@ var models_default = {
16148
16174
  modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16149
16175
  quotaInfo: {
16150
16176
  remainingFraction: 1,
16151
- resetTime: "2026-09-29T10:26:06Z"
16177
+ resetTime: "2026-09-30T12:45:45Z"
16152
16178
  },
16153
16179
  recommended: true,
16154
16180
  supportedMimeTypes: {
@@ -16187,7 +16213,7 @@ var models_default = {
16187
16213
  modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16188
16214
  quotaInfo: {
16189
16215
  remainingFraction: 1,
16190
- resetTime: "2026-09-29T10:26:06Z"
16216
+ resetTime: "2026-09-30T12:45:45Z"
16191
16217
  },
16192
16218
  recommended: true,
16193
16219
  supportedMimeTypes: {
@@ -16223,8 +16249,8 @@ var models_default = {
16223
16249
  },
16224
16250
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16225
16251
  quotaInfo: {
16226
- remainingFraction: 0.9730856,
16227
- resetTime: "2026-09-29T10:22:45Z"
16252
+ remainingFraction: 0.9673149,
16253
+ resetTime: "2026-09-30T12:41:07Z"
16228
16254
  },
16229
16255
  recommended: true,
16230
16256
  supportedMimeTypes: {
@@ -16306,8 +16332,8 @@ var models_default = {
16306
16332
  },
16307
16333
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16308
16334
  quotaInfo: {
16309
- remainingFraction: 0.9730856,
16310
- resetTime: "2026-09-29T10:22:45Z"
16335
+ remainingFraction: 0.9673149,
16336
+ resetTime: "2026-09-30T12:41:07Z"
16311
16337
  },
16312
16338
  recommended: true,
16313
16339
  supportedMimeTypes: {
@@ -16389,8 +16415,8 @@ var models_default = {
16389
16415
  },
16390
16416
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16391
16417
  quotaInfo: {
16392
- remainingFraction: 0.9730856,
16393
- resetTime: "2026-09-29T10:22:45Z"
16418
+ remainingFraction: 0.9673149,
16419
+ resetTime: "2026-09-30T12:41:07Z"
16394
16420
  },
16395
16421
  recommended: true,
16396
16422
  supportedMimeTypes: {
@@ -16469,8 +16495,8 @@ var models_default = {
16469
16495
  },
16470
16496
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16471
16497
  quotaInfo: {
16472
- remainingFraction: 0.9730856,
16473
- resetTime: "2026-09-29T10:22:45Z"
16498
+ remainingFraction: 0.9673149,
16499
+ resetTime: "2026-09-30T12:41:07Z"
16474
16500
  },
16475
16501
  recommended: true,
16476
16502
  requiresImageOutputOutsideFunctionResponses: true,
@@ -16550,8 +16576,8 @@ var models_default = {
16550
16576
  },
16551
16577
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16552
16578
  quotaInfo: {
16553
- remainingFraction: 0.9730856,
16554
- resetTime: "2026-09-29T10:22:45Z"
16579
+ remainingFraction: 0.9673149,
16580
+ resetTime: "2026-09-30T12:41:07Z"
16555
16581
  },
16556
16582
  recommended: true,
16557
16583
  supportedMimeTypes: {
@@ -16655,8 +16681,8 @@ var models_default = {
16655
16681
  },
16656
16682
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16657
16683
  quotaInfo: {
16658
- remainingFraction: 0.9730856,
16659
- resetTime: "2026-09-29T10:22:45Z"
16684
+ remainingFraction: 0.9673149,
16685
+ resetTime: "2026-09-30T12:41:07Z"
16660
16686
  },
16661
16687
  recommended: true,
16662
16688
  supportedMimeTypes: {
@@ -16725,8 +16751,8 @@ var models_default = {
16725
16751
  model: "MODEL_PLACEHOLDER_M21",
16726
16752
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16727
16753
  quotaInfo: {
16728
- remainingFraction: 0.9730856,
16729
- resetTime: "2026-09-29T10:22:45Z"
16754
+ remainingFraction: 0.9673149,
16755
+ resetTime: "2026-09-30T12:41:07Z"
16730
16756
  }
16731
16757
  },
16732
16758
  "gemini-3.1-flash-lite": {
@@ -16744,8 +16770,8 @@ var models_default = {
16744
16770
  },
16745
16771
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16746
16772
  quotaInfo: {
16747
- remainingFraction: 0.9730856,
16748
- resetTime: "2026-09-29T10:22:45Z"
16773
+ remainingFraction: 0.9673149,
16774
+ resetTime: "2026-09-30T12:41:07Z"
16749
16775
  }
16750
16776
  },
16751
16777
  "gemini-3.1-pro-high": {
@@ -16776,8 +16802,8 @@ var models_default = {
16776
16802
  },
16777
16803
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16778
16804
  quotaInfo: {
16779
- remainingFraction: 0.9730856,
16780
- resetTime: "2026-09-29T10:22:45Z"
16805
+ remainingFraction: 0.9673149,
16806
+ resetTime: "2026-09-30T12:41:07Z"
16781
16807
  },
16782
16808
  recommended: true,
16783
16809
  supportedMimeTypes: {
@@ -16867,8 +16893,8 @@ var models_default = {
16867
16893
  },
16868
16894
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16869
16895
  quotaInfo: {
16870
- remainingFraction: 0.9730856,
16871
- resetTime: "2026-09-29T10:22:45Z"
16896
+ remainingFraction: 0.9673149,
16897
+ resetTime: "2026-09-30T12:41:07Z"
16872
16898
  },
16873
16899
  recommended: true,
16874
16900
  supportedMimeTypes: {
@@ -16972,8 +16998,8 @@ var models_default = {
16972
16998
  },
16973
16999
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16974
17000
  quotaInfo: {
16975
- remainingFraction: 0.9730856,
16976
- resetTime: "2026-09-29T10:22:45Z"
17001
+ remainingFraction: 0.9673149,
17002
+ resetTime: "2026-09-30T12:41:07Z"
16977
17003
  },
16978
17004
  recommended: true,
16979
17005
  supportedMimeTypes: {
@@ -17055,8 +17081,8 @@ var models_default = {
17055
17081
  },
17056
17082
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17057
17083
  quotaInfo: {
17058
- remainingFraction: 0.9730856,
17059
- resetTime: "2026-09-29T10:22:45Z"
17084
+ remainingFraction: 0.9673149,
17085
+ resetTime: "2026-09-30T12:41:07Z"
17060
17086
  },
17061
17087
  recommended: true,
17062
17088
  supportedMimeTypes: {
@@ -17162,8 +17188,8 @@ var models_default = {
17162
17188
  },
17163
17189
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17164
17190
  quotaInfo: {
17165
- remainingFraction: 0.9730856,
17166
- resetTime: "2026-09-29T10:22:45Z"
17191
+ remainingFraction: 0.9673149,
17192
+ resetTime: "2026-09-30T12:41:07Z"
17167
17193
  },
17168
17194
  recommended: true,
17169
17195
  supportedMimeTypes: {
@@ -17281,8 +17307,8 @@ var models_default = {
17281
17307
  },
17282
17308
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17283
17309
  quotaInfo: {
17284
- remainingFraction: 0.9730856,
17285
- resetTime: "2026-09-29T10:22:45Z"
17310
+ remainingFraction: 0.9673149,
17311
+ resetTime: "2026-09-30T12:41:07Z"
17286
17312
  },
17287
17313
  recommended: true,
17288
17314
  supportedMimeTypes: {
@@ -17400,8 +17426,8 @@ var models_default = {
17400
17426
  },
17401
17427
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17402
17428
  quotaInfo: {
17403
- remainingFraction: 0.9730856,
17404
- resetTime: "2026-09-29T10:22:45Z"
17429
+ remainingFraction: 0.9673149,
17430
+ resetTime: "2026-09-30T12:41:07Z"
17405
17431
  },
17406
17432
  recommended: true,
17407
17433
  supportedMimeTypes: {
@@ -17519,8 +17545,8 @@ var models_default = {
17519
17545
  },
17520
17546
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17521
17547
  quotaInfo: {
17522
- remainingFraction: 0.9730856,
17523
- resetTime: "2026-09-29T10:22:45Z"
17548
+ remainingFraction: 0.9673149,
17549
+ resetTime: "2026-09-30T12:41:07Z"
17524
17550
  },
17525
17551
  recommended: true,
17526
17552
  supportedMimeTypes: {
@@ -17637,8 +17663,8 @@ var models_default = {
17637
17663
  },
17638
17664
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17639
17665
  quotaInfo: {
17640
- remainingFraction: 0.9730856,
17641
- resetTime: "2026-09-29T10:22:45Z"
17666
+ remainingFraction: 0.9673149,
17667
+ resetTime: "2026-09-30T12:41:07Z"
17642
17668
  },
17643
17669
  recommended: true,
17644
17670
  supportedMimeTypes: {
@@ -17748,8 +17774,8 @@ var models_default = {
17748
17774
  },
17749
17775
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17750
17776
  quotaInfo: {
17751
- remainingFraction: 0.9730856,
17752
- resetTime: "2026-09-29T10:22:45Z"
17777
+ remainingFraction: 0.9673149,
17778
+ resetTime: "2026-09-30T12:41:07Z"
17753
17779
  },
17754
17780
  recommended: true,
17755
17781
  supportedMimeTypes: {
@@ -17861,8 +17887,8 @@ var models_default = {
17861
17887
  },
17862
17888
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17863
17889
  quotaInfo: {
17864
- remainingFraction: 0.9730856,
17865
- resetTime: "2026-09-29T10:22:45Z"
17890
+ remainingFraction: 0.9673149,
17891
+ resetTime: "2026-09-30T12:41:07Z"
17866
17892
  },
17867
17893
  recommended: true,
17868
17894
  supportedMimeTypes: {
@@ -17974,8 +18000,8 @@ var models_default = {
17974
18000
  },
17975
18001
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17976
18002
  quotaInfo: {
17977
- remainingFraction: 0.9730856,
17978
- resetTime: "2026-09-29T10:22:45Z"
18003
+ remainingFraction: 0.9673149,
18004
+ resetTime: "2026-09-30T12:41:07Z"
17979
18005
  },
17980
18006
  recommended: true,
17981
18007
  supportedMimeTypes: {
@@ -18086,8 +18112,8 @@ var models_default = {
18086
18112
  },
18087
18113
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18088
18114
  quotaInfo: {
18089
- remainingFraction: 0.9730856,
18090
- resetTime: "2026-09-29T10:22:45Z"
18115
+ remainingFraction: 0.9673149,
18116
+ resetTime: "2026-09-30T12:41:07Z"
18091
18117
  },
18092
18118
  recommended: true,
18093
18119
  supportedMimeTypes: {
@@ -18197,8 +18223,8 @@ var models_default = {
18197
18223
  },
18198
18224
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18199
18225
  quotaInfo: {
18200
- remainingFraction: 0.9730856,
18201
- resetTime: "2026-09-29T10:22:45Z"
18226
+ remainingFraction: 0.9673149,
18227
+ resetTime: "2026-09-30T12:41:07Z"
18202
18228
  },
18203
18229
  recommended: true,
18204
18230
  supportedMimeTypes: {
@@ -18310,8 +18336,8 @@ var models_default = {
18310
18336
  },
18311
18337
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18312
18338
  quotaInfo: {
18313
- remainingFraction: 0.9730856,
18314
- resetTime: "2026-09-29T10:22:45Z"
18339
+ remainingFraction: 0.9673149,
18340
+ resetTime: "2026-09-30T12:41:07Z"
18315
18341
  },
18316
18342
  recommended: true,
18317
18343
  supportedMimeTypes: {
@@ -18423,8 +18449,8 @@ var models_default = {
18423
18449
  },
18424
18450
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18425
18451
  quotaInfo: {
18426
- remainingFraction: 0.9730856,
18427
- resetTime: "2026-09-29T10:22:45Z"
18452
+ remainingFraction: 0.9673149,
18453
+ resetTime: "2026-09-30T12:41:07Z"
18428
18454
  },
18429
18455
  recommended: true,
18430
18456
  supportedMimeTypes: {
@@ -18535,8 +18561,8 @@ var models_default = {
18535
18561
  },
18536
18562
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18537
18563
  quotaInfo: {
18538
- remainingFraction: 0.9730856,
18539
- resetTime: "2026-09-29T10:22:45Z"
18564
+ remainingFraction: 0.9673149,
18565
+ resetTime: "2026-09-30T12:41:07Z"
18540
18566
  },
18541
18567
  recommended: true,
18542
18568
  supportedMimeTypes: {
@@ -18625,8 +18651,8 @@ var models_default = {
18625
18651
  },
18626
18652
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18627
18653
  quotaInfo: {
18628
- remainingFraction: 0.9730856,
18629
- resetTime: "2026-09-29T10:22:45Z"
18654
+ remainingFraction: 0.9673149,
18655
+ resetTime: "2026-09-30T12:41:07Z"
18630
18656
  },
18631
18657
  recommended: true,
18632
18658
  supportedMimeTypes: {
@@ -18703,7 +18729,7 @@ var models_default = {
18703
18729
  modelProvider: "MODEL_PROVIDER_OPENAI",
18704
18730
  quotaInfo: {
18705
18731
  remainingFraction: 1,
18706
- resetTime: "2026-09-29T10:26:06Z"
18732
+ resetTime: "2026-09-30T12:45:45Z"
18707
18733
  },
18708
18734
  recommended: true,
18709
18735
  supportsThinking: true,
@@ -19775,9 +19801,14 @@ function normalizeToolSchemaTypes(tools, toolMapper) {
19775
19801
  fn.name = toolMapper ? toolMapper.toGemini(fn.name) : sanitizeToolName(fn.name);
19776
19802
  }
19777
19803
  if (fn) {
19804
+ if (!fn.parameters) {
19805
+ fn.parameters = fn.parameters_json_schema ?? fn.parametersJsonSchema;
19806
+ }
19778
19807
  if (!fn.parameters) {
19779
19808
  fn.parameters = { type: "OBJECT", properties: {} };
19780
19809
  }
19810
+ delete fn.parameters_json_schema;
19811
+ delete fn.parametersJsonSchema;
19781
19812
  sanitizeSchema(fn.parameters);
19782
19813
  }
19783
19814
  }
@@ -20202,22 +20233,81 @@ var ChatLoggerImpl = class {
20202
20233
  }
20203
20234
  };
20204
20235
 
20205
- // src/plugin.ts
20206
- var AGY_QUOTA_COMMAND = "agyquota";
20207
- var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
20208
-
20209
- Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
20210
- Do not call other tools.
20211
- `;
20212
- var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
20213
- 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.
20236
+ // src/plugin/headers.ts
20237
+ function getSafeHeader(headers, key) {
20238
+ if (!headers) {
20239
+ return void 0;
20240
+ }
20241
+ const targetKey = key.toLowerCase();
20242
+ if (typeof headers.get === "function") {
20243
+ try {
20244
+ return headers.get(targetKey) || void 0;
20245
+ } catch {
20246
+ }
20247
+ }
20248
+ if (Array.isArray(headers)) {
20249
+ const found = headers.find((item) => {
20250
+ if (Array.isArray(item) && typeof item[0] === "string") {
20251
+ return item[0].toLowerCase() === targetKey;
20252
+ }
20253
+ return false;
20254
+ });
20255
+ return found ? String(found[1]) : void 0;
20256
+ }
20257
+ if (typeof headers === "object") {
20258
+ const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
20259
+ return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
20260
+ }
20261
+ return void 0;
20262
+ }
20263
+ function setSafeHeaders(initHeaders, newHeaders) {
20264
+ if (typeof globalThis.Headers !== "undefined") {
20265
+ const headers = new globalThis.Headers(initHeaders ?? {});
20266
+ for (const [k, v] of Object.entries(newHeaders)) {
20267
+ headers.set(k, v);
20268
+ }
20269
+ return headers;
20270
+ }
20271
+ if (Array.isArray(initHeaders)) {
20272
+ const nextHeaders2 = [...initHeaders];
20273
+ for (const [k, v] of Object.entries(newHeaders)) {
20274
+ const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
20275
+ if (idx !== -1) {
20276
+ nextHeaders2[idx] = [k, v];
20277
+ } else {
20278
+ nextHeaders2.push([k, v]);
20279
+ }
20280
+ }
20281
+ return nextHeaders2;
20282
+ }
20283
+ const nextHeaders = {};
20284
+ if (initHeaders && typeof initHeaders === "object") {
20285
+ for (const [k, v] of Object.entries(initHeaders)) {
20286
+ nextHeaders[k] = String(v);
20287
+ }
20288
+ }
20289
+ for (const [k, v] of Object.entries(newHeaders)) {
20290
+ const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
20291
+ if (existingKey) {
20292
+ nextHeaders[existingKey] = v;
20293
+ } else {
20294
+ nextHeaders[k] = v;
20295
+ }
20296
+ }
20297
+ return nextHeaders;
20298
+ }
20299
+ function toUrlString(value) {
20300
+ if (typeof value === "string") {
20301
+ return value;
20302
+ }
20303
+ const candidate = value.url;
20304
+ if (candidate) {
20305
+ return candidate;
20306
+ }
20307
+ return value.toString();
20308
+ }
20214
20309
 
20215
- Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
20216
- Do not call other tools.
20217
- `;
20218
- var latestAgyAuthResolver;
20219
- var latestAgyConfiguredProjectId;
20220
- var latestAgyUserAgentModel;
20310
+ // src/plugin/tier.ts
20221
20311
  var STATIC_MODELS_SIMPLE = {
20222
20312
  "gemini-3.8-flash": {
20223
20313
  name: "Gemini 3.8 Flash",
@@ -20305,6 +20395,39 @@ var TIER_MAPPING = {
20305
20395
  high: "gemini-3.1-pro-high"
20306
20396
  }
20307
20397
  };
20398
+ function resolveModelTier(baseModelId, headersOrInit) {
20399
+ const parts = baseModelId.split("@");
20400
+ const base = parts[0] || "";
20401
+ const suffixTier = parts[1]?.toLowerCase();
20402
+ const mapping = TIER_MAPPING[base];
20403
+ if (!mapping) {
20404
+ return baseModelId;
20405
+ }
20406
+ const rawHeaders = headersOrInit && typeof headersOrInit === "object" && "headers" in headersOrInit ? headersOrInit.headers : headersOrInit;
20407
+ const headerTier = getSafeHeader(rawHeaders, "x-agy-tier")?.toLowerCase() || null;
20408
+ const requestedTier = headerTier || suffixTier;
20409
+ if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
20410
+ return mapping[requestedTier] || baseModelId;
20411
+ }
20412
+ return mapping["medium"] ?? mapping["high"] ?? baseModelId;
20413
+ }
20414
+
20415
+ // src/plugin.ts
20416
+ var AGY_QUOTA_COMMAND = "agyquota";
20417
+ var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
20418
+
20419
+ Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
20420
+ Do not call other tools.
20421
+ `;
20422
+ var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
20423
+ 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.
20424
+
20425
+ Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
20426
+ Do not call other tools.
20427
+ `;
20428
+ var latestAgyAuthResolver;
20429
+ var latestAgyConfiguredProjectId;
20430
+ var latestAgyUserAgentModel;
20308
20431
  var buildModelFromSimple = (modelId, simple) => {
20309
20432
  const isClaude = modelId.startsWith("claude-");
20310
20433
  const isGpt = modelId.startsWith("gpt-");
@@ -20398,83 +20521,6 @@ var STATIC_MODELS = {};
20398
20521
  for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
20399
20522
  STATIC_MODELS[modelId] = buildModelFromSimple(modelId, simple);
20400
20523
  }
20401
- function getSafeHeader(headers, key) {
20402
- if (!headers) {
20403
- return void 0;
20404
- }
20405
- const targetKey = key.toLowerCase();
20406
- if (typeof headers.get === "function") {
20407
- try {
20408
- return headers.get(targetKey) || void 0;
20409
- } catch {
20410
- }
20411
- }
20412
- if (Array.isArray(headers)) {
20413
- const found = headers.find((item) => {
20414
- if (Array.isArray(item) && typeof item[0] === "string") {
20415
- return item[0].toLowerCase() === targetKey;
20416
- }
20417
- return false;
20418
- });
20419
- return found ? String(found[1]) : void 0;
20420
- }
20421
- if (typeof headers === "object") {
20422
- const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
20423
- return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
20424
- }
20425
- return void 0;
20426
- }
20427
- function setSafeHeaders(initHeaders, newHeaders) {
20428
- if (typeof globalThis.Headers !== "undefined") {
20429
- const headers = new globalThis.Headers(initHeaders ?? {});
20430
- for (const [k, v] of Object.entries(newHeaders)) {
20431
- headers.set(k, v);
20432
- }
20433
- return headers;
20434
- }
20435
- if (Array.isArray(initHeaders)) {
20436
- const nextHeaders2 = [...initHeaders];
20437
- for (const [k, v] of Object.entries(newHeaders)) {
20438
- const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
20439
- if (idx !== -1) {
20440
- nextHeaders2[idx] = [k, v];
20441
- } else {
20442
- nextHeaders2.push([k, v]);
20443
- }
20444
- }
20445
- return nextHeaders2;
20446
- }
20447
- const nextHeaders = {};
20448
- if (initHeaders && typeof initHeaders === "object") {
20449
- for (const [k, v] of Object.entries(initHeaders)) {
20450
- nextHeaders[k] = String(v);
20451
- }
20452
- }
20453
- for (const [k, v] of Object.entries(newHeaders)) {
20454
- const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
20455
- if (existingKey) {
20456
- nextHeaders[existingKey] = v;
20457
- } else {
20458
- nextHeaders[k] = v;
20459
- }
20460
- }
20461
- return nextHeaders;
20462
- }
20463
- function resolveModelTier(baseModelId, init) {
20464
- const parts = baseModelId.split("@");
20465
- const base = parts[0] || "";
20466
- const suffixTier = parts[1]?.toLowerCase();
20467
- const mapping = TIER_MAPPING[base];
20468
- if (!mapping) {
20469
- return baseModelId;
20470
- }
20471
- const headerTier = getSafeHeader(init?.headers, "x-agy-tier")?.toLowerCase() || null;
20472
- const requestedTier = headerTier || suffixTier;
20473
- if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
20474
- return mapping[requestedTier] || baseModelId;
20475
- }
20476
- return mapping["medium"] ?? mapping["high"];
20477
- }
20478
20524
  var AgyCLIOAuthPlugin = async ({ client }) => {
20479
20525
  let latestConfig;
20480
20526
  updateStaticModelsWithPricing(STATIC_MODELS);
@@ -20802,25 +20848,782 @@ async function ensureProjectContextOrThrow(authRecord, client, configuredProject
20802
20848
  throw error45;
20803
20849
  }
20804
20850
  }
20805
- function toUrlString(value) {
20806
- if (typeof value === "string") {
20807
- return value;
20851
+
20852
+ // src/plugin/types.ts
20853
+ function defineOpenCodeV2Plugin(def) {
20854
+ return def;
20855
+ }
20856
+
20857
+ // src/plugin/v2-storage.ts
20858
+ import { closeSync, existsSync as existsSync6, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync5, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync5 } from "fs";
20859
+ import { randomUUID as randomUUID4 } from "crypto";
20860
+ import { homedir as homedir4 } from "os";
20861
+ import { join as join6 } from "path";
20862
+ var storedAuthOverrideForTesting = void 0;
20863
+ function loadStoredAuthFromJson() {
20864
+ if (storedAuthOverrideForTesting !== void 0) {
20865
+ return storedAuthOverrideForTesting;
20866
+ }
20867
+ const authPath = join6(homedir4(), ".local", "share", "opencode", "auth.json");
20868
+ try {
20869
+ if (existsSync6(authPath)) {
20870
+ const content = readFileSync5(authPath, "utf8");
20871
+ const data = JSON.parse(content);
20872
+ return data?.[AGY_PROVIDER_ID];
20873
+ }
20874
+ } catch {
20808
20875
  }
20809
- const candidate = value.url;
20810
- if (candidate) {
20811
- return candidate;
20876
+ return void 0;
20877
+ }
20878
+ function saveStoredAuthToJson(authRecord) {
20879
+ if (process.env.NODE_ENV === "test" || process.env.VITEST || storedAuthOverrideForTesting !== void 0) {
20880
+ return;
20812
20881
  }
20813
- return value.toString();
20882
+ const dirPath = join6(homedir4(), ".local", "share", "opencode");
20883
+ if (!existsSync6(dirPath)) {
20884
+ mkdirSync5(dirPath, { recursive: true });
20885
+ }
20886
+ const authPath = join6(dirPath, "auth.json");
20887
+ const data = existsSync6(authPath) ? JSON.parse(readFileSync5(authPath, "utf8")) : {};
20888
+ data[AGY_PROVIDER_ID] = {
20889
+ type: "oauth",
20890
+ refresh: authRecord.refresh,
20891
+ access: authRecord.access,
20892
+ expires: authRecord.expires
20893
+ };
20894
+ const tempPath = `${authPath}.${process.pid}.${randomUUID4()}.tmp`;
20895
+ let tempFileDescriptor;
20896
+ let ownsTempFile = false;
20897
+ try {
20898
+ tempFileDescriptor = openSync(tempPath, "wx", 384);
20899
+ ownsTempFile = true;
20900
+ writeFileSync5(tempFileDescriptor, JSON.stringify(data, null, 2), {
20901
+ encoding: "utf8"
20902
+ });
20903
+ closeSync(tempFileDescriptor);
20904
+ tempFileDescriptor = void 0;
20905
+ renameSync4(tempPath, authPath);
20906
+ } catch (error45) {
20907
+ if (tempFileDescriptor !== void 0) {
20908
+ try {
20909
+ closeSync(tempFileDescriptor);
20910
+ } catch {
20911
+ }
20912
+ }
20913
+ if (ownsTempFile) {
20914
+ try {
20915
+ unlinkSync4(tempPath);
20916
+ } catch {
20917
+ }
20918
+ }
20919
+ throw error45;
20920
+ }
20921
+ }
20922
+
20923
+ // src/plugin/v2-fetch.ts
20924
+ function createV2FetchInterceptor(getAuthSnapshot) {
20925
+ return async function agyV2Fetch(input, init) {
20926
+ const isGL = isGenerativeLanguageRequest(input);
20927
+ const isInternal = toUrlString(input).includes("cloudcode-pa.googleapis.com");
20928
+ if (!isGL && !isInternal) {
20929
+ return (globalThis.fetch || fetch)(input, init);
20930
+ }
20931
+ let rawAuth = getAuthSnapshot ? await getAuthSnapshot() : void 0;
20932
+ if (!rawAuth) {
20933
+ rawAuth = loadStoredAuthFromJson();
20934
+ }
20935
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
20936
+ return (globalThis.fetch || fetch)(input, init);
20937
+ }
20938
+ let authRecord = resolveCachedAuth(rawAuth);
20939
+ if (accessTokenExpired(authRecord)) {
20940
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
20941
+ } } });
20942
+ if (refreshed) {
20943
+ authRecord = refreshed;
20944
+ }
20945
+ }
20946
+ if (!authRecord.access) {
20947
+ return (globalThis.fetch || fetch)(input, init);
20948
+ }
20949
+ if (isInternal) {
20950
+ const hasAuth = getSafeHeader(init?.headers, "Authorization") !== void 0;
20951
+ if (hasAuth) {
20952
+ return (globalThis.fetch || fetch)(input, init);
20953
+ }
20954
+ const userAgent = buildAgyCliUserAgent();
20955
+ const headers = setSafeHeaders(init?.headers, {
20956
+ Authorization: `Bearer ${authRecord.access}`,
20957
+ "User-Agent": userAgent
20958
+ });
20959
+ return (globalThis.fetch || fetch)(input, {
20960
+ ...init,
20961
+ headers
20962
+ });
20963
+ }
20964
+ const requestTarget = parseGenerativeLanguageRequest(input);
20965
+ const requestUserAgentModel = requestTarget?.effectiveModel;
20966
+ let projectContext;
20967
+ try {
20968
+ projectContext = await ensureProjectContext(
20969
+ authRecord,
20970
+ { auth: { set: async () => {
20971
+ } } },
20972
+ void 0,
20973
+ requestUserAgentModel
20974
+ );
20975
+ } catch {
20976
+ projectContext = {
20977
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
20978
+ auth: authRecord
20979
+ };
20980
+ }
20981
+ const originalRequestedModel = parseGenerativeLanguageRequest(input)?.effectiveModel;
20982
+ let modifiedInput = input;
20983
+ if (isGL && originalRequestedModel) {
20984
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
20985
+ const resolvedBase = resolveModelTier(originalBase, init);
20986
+ if (originalBase !== resolvedBase) {
20987
+ if (typeof modifiedInput === "string") {
20988
+ modifiedInput = modifiedInput.replace(`models/${originalBase}`, `models/${resolvedBase}`);
20989
+ } else if (typeof Request !== "undefined" && modifiedInput instanceof Request) {
20990
+ const newUrl = modifiedInput.url.replace(`models/${originalBase}`, `models/${resolvedBase}`);
20991
+ modifiedInput = new Request(newUrl, modifiedInput);
20992
+ }
20993
+ }
20994
+ }
20995
+ const transformed = prepareAgyRequest(
20996
+ modifiedInput,
20997
+ init,
20998
+ authRecord.access,
20999
+ projectContext.effectiveProjectId,
21000
+ void 0
21001
+ );
21002
+ const chatLogger = createChatLogger();
21003
+ if (chatLogger) {
21004
+ chatLogger.logRequest(
21005
+ toUrlString(transformed.request),
21006
+ transformed.init.method || "GET",
21007
+ transformed.init.headers,
21008
+ transformed.init.body
21009
+ );
21010
+ }
21011
+ const response = await fetchWithRetry(transformed.request, transformed.init);
21012
+ return transformAgyResponse(
21013
+ response,
21014
+ transformed.streaming,
21015
+ null,
21016
+ transformed.requestedModel,
21017
+ transformed.sessionId,
21018
+ chatLogger
21019
+ );
21020
+ };
20814
21021
  }
20815
21022
 
21023
+ // src/plugin/v2-session.ts
21024
+ function createV2HttpRequestHook(state = {}) {
21025
+ return async (event) => {
21026
+ if (!event) return;
21027
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21028
+ const isGL = isGenerativeLanguageRequest(rawUrl);
21029
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21030
+ if (!isGL && !isInternal) {
21031
+ return;
21032
+ }
21033
+ event.headers = event.headers || {};
21034
+ let modelName;
21035
+ let rawAuth = event.auth;
21036
+ if (rawAuth && !rawAuth.type) {
21037
+ const tokenVal = rawAuth.access || rawAuth.token;
21038
+ if (tokenVal || rawAuth.refresh) {
21039
+ rawAuth = { type: "oauth", access: tokenVal, ...rawAuth };
21040
+ }
21041
+ }
21042
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
21043
+ rawAuth = loadStoredAuthFromJson();
21044
+ }
21045
+ let authRecord = rawAuth && isOAuthAuth(rawAuth) ? resolveCachedAuth(rawAuth) : void 0;
21046
+ if (authRecord && accessTokenExpired(authRecord)) {
21047
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
21048
+ } } });
21049
+ if (refreshed) {
21050
+ authRecord = refreshed;
21051
+ try {
21052
+ saveStoredAuthToJson(refreshed);
21053
+ } catch {
21054
+ console.warn("[Agy Auth] Refreshed credentials could not be persisted; the current request will continue.");
21055
+ }
21056
+ }
21057
+ }
21058
+ if (isGL) {
21059
+ const parsed = parseGenerativeLanguageRequest(rawUrl);
21060
+ modelName = parsed?.effectiveModel;
21061
+ if (modelName) {
21062
+ state.lastInterceptedModel = modelName;
21063
+ }
21064
+ if (typeof event.headers.delete === "function") {
21065
+ event.headers.delete("x-goog-api-key");
21066
+ event.headers.delete("api-key");
21067
+ } else {
21068
+ for (const key of Object.keys(event.headers)) {
21069
+ const lower = key.toLowerCase();
21070
+ if (lower === "x-goog-api-key" || lower === "api-key") {
21071
+ delete event.headers[key];
21072
+ }
21073
+ }
21074
+ }
21075
+ if (event.request?.headers) {
21076
+ if (typeof event.request.headers.delete === "function") {
21077
+ event.request.headers.delete("x-goog-api-key");
21078
+ event.request.headers.delete("api-key");
21079
+ } else {
21080
+ for (const key of Object.keys(event.request.headers)) {
21081
+ const lower = key.toLowerCase();
21082
+ if (lower === "x-goog-api-key" || lower === "api-key") {
21083
+ delete event.request.headers[key];
21084
+ }
21085
+ }
21086
+ }
21087
+ }
21088
+ let cleanUrl = rawUrl;
21089
+ try {
21090
+ const parsedUrl = new URL(rawUrl);
21091
+ let urlChanged = false;
21092
+ for (const param of ["key", "x-goog-api-key", "api-key"]) {
21093
+ if (parsedUrl.searchParams.has(param)) {
21094
+ parsedUrl.searchParams.delete(param);
21095
+ urlChanged = true;
21096
+ }
21097
+ }
21098
+ if (urlChanged) {
21099
+ cleanUrl = parsedUrl.toString();
21100
+ }
21101
+ } catch {
21102
+ }
21103
+ if (authRecord && authRecord.access) {
21104
+ let projectContext;
21105
+ try {
21106
+ projectContext = await ensureProjectContext(
21107
+ authRecord,
21108
+ { auth: { set: async () => {
21109
+ } } },
21110
+ void 0,
21111
+ modelName
21112
+ );
21113
+ } catch {
21114
+ projectContext = {
21115
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
21116
+ auth: authRecord
21117
+ };
21118
+ }
21119
+ const originalRequestedModel = modelName;
21120
+ let modifiedUrl = cleanUrl;
21121
+ if (originalRequestedModel) {
21122
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
21123
+ const initHeaders = event.headers instanceof Headers ? event.headers : event.request?.headers;
21124
+ const resolvedBase = resolveModelTier(originalBase, { headers: initHeaders });
21125
+ if (originalBase !== resolvedBase) {
21126
+ modifiedUrl = modifiedUrl.replace(`models/${originalBase}`, `models/${resolvedBase}`);
21127
+ }
21128
+ }
21129
+ let bodyPayload = event.body;
21130
+ if (bodyPayload === void 0 && event.request) {
21131
+ if (typeof event.request.clone === "function") {
21132
+ try {
21133
+ bodyPayload = await event.request.clone().text();
21134
+ } catch {
21135
+ }
21136
+ } else if (event.request.body !== void 0) {
21137
+ bodyPayload = event.request.body;
21138
+ }
21139
+ }
21140
+ let preExistingUserAgent;
21141
+ if (typeof event.headers?.get === "function") {
21142
+ preExistingUserAgent = event.headers.get("user-agent") || event.headers.get("User-Agent") || void 0;
21143
+ } else if (event.headers && typeof event.headers === "object") {
21144
+ preExistingUserAgent = event.headers["user-agent"] || event.headers["User-Agent"] || void 0;
21145
+ }
21146
+ if (!preExistingUserAgent && typeof event.request?.headers?.get === "function") {
21147
+ preExistingUserAgent = event.request.headers.get("user-agent") || event.request.headers.get("User-Agent") || void 0;
21148
+ } else if (!preExistingUserAgent && event.request?.headers && typeof event.request.headers === "object") {
21149
+ preExistingUserAgent = event.request.headers["user-agent"] || event.request.headers["User-Agent"] || void 0;
21150
+ }
21151
+ const method = event.method || event.request?.method || "POST";
21152
+ const requestHeaders = event.headers || event.request?.headers;
21153
+ const transformed = prepareAgyRequest(
21154
+ modifiedUrl,
21155
+ {
21156
+ method,
21157
+ headers: requestHeaders,
21158
+ body: bodyPayload
21159
+ },
21160
+ authRecord.access,
21161
+ projectContext.effectiveProjectId
21162
+ );
21163
+ const targetUrl = toUrlString(transformed.request);
21164
+ if (typeof event.url === "string") {
21165
+ event.url = targetUrl;
21166
+ }
21167
+ if (event.request && typeof event.request === "object") {
21168
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21169
+ event.request = new Request(targetUrl, {
21170
+ method: transformed.init.method,
21171
+ headers: transformed.init.headers,
21172
+ body: transformed.init.body
21173
+ });
21174
+ } else if (typeof event.request.url === "string") {
21175
+ try {
21176
+ event.request.url = targetUrl;
21177
+ } catch {
21178
+ }
21179
+ }
21180
+ }
21181
+ const headerEntries = transformed.init.headers instanceof Headers ? Array.from(transformed.init.headers.entries()) : Object.entries(transformed.init.headers || {});
21182
+ for (const [k, v] of headerEntries) {
21183
+ const lowerK = k.toLowerCase();
21184
+ if (lowerK === "user-agent") {
21185
+ if (preExistingUserAgent) {
21186
+ continue;
21187
+ }
21188
+ if (typeof event.headers?.set === "function") {
21189
+ event.headers.set("User-Agent", v);
21190
+ } else if (event.headers) {
21191
+ event.headers["User-Agent"] = v;
21192
+ }
21193
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21194
+ event.request.headers.set("User-Agent", v);
21195
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21196
+ event.request.headers["User-Agent"] = v;
21197
+ }
21198
+ continue;
21199
+ }
21200
+ if (typeof event.headers?.set === "function") {
21201
+ event.headers.set(k, v);
21202
+ } else if (event.headers) {
21203
+ event.headers[k] = v;
21204
+ }
21205
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21206
+ event.request.headers.set(k, v);
21207
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21208
+ event.request.headers[k] = v;
21209
+ }
21210
+ }
21211
+ if (transformed.init.body !== void 0) {
21212
+ event.body = transformed.init.body;
21213
+ if (event.request && typeof event.request === "object" && !(event.request instanceof Request)) {
21214
+ event.request.body = transformed.init.body;
21215
+ }
21216
+ }
21217
+ } else {
21218
+ if (typeof event.url === "string") {
21219
+ event.url = cleanUrl;
21220
+ }
21221
+ if (event.request && typeof event.request === "object") {
21222
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21223
+ event.request = new Request(cleanUrl, event.request);
21224
+ } else if (typeof event.request.url === "string") {
21225
+ try {
21226
+ event.request.url = cleanUrl;
21227
+ } catch {
21228
+ }
21229
+ }
21230
+ }
21231
+ }
21232
+ }
21233
+ if (authRecord && authRecord.access) {
21234
+ if (typeof event.headers?.set === "function") {
21235
+ event.headers.set("Authorization", `Bearer ${authRecord.access}`);
21236
+ } else if (event.headers) {
21237
+ event.headers["Authorization"] = `Bearer ${authRecord.access}`;
21238
+ }
21239
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21240
+ event.request.headers.set("Authorization", `Bearer ${authRecord.access}`);
21241
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21242
+ event.request.headers["Authorization"] = `Bearer ${authRecord.access}`;
21243
+ }
21244
+ }
21245
+ const userAgent = buildAgyCliUserAgent(modelName);
21246
+ if (typeof event.headers?.set === "function") {
21247
+ if (!event.headers.get("User-Agent") && !event.headers.get("user-agent")) {
21248
+ event.headers.set("User-Agent", userAgent);
21249
+ }
21250
+ } else if (event.headers) {
21251
+ if (!event.headers["User-Agent"] && !event.headers["user-agent"]) {
21252
+ event.headers["User-Agent"] = userAgent;
21253
+ }
21254
+ }
21255
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21256
+ if (!event.request.headers.get("User-Agent") && !event.request.headers.get("user-agent")) {
21257
+ event.request.headers.set("User-Agent", userAgent);
21258
+ }
21259
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21260
+ if (!event.request.headers["User-Agent"] && !event.request.headers["user-agent"]) {
21261
+ event.request.headers["User-Agent"] = userAgent;
21262
+ }
21263
+ }
21264
+ };
21265
+ }
21266
+ function createV2HttpResponseHook(state = {}) {
21267
+ return async (event) => {
21268
+ if (!event || !event.response) return;
21269
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21270
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21271
+ if (isInternal && event.response instanceof Response) {
21272
+ const isStreaming = rawUrl.includes(":streamGenerateCode") || event.response.headers.get("content-type")?.includes("text/event-stream");
21273
+ const parsedModel = parseGenerativeLanguageRequest(rawUrl)?.effectiveModel || state.lastInterceptedModel;
21274
+ const transformed = await transformAgyResponse(
21275
+ event.response,
21276
+ !!isStreaming,
21277
+ null,
21278
+ parsedModel,
21279
+ void 0,
21280
+ void 0
21281
+ );
21282
+ event.response = transformed;
21283
+ }
21284
+ };
21285
+ }
21286
+ function createV2RetryHook() {
21287
+ return async (event) => {
21288
+ if (!event) return;
21289
+ const response = event.response;
21290
+ if (response instanceof Response) {
21291
+ if (response.status === 429 || response.status === 503) {
21292
+ const quota = await classifyQuotaResponse(response);
21293
+ if (quota?.retryDelayMs) {
21294
+ event.retryDelayMs = quota.retryDelayMs;
21295
+ } else {
21296
+ event.retryDelayMs = await resolveRetryDelayMs(response, event.attempt || 1);
21297
+ }
21298
+ }
21299
+ } else if (event.details && Array.isArray(event.details)) {
21300
+ const retryInfo = event.details.find(
21301
+ (d) => d && d["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
21302
+ );
21303
+ if (retryInfo?.retryDelay) {
21304
+ const delayMs = retryInternals.parseRetryDelayValue(retryInfo.retryDelay);
21305
+ if (delayMs !== null) {
21306
+ event.retryDelayMs = delayMs;
21307
+ }
21308
+ }
21309
+ }
21310
+ };
21311
+ }
21312
+ function registerV2SessionHooks(ctx) {
21313
+ const state = {};
21314
+ ctx.session.hook("http.request", createV2HttpRequestHook(state), { providerID: AGY_PROVIDER_ID });
21315
+ ctx.session.hook("http.response", createV2HttpResponseHook(state), { providerID: AGY_PROVIDER_ID });
21316
+ ctx.session.hook("retry", createV2RetryHook(), { providerID: AGY_PROVIDER_ID });
21317
+ }
21318
+
21319
+ // src/plugin/v2.ts
21320
+ async function setupOpenCodeV2(ctx) {
21321
+ const resolveVariants = (modelId) => {
21322
+ const mapping = TIER_MAPPING[modelId];
21323
+ if (!mapping) return void 0;
21324
+ const variants = [];
21325
+ if (mapping.minimal !== void 0) variants.push({ id: "minimal" });
21326
+ if (mapping.low !== void 0) variants.push({ id: "low" });
21327
+ if (mapping.medium !== void 0) variants.push({ id: "medium" });
21328
+ if (mapping.high !== void 0) variants.push({ id: "high" });
21329
+ return variants.length > 0 ? variants : void 0;
21330
+ };
21331
+ const updateProviderRecord = (p) => {
21332
+ p.name = "Antigravity CLI";
21333
+ p.activation = "enabled";
21334
+ p.package = "aisdk:@ai-sdk/google";
21335
+ p.description = "Google Gemini Antigravity Code Assist OAuth provider";
21336
+ p.settings = { ...p.settings || {}, apiKey: "dummy" };
21337
+ p.integrationID = AGY_PROVIDER_ID;
21338
+ };
21339
+ const buildModelRecord = (modelId, simple, existingModel) => {
21340
+ const isClaude = modelId.startsWith("claude-");
21341
+ const isGpt = modelId.startsWith("gpt-");
21342
+ const variants = resolveVariants(modelId);
21343
+ return {
21344
+ id: modelId,
21345
+ providerID: AGY_PROVIDER_ID,
21346
+ name: simple.name,
21347
+ description: simple.description,
21348
+ family: modelId.includes("gemini") ? "gemini" : isClaude ? "claude" : isGpt ? "gpt" : "unknown",
21349
+ reasoning: simple.reasoning,
21350
+ attachment: simple.attachment,
21351
+ tool_call: simple.toolCall,
21352
+ limit: {
21353
+ context: simple.maxTokens,
21354
+ output: simple.maxOutputTokens
21355
+ },
21356
+ cost: simple.cost || { input: 0, output: 0 },
21357
+ ...variants ? { variants } : {},
21358
+ ...existingModel || {}
21359
+ };
21360
+ };
21361
+ const updateModelRecord = (m, modelId, simple) => {
21362
+ m.name = simple.name;
21363
+ m.capabilities = {
21364
+ tools: true,
21365
+ input: ["text", "image"],
21366
+ output: ["text"]
21367
+ };
21368
+ m.limit = {
21369
+ context: simple.maxTokens,
21370
+ output: simple.maxOutputTokens
21371
+ };
21372
+ m.family = "gemini";
21373
+ if (simple.cost) {
21374
+ m.cost = simple.cost;
21375
+ }
21376
+ const variants = resolveVariants(modelId);
21377
+ if (variants) {
21378
+ m.variants = variants;
21379
+ }
21380
+ };
21381
+ if (ctx.provider?.transform) {
21382
+ ctx.provider.transform(async (editor) => {
21383
+ if (!editor) return;
21384
+ if (typeof editor.update === "function") {
21385
+ editor.update(AGY_PROVIDER_ID, updateProviderRecord);
21386
+ } else if (typeof editor.set === "function") {
21387
+ const p = { id: AGY_PROVIDER_ID };
21388
+ updateProviderRecord(p);
21389
+ editor.set(AGY_PROVIDER_ID, p);
21390
+ } else if (typeof editor === "object") {
21391
+ const p = editor[AGY_PROVIDER_ID] || { id: AGY_PROVIDER_ID };
21392
+ updateProviderRecord(p);
21393
+ editor[AGY_PROVIDER_ID] = p;
21394
+ }
21395
+ });
21396
+ }
21397
+ if (ctx.model?.transform) {
21398
+ ctx.model.transform(async (editor) => {
21399
+ if (!editor) return;
21400
+ if (typeof editor.update === "function") {
21401
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21402
+ editor.update(AGY_PROVIDER_ID, modelId, (m) => updateModelRecord(m, modelId, simple));
21403
+ }
21404
+ } else if (typeof editor.set === "function") {
21405
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21406
+ const m = buildModelRecord(modelId, simple);
21407
+ editor.set(`${AGY_PROVIDER_ID}:${modelId}`, m);
21408
+ }
21409
+ } else if (typeof editor === "object") {
21410
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21411
+ const key = `${AGY_PROVIDER_ID}:${modelId}`;
21412
+ editor[key] = buildModelRecord(modelId, simple, editor[key]);
21413
+ }
21414
+ }
21415
+ });
21416
+ }
21417
+ if (ctx.catalog?.transform) {
21418
+ ctx.catalog.transform(async (editor) => {
21419
+ if (!editor) return;
21420
+ if (typeof editor?.provider?.update === "function") {
21421
+ editor.provider.update(AGY_PROVIDER_ID, updateProviderRecord);
21422
+ if (typeof editor?.model?.update === "function") {
21423
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21424
+ editor.model.update(AGY_PROVIDER_ID, modelId, (m) => updateModelRecord(m, modelId, simple));
21425
+ }
21426
+ }
21427
+ return;
21428
+ }
21429
+ const catalog = editor;
21430
+ catalog.providers = catalog.providers || {};
21431
+ catalog.providers[AGY_PROVIDER_ID] = {
21432
+ id: AGY_PROVIDER_ID,
21433
+ name: "Antigravity CLI",
21434
+ npm: "aisdk:@ai-sdk/google",
21435
+ settings: { apiKey: "dummy" },
21436
+ integrationID: AGY_PROVIDER_ID,
21437
+ models: { ...catalog.providers[AGY_PROVIDER_ID]?.models || {} },
21438
+ ...catalog.providers[AGY_PROVIDER_ID]
21439
+ };
21440
+ if (catalog.providers[AGY_PROVIDER_ID].settings) {
21441
+ catalog.providers[AGY_PROVIDER_ID].settings = {
21442
+ ...catalog.providers[AGY_PROVIDER_ID].settings,
21443
+ apiKey: "dummy"
21444
+ };
21445
+ } else {
21446
+ catalog.providers[AGY_PROVIDER_ID].settings = { apiKey: "dummy" };
21447
+ }
21448
+ catalog.providers[AGY_PROVIDER_ID].integrationID = AGY_PROVIDER_ID;
21449
+ const targetModels = catalog.providers[AGY_PROVIDER_ID].models;
21450
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21451
+ targetModels[modelId] = buildModelRecord(modelId, simple, targetModels[modelId]);
21452
+ }
21453
+ });
21454
+ }
21455
+ ctx.tool.transform(async (editor) => {
21456
+ if (!editor) return;
21457
+ const quotaTool = createAgyQuotaTool({
21458
+ client: void 0,
21459
+ getAuthResolver: () => void 0,
21460
+ getConfiguredProjectId: () => void 0,
21461
+ getUserAgentModel: () => void 0
21462
+ });
21463
+ const quotaSummaryTool = createAgyQuotaSummaryTool({
21464
+ client: void 0,
21465
+ getAuthResolver: () => void 0,
21466
+ getConfiguredProjectId: () => void 0,
21467
+ getUserAgentModel: () => void 0
21468
+ });
21469
+ if (typeof editor.add === "function") {
21470
+ editor.add({
21471
+ name: AGY_QUOTA_TOOL_NAME,
21472
+ description: quotaTool.description,
21473
+ input: {},
21474
+ execute: async (args, context) => quotaTool.execute(args, context)
21475
+ });
21476
+ editor.add({
21477
+ name: AGY_QUOTA_SUMMARY_TOOL_NAME,
21478
+ description: quotaSummaryTool.description,
21479
+ input: {},
21480
+ execute: async (args, context) => quotaSummaryTool.execute(args, context)
21481
+ });
21482
+ } else if (typeof editor.set === "function") {
21483
+ editor.set(AGY_QUOTA_TOOL_NAME, quotaTool);
21484
+ editor.set(AGY_QUOTA_SUMMARY_TOOL_NAME, quotaSummaryTool);
21485
+ } else if (editor.tools && typeof editor.tools === "object") {
21486
+ editor.tools[AGY_QUOTA_TOOL_NAME] = quotaTool;
21487
+ editor.tools[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
21488
+ } else if (typeof editor === "object") {
21489
+ editor[AGY_QUOTA_TOOL_NAME] = quotaTool;
21490
+ editor[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
21491
+ }
21492
+ });
21493
+ ctx.command.transform(async (editor) => {
21494
+ if (!editor) return;
21495
+ const commands = {
21496
+ [AGY_V2_QUOTA_COMMAND]: {
21497
+ description: "Show Agy Code Assist quota usage",
21498
+ template: AGY_V2_QUOTA_COMMAND_TEMPLATE
21499
+ },
21500
+ [AGY_V2_QUOTA_SUMMARY_COMMAND]: {
21501
+ description: "Show Agy Code Assist quota summary with weekly and 5-hour limits",
21502
+ template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
21503
+ }
21504
+ };
21505
+ if (typeof editor.add === "function") {
21506
+ editor.add({
21507
+ name: AGY_V2_QUOTA_COMMAND,
21508
+ description: "Display current Antigravity quota usage",
21509
+ template: AGY_V2_QUOTA_COMMAND_TEMPLATE
21510
+ });
21511
+ editor.add({
21512
+ name: AGY_V2_QUOTA_SUMMARY_COMMAND,
21513
+ description: "Display Antigravity quota summary grouped by model family",
21514
+ template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
21515
+ });
21516
+ } else if (typeof editor.set === "function") {
21517
+ editor.set(AGY_V2_QUOTA_COMMAND, commands[AGY_V2_QUOTA_COMMAND]);
21518
+ editor.set(AGY_V2_QUOTA_SUMMARY_COMMAND, commands[AGY_V2_QUOTA_SUMMARY_COMMAND]);
21519
+ } else if (editor.commands && typeof editor.commands === "object") {
21520
+ editor.commands[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
21521
+ editor.commands[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
21522
+ } else if (typeof editor === "object") {
21523
+ editor[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
21524
+ editor[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
21525
+ }
21526
+ });
21527
+ ctx.integration?.transform?.((editor) => {
21528
+ if (!editor) return;
21529
+ editor.update?.(AGY_PROVIDER_ID, (integration) => {
21530
+ integration.name = "Antigravity CLI (plugin)";
21531
+ });
21532
+ editor.method?.update?.({
21533
+ integrationID: AGY_PROVIDER_ID,
21534
+ method: {
21535
+ id: "oauth",
21536
+ type: "oauth",
21537
+ label: "Antigravity CLI (OAuth)"
21538
+ },
21539
+ authorize: async () => {
21540
+ const authorization = await authorizeAgy();
21541
+ return {
21542
+ mode: "code",
21543
+ url: authorization.url,
21544
+ instructions: "Please complete Google account authorization in your browser. After authorization, copy the full redirect URL or code and paste it below:",
21545
+ callback: async (code) => {
21546
+ const trimmed = code.trim();
21547
+ const parsed = parseOAuthCallbackInput(trimmed);
21548
+ const authCode = parsed.code || trimmed;
21549
+ if (!authCode) {
21550
+ return { type: "failed", error: "Missing authorization code in callback input" };
21551
+ }
21552
+ if (parsed.state && parsed.state !== authorization.state) {
21553
+ return { type: "failed", error: "State mismatch in callback input (possible CSRF attempt)" };
21554
+ }
21555
+ const exchangeResult = await exchangeAgyWithVerifier(authCode, authorization.verifier);
21556
+ if (exchangeResult.type !== "success") {
21557
+ return exchangeResult;
21558
+ }
21559
+ const initialRefresh = formatRefreshParts({
21560
+ refreshToken: exchangeResult.refresh
21561
+ });
21562
+ let authRecord = {
21563
+ type: "oauth",
21564
+ refresh: initialRefresh,
21565
+ access: exchangeResult.access,
21566
+ expires: exchangeResult.expires
21567
+ };
21568
+ try {
21569
+ const projectContext = await ensureProjectContext(
21570
+ authRecord,
21571
+ { auth: { set: async () => {
21572
+ } } }
21573
+ );
21574
+ authRecord = {
21575
+ ...authRecord,
21576
+ refresh: projectContext.auth.refresh
21577
+ };
21578
+ } catch {
21579
+ }
21580
+ try {
21581
+ saveStoredAuthToJson(authRecord);
21582
+ } catch {
21583
+ return {
21584
+ type: "failed",
21585
+ error: "Google authentication succeeded but AGY credentials could not be stored. Check filesystem access and retry."
21586
+ };
21587
+ }
21588
+ return {
21589
+ type: "oauth",
21590
+ methodID: "oauth",
21591
+ refresh: authRecord.refresh,
21592
+ access: authRecord.access,
21593
+ expires: authRecord.expires
21594
+ };
21595
+ }
21596
+ };
21597
+ }
21598
+ });
21599
+ });
21600
+ ctx.aisdk?.hook("sdk", async (event) => {
21601
+ if (!event) return;
21602
+ const isMatchingProvider = event.providerID === AGY_PROVIDER_ID || event.model?.providerID === AGY_PROVIDER_ID;
21603
+ if (!isMatchingProvider) return;
21604
+ event.options = event.options || {};
21605
+ event.options.apiKey = "dummy";
21606
+ event.options.fetch = createV2FetchInterceptor();
21607
+ });
21608
+ registerV2SessionHooks(ctx);
21609
+ }
21610
+ var v2PluginDefinition = defineOpenCodeV2Plugin({
21611
+ id: AGY_PROVIDER_ID,
21612
+ setup: setupOpenCodeV2
21613
+ });
21614
+
20816
21615
  // index.ts
20817
- var index_default = {
20818
- id: "@anthonyhaussman/opencode-agy-auth",
21616
+ var dualPlugin = {
21617
+ ...v2PluginDefinition,
20819
21618
  server: AgyCLIOAuthPlugin
20820
21619
  };
21620
+ var index_default = dualPlugin;
20821
21621
  export {
20822
21622
  AgyCLIOAuthPlugin,
20823
21623
  GoogleOAuthPlugin,
20824
- index_default as default
21624
+ index_default as default,
21625
+ defineOpenCodeV2Plugin,
21626
+ setupOpenCodeV2,
21627
+ v2PluginDefinition
20825
21628
  };
20826
21629
  //# sourceMappingURL=index.js.map