decolua
2026-05-16 11:20:08 +07:00
parent 74043f59ab
commit 4a575f21a2
9 changed files with 884 additions and 43 deletions
+37 -35
View File
@@ -5,6 +5,7 @@ import { KiroService } from "@/lib/oauth/services/kiro";
import { GEMINI_CONFIG } from "@/lib/oauth/constants/oauth";
import { refreshGoogleToken, updateProviderCredentials, refreshKiroToken } from "@/sse/services/tokenRefresh";
import { resolveOllamaLocalHost } from "open-sse/config/providers.js";
import { resolveKiroModels } from "open-sse/services/kiroModels.js";
const GEMINI_CLI_MODELS_URL = "https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels";
@@ -288,52 +289,53 @@ export async function GET(request, { params }) {
});
}
// Kiro: Try dynamic model fetching first
// Kiro: Use resolveKiroModels to fetch live catalog + expand variants
if (connection.provider === "kiro") {
const credentials = {
accessToken: connection.accessToken,
refreshToken: connection.refreshToken,
providerSpecificData: connection.providerSpecificData || {}
};
let warning;
try {
const kiroService = new KiroService();
const profileArn = connection.providerSpecificData?.profileArn;
const accessToken = connection.accessToken;
const refreshToken = connection.refreshToken;
if (accessToken && profileArn) {
try {
const models = await kiroService.listAvailableModels(accessToken, profileArn);
return NextResponse.json({
provider: connection.provider,
connectionId: connection.id,
models
});
} catch (error) {
if (error.message.includes("AccessDeniedException") && refreshToken) {
console.log("Kiro token invalid/expired. Attempting refresh...");
const refreshed = await refreshKiroToken(refreshToken, connection.providerSpecificData);
if (refreshed?.accessToken) {
await updateProviderCredentials(connection.id, {
accessToken: refreshed.accessToken,
refreshToken: refreshed.refreshToken || refreshToken,
expiresIn: refreshed.expiresIn,
});
const models = await kiroService.listAvailableModels(refreshed.accessToken, profileArn);
return NextResponse.json({
provider: connection.provider,
connectionId: connection.id,
models
});
}
const result = await resolveKiroModels(credentials, {
log: console,
onCredentialsRefreshed: async (refreshed) => {
if (refreshed?.accessToken) {
await updateProviderCredentials(connection.id, {
accessToken: refreshed.accessToken,
refreshToken: refreshed.refreshToken || connection.refreshToken,
expiresIn: refreshed.expiresIn,
});
connection.accessToken = refreshed.accessToken;
if (refreshed.refreshToken) connection.refreshToken = refreshed.refreshToken;
}
throw error; // Let outer catch handle it
}
});
if (result?.models?.length) {
const models = result.models.map((m) => ({
id: m.id,
name: m.name,
upstreamModelId: m.upstreamModelId,
contextLength: m.contextLength,
rateMultiplier: m.rateMultiplier,
capabilities: m.capabilities,
description: m.description
}));
return NextResponse.json({
provider: connection.provider,
connectionId: connection.id,
models
});
}
warning = "Kiro returned no models; falling back to static catalog.";
} catch (error) {
warning = `Failed to fetch Kiro models: ${error.message}`;
console.log("Failed to fetch Kiro models dynamically, falling back to static:", error.message);
}
// Return empty dynamic list so UI falls back to static provider models.
// Empty dynamic list UI falls back to static provider models.
return NextResponse.json({
provider: connection.provider,
connectionId: connection.id,
+1
View File
@@ -7,6 +7,7 @@ import {
} from "@/shared/constants/providers";
import { getProviderConnections, getCombos, getCustomModels, getModelAliases } from "@/lib/localDb";
import { getDisabledModels } from "@/lib/disabledModelsDb";
import { resolveKiroModels } from "open-sse/services/kiroModels.js";
const parseOpenAIStyleModels = (data) => {
if (Array.isArray(data)) return data;