MCPcopy
hub / github.com/anomalyco/opencode / fetch

Function fetch

packages/opencode/src/plugin/xai.ts:477–547  ·  view source on GitHub ↗
(requestInput: RequestInfo | URL, init?: RequestInit)

Source from the content-addressed store, hash-verified

475 // around a user-configured gateway.
476 apiKey: OAUTH_DUMMY_KEY,
477 async fetch(requestInput: RequestInfo | URL, init?: RequestInit) {
478 let currentAuth = await getAuth()
479 // Auth can flip from oauth to api mid-session (user re-runs
480 // /connect with a pasted key). When that happens, pass the
481 // request through untouched so the AI SDK's own apiKey-based
482 // Authorization header reaches xAI unmodified.
483 if (currentAuth.type !== "oauth") return fetch(requestInput, init)
484
485 // Refresh either when the stored expires timestamp is within the
486 // skew window, or — for JWT access tokens — when the JWT exp
487 // claim itself is. The stored expires field is best-effort
488 // (xAI doesn't always return expires_in) so the JWT check is the
489 // load-bearing one for tokens that lack a fresh stored deadline.
490 const expiresSoon =
491 !currentAuth.expires ||
492 currentAuth.expires - Date.now() <= ACCESS_TOKEN_REFRESH_SKEW_MS ||
493 accessTokenIsExpiring(currentAuth.access)
494 if (expiresSoon) {
495 if (!refreshPromise) {
496 const refreshToken = currentAuth.refresh
497 refreshPromise = refreshAccessToken(refreshToken, options)
498 .then(async (tokens) => {
499 const refreshedExpires = Date.now() + (tokens.expires_in ?? 3600) * 1000
500 const refreshedRefresh = tokens.refresh_token || refreshToken
501 // Persist the rotated pair as best-effort. xAI has already consumed the
502 // old refresh_token by the time we get here; an auth.set failure leaves
503 // the on-disk state stale but the in-memory result is still valid for
504 // this turn. The next live refresh against the stale disk state will
505 // 4xx and force re-login — a known cross-process limitation.
506 await input.client.auth
507 .set({
508 path: { id: "xai" },
509 body: {
510 type: "oauth",
511 access: tokens.access_token,
512 refresh: refreshedRefresh,
513 expires: refreshedExpires,
514 },
515 })
516 .catch(() => {})
517 return { access: tokens.access_token, refresh: refreshedRefresh, expires: refreshedExpires }
518 })
519 .finally(() => {
520 refreshPromise = undefined
521 })
522 }
523 const refreshed = await refreshPromise
524 currentAuth = { ...currentAuth, ...refreshed }
525 }
526
527 // Copy the caller's headers into a fresh Headers (case-insensitive)
528 // so we never mutate the RequestInit the AI SDK may reuse on retry.
529 // Headers.set overwrites case-insensitively, which kills the dummy
530 // bearer the AI SDK injected from apiKey in a single line.
531 const headers = new Headers(requestInput instanceof Request ? requestInput.headers : undefined)
532 if (init?.headers) {
533 const entries =
534 init.headers instanceof Headers

Callers 15

exchangeCodeForTokensFunction · 0.70
refreshAccessTokenFunction · 0.70
requestDeviceCodeFunction · 0.70
pollDeviceCodeTokenFunction · 0.70
listRoutersFunction · 0.70
api.tsFile · 0.50
createPlatformFunction · 0.50
checkHealthFunction · 0.50
signFunction · 0.50
index.tsFile · 0.50

Calls 3

accessTokenIsExpiringFunction · 0.85
refreshAccessTokenFunction · 0.70
setMethod · 0.45

Tested by

no test coverage detected