@anthonyhaussman/opencode-agy-auth 1.2.3-alpha.7 → 1.2.3-alpha.8

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
@@ -20694,7 +20694,7 @@ function defineOpenCodeV2Plugin(def) {
20694
20694
  // src/plugin/v2.ts
20695
20695
  import { homedir as homedir4 } from "os";
20696
20696
  import { join as join6 } from "path";
20697
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
20697
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
20698
20698
  import "http";
20699
20699
  var AGY_V2_QUOTA_COMMAND = "agy-quota";
20700
20700
  var AGY_V2_QUOTA_SUMMARY_COMMAND = "agy-quota-summary";
@@ -20811,6 +20811,34 @@ function loadStoredAuthFromJson() {
20811
20811
  }
20812
20812
  return void 0;
20813
20813
  }
20814
+ function saveStoredAuthToJson(authRecord) {
20815
+ if (process.env.NODE_ENV === "test" || process.env.VITEST || storedAuthOverrideForTesting !== void 0) {
20816
+ return;
20817
+ }
20818
+ try {
20819
+ const dirPath = join6(homedir4(), ".local", "share", "opencode");
20820
+ if (!existsSync6(dirPath)) {
20821
+ mkdirSync5(dirPath, { recursive: true });
20822
+ }
20823
+ const authPath = join6(dirPath, "auth.json");
20824
+ let data = {};
20825
+ if (existsSync6(authPath)) {
20826
+ try {
20827
+ data = JSON.parse(readFileSync5(authPath, "utf8")) || {};
20828
+ } catch {
20829
+ data = {};
20830
+ }
20831
+ }
20832
+ data[AGY_PROVIDER_ID] = {
20833
+ type: "oauth",
20834
+ refresh: authRecord.refresh,
20835
+ access: authRecord.access,
20836
+ expires: authRecord.expires
20837
+ };
20838
+ writeFileSync5(authPath, JSON.stringify(data, null, 2), "utf8");
20839
+ } catch {
20840
+ }
20841
+ }
20814
20842
  function createV2FetchInterceptor(getAuthSnapshot) {
20815
20843
  return async function agyV2Fetch(input, init) {
20816
20844
  const isGL = isGenerativeLanguageRequest(input);
@@ -21126,8 +21154,10 @@ async function setupOpenCodeV2(ctx) {
21126
21154
  };
21127
21155
  } catch {
21128
21156
  }
21157
+ saveStoredAuthToJson(authRecord);
21129
21158
  return {
21130
- type: "success",
21159
+ type: "oauth",
21160
+ methodID: "oauth",
21131
21161
  refresh: authRecord.refresh,
21132
21162
  access: authRecord.access,
21133
21163
  expires: authRecord.expires
@@ -21157,6 +21187,25 @@ async function setupOpenCodeV2(ctx) {
21157
21187
  }
21158
21188
  event.headers = event.headers || {};
21159
21189
  let modelName;
21190
+ let rawAuth = event.auth;
21191
+ if (rawAuth && !rawAuth.type) {
21192
+ const tokenVal = rawAuth.access || rawAuth.token;
21193
+ if (tokenVal || rawAuth.refresh) {
21194
+ rawAuth = { type: "oauth", access: tokenVal, ...rawAuth };
21195
+ }
21196
+ }
21197
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
21198
+ rawAuth = loadStoredAuthFromJson();
21199
+ }
21200
+ let authRecord = rawAuth && isOAuthAuth(rawAuth) ? resolveCachedAuth(rawAuth) : void 0;
21201
+ if (authRecord && accessTokenExpired(authRecord)) {
21202
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
21203
+ } } });
21204
+ if (refreshed) {
21205
+ authRecord = refreshed;
21206
+ saveStoredAuthToJson(refreshed);
21207
+ }
21208
+ }
21160
21209
  if (isGL) {
21161
21210
  const parsed = parseGenerativeLanguageRequest(rawUrl);
21162
21211
  modelName = parsed?.effectiveModel;
@@ -21184,6 +21233,7 @@ async function setupOpenCodeV2(ctx) {
21184
21233
  }
21185
21234
  }
21186
21235
  }
21236
+ let cleanUrl = rawUrl;
21187
21237
  try {
21188
21238
  const parsedUrl = new URL(rawUrl);
21189
21239
  let urlChanged = false;
@@ -21194,63 +21244,187 @@ async function setupOpenCodeV2(ctx) {
21194
21244
  }
21195
21245
  }
