Skip to content

Commit 7c0b699

Browse files
committed
fix(provider): auto-refresh AWS SSO credentials on expiry
When fromNodeProviderChain throws CredentialsProviderError (expired or uninitialized SSO session), spawn 'aws sso login [--profile <name>]', await successful exit, then retry credential resolution transparently. The AI SDK never sees an error and the session continues uninterrupted. Detects by error .name (stable SDK contract) not message string.
1 parent dba03a7 commit 7c0b699

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

packages/opencode/src/provider/provider.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os from "os"
2+
import { spawn } from "child_process"
23
import fuzzysort from "fuzzysort"
34
import { Config } from "@/config/config"
45
import { mapValues, mergeDeep, omit, pickBy, sortBy } from "remeda"
@@ -290,7 +291,23 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
290291
// Build credential provider options (only pass profile if specified)
291292
const credentialProviderOptions = profile ? { profile } : {}
292293

293-
providerOptions.credentialProvider = fromNodeProviderChain(credentialProviderOptions)
294+
const rawProvider = fromNodeProviderChain(credentialProviderOptions)
295+
providerOptions.credentialProvider = async () => {
296+
try {
297+
return await rawProvider()
298+
} catch (e) {
299+
if (e instanceof Error && e.name === "CredentialsProviderError") {
300+
await new Promise<void>((resolve, reject) => {
301+
const args = ["sso", "login", ...(profile ? ["--profile", profile] : [])]
302+
const child = spawn("aws", args, { stdio: "pipe" })
303+
child.on("exit", (code) => (code === 0 ? resolve() : reject(e)))
304+
child.on("error", () => reject(e))
305+
})
306+
return await rawProvider()
307+
}
308+
throw e
309+
}
310+
}
294311
}
295312

296313
// Add custom endpoint if specified (endpoint takes precedence over baseURL)

0 commit comments

Comments
 (0)