import { BaseExecutor } from "./base.js"; import { PROVIDERS, OAUTH_ENDPOINTS } from "../config/constants.js"; export class DefaultExecutor extends BaseExecutor { constructor(provider) { super(provider, PROVIDERS[provider] || PROVIDERS.openai); } buildUrl(model, stream, urlIndex = 0) { switch (this.provider) { case "claude": case "glm": case "kimi": case "minimax": return `${this.config.baseUrl}?beta=true`; case "gemini": return `${this.config.baseUrl}/${model}:${stream ? "streamGenerateContent?alt=sse" : "generateContent"}`; default: return this.config.baseUrl; } } buildHeaders(credentials, stream = true) { const headers = { "Content-Type": "application/json", ...this.config.headers }; switch (this.provider) { case "gemini": credentials.apiKey ? headers["x-goog-api-key"] = credentials.apiKey : headers["Authorization"] = `Bearer ${credentials.accessToken}`; break; case "claude": credentials.apiKey ? headers["x-api-key"] = credentials.apiKey : headers["Authorization"] = `Bearer ${credentials.accessToken}`; break; case "glm": case "kimi": case "minimax": headers["x-api-key"] = credentials.apiKey; break; default: headers["Authorization"] = `Bearer ${credentials.apiKey || credentials.accessToken}`; } if (stream) headers["Accept"] = "text/event-stream"; return headers; } async refreshCredentials(credentials, log) { if (!credentials.refreshToken) return null; const refreshers = { claude: () => this.refreshWithJSON(OAUTH_ENDPOINTS.anthropic.token, { grant_type: "refresh_token", refresh_token: credentials.refreshToken, client_id: PROVIDERS.claude.clientId }), codex: () => this.refreshWithForm(OAUTH_ENDPOINTS.openai.token, { grant_type: "refresh_token", refresh_token: credentials.refreshToken, client_id: PROVIDERS.codex.clientId, scope: "openid profile email offline_access" }), qwen: () => this.refreshWithForm(OAUTH_ENDPOINTS.qwen.token, { grant_type: "refresh_token", refresh_token: credentials.refreshToken, client_id: PROVIDERS.qwen.clientId }), iflow: () => this.refreshIflow(credentials.refreshToken), gemini: () => this.refreshGoogle(credentials.refreshToken), kiro: () => this.refreshKiro(credentials.refreshToken) }; const refresher = refreshers[this.provider]; if (!refresher) return null; try { const result = await refresher(); if (result) log?.info?.("TOKEN", `${this.provider} refreshed`); return result; } catch (error) { log?.error?.("TOKEN", `${this.provider} refresh error: ${error.message}`); return null; } } async refreshWithJSON(url, body) { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify(body) }); if (!response.ok) return null; const tokens = await response.json(); return { accessToken: tokens.access_token, refreshToken: tokens.refresh_token || body.refresh_token, expiresIn: tokens.expires_in }; } async refreshWithForm(url, params) { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json" }, body: new URLSearchParams(params) }); if (!response.ok) return null; const tokens = await response.json(); return { accessToken: tokens.access_token, refreshToken: tokens.refresh_token || params.refresh_token, expiresIn: tokens.expires_in }; } async refreshIflow(refreshToken) { const basicAuth = btoa(`${PROVIDERS.iflow.clientId}:${PROVIDERS.iflow.clientSecret}`); const response = await fetch(OAUTH_ENDPOINTS.iflow.token, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", "Authorization": `Basic ${basicAuth}` }, body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id: PROVIDERS.iflow.clientId, client_secret: PROVIDERS.iflow.clientSecret }) }); if (!response.ok) return null; const tokens = await response.json(); return { accessToken: tokens.access_token, refreshToken: tokens.refresh_token || refreshToken, expiresIn: tokens.expires_in }; } async refreshGoogle(refreshToken) { const response = await fetch(OAUTH_ENDPOINTS.google.token, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json" }, body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id: this.config.clientId, client_secret: this.config.clientSecret }) }); if (!response.ok) return null; const tokens = await response.json(); return { accessToken: tokens.access_token, refreshToken: tokens.refresh_token || refreshToken, expiresIn: tokens.expires_in }; } async refreshKiro(refreshToken) { const response = await fetch(PROVIDERS.kiro.tokenUrl, { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json", "User-Agent": "kiro-cli/1.0.0" }, body: JSON.stringify({ refreshToken }) }); if (!response.ok) return null; const tokens = await response.json(); return { accessToken: tokens.accessToken, refreshToken: tokens.refreshToken || refreshToken, expiresIn: tokens.expiresIn }; } } export default DefaultExecutor;