21196
21246
  if (urlChanged) {
21197
- const cleanedUrl = parsedUrl.toString();
21198
- if (typeof event.url === "string") {
21199
- event.url = cleanedUrl;
21247
+ cleanUrl = parsedUrl.toString();
21248
+ }
21249
+ } catch {
21250
+ }
21251
+ if (authRecord && authRecord.access) {
21252
+ let projectContext;
21253
+ try {
21254
+ projectContext = await ensureProjectContext(
21255
+ authRecord,
21256
+ { auth: { set: async () => {
21257
+ } } },
21258
+ void 0,
21259
+ modelName
21260
+ );
21261
+ } catch {
21262
+ projectContext = {
21263
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
21264
+ auth: authRecord
21265
+ };
21266
+ }
21267
+ const originalRequestedModel = modelName;
21268
+ let modifiedUrl = cleanUrl;
21269
+ if (originalRequestedModel) {
21270
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
21271
+ const initHeaders = event.headers instanceof Headers ? event.headers : event.request?.headers;
21272
+ const resolvedBase = resolveModelTier2(originalBase, { headers: initHeaders });
21273
+ if (originalBase !== resolvedBase) {
21274
+ modifiedUrl = modifiedUrl.replace(`models/${originalBase}`, `models/${resolvedBase}`);
21200
21275
  }
21201
- if (event.request && typeof event.request === "object") {
21202
- if (typeof event.request.url === "string") {
21203
- event.request.url = cleanedUrl;
21276
+ }
21277
+ let bodyPayload = event.body;
21278
+ if (bodyPayload === void 0 && event.request) {
21279
+ if (typeof event.request.clone === "function") {
21280
+ try {
21281
+ bodyPayload = await event.request.clone().text();
21282
+ } catch {
21204
21283
  }
21284
+ } else if (event.request.body !== void 0) {
21285
+ bodyPayload = event.request.body;
21205
21286
  }
21206
21287
  }
21207
- } catch {
21208
- }
21209
- const hasAuth = typeof event.headers?.get === "function" ? !!event.headers.get("Authorization") : event.headers && Object.keys(event.headers).some((k) => k.toLowerCase() === "authorization");
21210
- if (!hasAuth) {
21211
- let token;
21212
- if (typeof event.auth?.access === "string" && event.auth.access) {
21213
- token = event.auth.access;
21214
- } else if (typeof event.auth?.token === "string" && event.auth.token) {
21215
- token = event.auth.token;
21216
- } else {
21217
- const storedAuth = loadStoredAuthFromJson();
21218
- if (storedAuth && isOAuthAuth(storedAuth)) {
21219
- const resolved = resolveCachedAuth(storedAuth);
21220
- token = resolved.access;
21288
+ let preExistingUserAgent;
21289
+ if (typeof event.headers?.get === "function") {
21290
+ preExistingUserAgent = event.headers.get("user-agent") || event.headers.get("User-Agent") || void 0;
21291
+ } else if (event.headers && typeof event.headers === "object") {
21292
+ preExistingUserAgent = event.headers["user-agent"] || event.headers["User-Agent"] || void 0;
21293
+ }
21294
+ if (!preExistingUserAgent && typeof event.request?.headers?.get === "function") {
21295
+ preExistingUserAgent = event.request.headers.get("user-agent") || event.request.headers.get("User-Agent") || void 0;
21296
+ } else if (!preExistingUserAgent && event.request?.headers && typeof event.request.headers === "object") {
21297
+ preExistingUserAgent = event.request.headers["user-agent"] || event.request.headers["User-Agent"] || void 0;
21298
+ }
21299
+ const method = event.method || event.request?.method || "POST";
21300
+ const requestHeaders = event.headers || event.request?.headers;
21301
+ const transformed = prepareAgyRequest(
21302
+ modifiedUrl,
21303
+ {
21304
+ method,
21305
+ headers: requestHeaders,
21306
+ body: bodyPayload
21307
+ },
21308
+ authRecord.access,
21309
+ projectContext.effectiveProjectId
21310
+ );
21311
+ const targetUrl = toUrlString2(transformed.request);
21312
+ if (typeof event.url === "string") {
21313
+ event.url = targetUrl;
21314
+ }
21315
+ if (event.request && typeof event.request === "object") {
21316
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21317
+ event.request = new Request(targetUrl, {
21318
+ method: transformed.init.method,
21319
+ headers: transformed.init.headers,
21320
+ body: transformed.init.body
21321
+ });
21322
+ } else if (typeof event.request.url === "string") {
21323
+ try {
21324
+ event.request.url = targetUrl;
21325
+ } catch {
21326
+ }
21221
21327
  }
21222
21328
  }
21223
- if (token) {
21329
+ const headerEntries = transformed.init.headers instanceof Headers ? Array.from(transformed.init.headers.entries()) : Object.entries(transformed.init.headers || {});
21330
+ for (const [k, v] of headerEntries) {
21331
+ const lowerK = k.toLowerCase();
21332
+ if (lowerK === "user-agent") {
21333
+ if (preExistingUserAgent) {
21334
+ continue;
21335
+ }
21336
+ if (typeof event.headers?.set === "function") {
21337
+ event.headers.set("User-Agent", v);
21338
+ } else if (event.headers) {
21339
+ event.headers["User-Agent"] = v;
21340
+ }
21341
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21342
+ event.request.headers.set("User-Agent", v);
21343
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21344
+ event.request.headers["User-Agent"] = v;
21345
+ }
21346
+ continue;
21347
+ }
21224
21348
  if (typeof event.headers?.set === "function") {
21225
- event.headers.set("Authorization", `Bearer ${token}`);
21349
+ event.headers.set(k, v);
21226
21350
  } else if (event.headers) {
21227
- event.headers["Authorization"] = `Bearer ${token}`;
21351
+ event.headers[k] = v;
21228
21352
  }
21229
21353
  if (event.request?.headers && typeof event.request.headers.set === "function") {
21230
- event.request.headers.set("Authorization", `Bearer ${token}`);
21354
+ event.request.headers.set(k, v);
21355
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21356
+ event.request.headers[k] = v;
21357
+ }
21358
+ }
21359
+ if (transformed.init.body !== void 0) {
21360
+ event.body = transformed.init.body;
21361
+ if (event.request && typeof event.request === "object" && !(event.request instanceof Request)) {
21362
+ event.request.body = transformed.init.body;
21363
+ }
21364
+ }
21365
+ } else {
21366
+ if (typeof event.url === "string") {
21367
+ event.url = cleanUrl;
21368
+ }
21369
+ if (event.request && typeof event.request === "object") {
21370
+ if (typeof event.request.url === "string") {
21371
+ event.request.url = cleanUrl;
21231
21372
  }
21232
21373
  }
21233
21374
  }
21234
21375
  }
21376
+ if (authRecord && authRecord.access) {
21377
+ if (typeof event.headers?.set === "function") {
21378
+ event.headers.set("Authorization", `Bearer ${authRecord.access}`);
21379
+ } else if (event.headers) {
21380
+ event.headers["Authorization"] = `Bearer ${authRecord.access}`;
21381
+ }
21382
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21383
+ event.request.headers.set("Authorization", `Bearer ${authRecord.access}`);
21384
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21385
+ event.request.headers["Authorization"] = `Bearer ${authRecord.access}`;
21386
+ }
21387
+ }
21235
21388
  const userAgent = buildAgyCliUserAgent(modelName);
21236
- if (typeof event.headers.set === "function") {
21237
- if (!event.headers.get("User-Agent")) {
21389
+ if (typeof event.headers?.set === "function") {
21390
+ if (!event.headers.get("User-Agent") && !event.headers.get("user-agent")) {
21238
21391
  event.headers.set("User-Agent", userAgent);
21239
21392
  }
21240
- } else {
21393
+ } else if (event.headers) {
21241
21394
  if (!event.headers["User-Agent"] && !event.headers["user-agent"]) {
21242
21395
  event.headers["User-Agent"] = userAgent;
21243
21396
  }
21244
21397
  }
21398
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21399
+ if (!event.request.headers.get("User-Agent") && !event.request.headers.get("user-agent")) {
21400
+ event.request.headers.set("User-Agent", userAgent);
21401
+ }
21402
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21403
+ if (!event.request.headers["User-Agent"] && !event.request.headers["user-agent"]) {
21404
+ event.request.headers["User-Agent"] = userAgent;
21405
+ }
21406
+ }
21245
21407
  },
21246
21408
  { providerID: AGY_PROVIDER_ID }
21247
21409
  );
21248
21410
  ctx.session.hook(
21249
21411
  "http.response",
21250
21412
  async (event) => {
21251
- if (!event) return;
21252
- if (event.response?.status === 429) {
21253
- return;
21413
+ if (!event || !event.response) return;
21414
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21415
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21416
+ if (isInternal && event.response instanceof Response) {
21417
+ const isStreaming = rawUrl.includes(":streamGenerateCode") || event.response.headers.get("content-type")?.includes("text/event-stream");
21418
+ const parsedModel = parseGenerativeLanguageRequest(rawUrl)?.effectiveModel;
21419
+ const transformed = transformAgyResponse(
21420
+ event.response,
21421
+ !!isStreaming,
21422
+ null,
21423
+ parsedModel,
21424
+ void 0,
21425
+ void 0
21426
+ );
21427
+ event.response = transformed;
21254
21428
  }
21255
21429
  },
21256
21430
  { providerID: AGY_PROVIDER_ID }