Jelajahi Sumber

fix(opencode): pass OAuth scopes to GoogleAuth for Vertex AI (#15110)

Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Saurav M H 3 bulan lalu
induk
melakukan
797c689ec2

+ 3 - 3
packages/core/src/plugin/provider/google-vertex.ts

@@ -43,9 +43,9 @@ function authFetch(fetchWithRuntimeOptions?: unknown) {
   // do not, so inject a Google access token into their fetch path.
   return async (input: Parameters<typeof fetch>[0], init?: RequestInit) => {
     const { GoogleAuth } = await import("google-auth-library")
-    const auth = new GoogleAuth()
-    const client = await auth.getApplicationDefault()
-    const token = await client.credential.getAccessToken()
+    const auth = new GoogleAuth({ scopes: ["https://www.googleapis.com/auth/cloud-platform"] })
+    const client = await auth.getClient()
+    const token = await client.getAccessToken()
     const headers = new Headers(init?.headers)
     headers.set("Authorization", `Bearer ${token.token}`)
     return typeof fetchWithRuntimeOptions === "function"

+ 10 - 5
packages/core/test/plugin/provider-google-vertex.test.ts

@@ -7,6 +7,7 @@ import { ProviderV2 } from "@opencode-ai/core/provider"
 import { fakeSelectorSdk, it, model, withEnv } from "./provider-helper"
 
 const vertexOptions: Record<string, any>[] = []
+const googleAuthOptions: Record<string, any>[] = []
 
 void mock.module("@ai-sdk/google-vertex", () => ({
   createVertex: (options: Record<string, any>) => {
@@ -19,12 +20,14 @@ void mock.module("@ai-sdk/google-vertex", () => ({
 
 void mock.module("google-auth-library", () => ({
   GoogleAuth: class {
-    async getApplicationDefault() {
+    constructor(options: Record<string, any>) {
+      googleAuthOptions.push(options)
+    }
+
+    async getClient() {
       return {
-        credential: {
-          async getAccessToken() {
-            return { token: "vertex-token" }
-          },
+        async getAccessToken() {
+          return { token: "vertex-token" }
         },
       }
     }
@@ -247,6 +250,7 @@ describe("GoogleVertexPlugin", () => {
 
   it.effect("keeps Google auth fetch for OpenAI-compatible Vertex endpoints", () =>
     Effect.gen(function* () {
+      googleAuthOptions.length = 0
       const fetchCalls: { input: Parameters<typeof fetch>[0]; init?: RequestInit }[] = []
       const plugin = yield* PluginV2.Service
       yield* plugin.add(GoogleVertexPlugin)
@@ -292,6 +296,7 @@ describe("GoogleVertexPlugin", () => {
           }),
       )
       expect(fetchCalls).toHaveLength(1)
+      expect(googleAuthOptions).toEqual([{ scopes: ["https://www.googleapis.com/auth/cloud-platform"] }])
       expect(fetchCalls[0].input).toBe("https://vertex.example")
       expect(new Headers(fetchCalls[0].init?.headers).get("authorization")).toBe("Bearer vertex-token")
       expect(new Headers(fetchCalls[0].init?.headers).get("x-test")).toBe("1")

+ 3 - 3
packages/opencode/src/provider/provider.ts

@@ -502,9 +502,9 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
           location,
           fetch: async (input: RequestInfo | URL, init?: RequestInit) => {
             const { GoogleAuth } = await import("google-auth-library")
-            const auth = new GoogleAuth()
-            const client = await auth.getApplicationDefault()
-            const token = await client.credential.getAccessToken()
+            const auth = new GoogleAuth({ scopes: ["https://www.googleapis.com/auth/cloud-platform"] })
+            const client = await auth.getClient()
+            const token = await client.getAccessToken()
 
             const headers = new Headers(init?.headers)
             headers.set("Authorization", `Bearer ${token.token}`)