Spaces:
Build error
Build error
Upload folder using huggingface_hub
Browse files
app/api/analyze-edit-intent/route.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
import { NextRequest, NextResponse } from 'next/server';
|
| 2 |
-
import { createGroq } from '@ai-sdk/groq';
|
| 3 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 4 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 5 |
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
@@ -11,11 +10,6 @@ import { z } from 'zod';
|
|
| 11 |
const isUsingAIGateway = !!process.env.AI_GATEWAY_API_KEY;
|
| 12 |
const aiGatewayBaseURL = 'https://ai-gateway.vercel.sh/v1';
|
| 13 |
|
| 14 |
-
const groq = createGroq({
|
| 15 |
-
apiKey: process.env.AI_GATEWAY_API_KEY ?? process.env.GROQ_API_KEY,
|
| 16 |
-
baseURL: isUsingAIGateway ? aiGatewayBaseURL : undefined,
|
| 17 |
-
});
|
| 18 |
-
|
| 19 |
const anthropic = createAnthropic({
|
| 20 |
apiKey: process.env.AI_GATEWAY_API_KEY ?? process.env.ANTHROPIC_API_KEY,
|
| 21 |
baseURL: isUsingAIGateway ? aiGatewayBaseURL : (process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1'),
|
|
@@ -108,16 +102,12 @@ export async function POST(request: NextRequest) {
|
|
| 108 |
if (model.startsWith('anthropic/')) {
|
| 109 |
aiModel = anthropic(model.replace('anthropic/', ''));
|
| 110 |
} else if (model.startsWith('openai/')) {
|
| 111 |
-
|
| 112 |
-
aiModel = groq(model);
|
| 113 |
-
} else {
|
| 114 |
-
aiModel = openai(model.replace('openai/', ''));
|
| 115 |
-
}
|
| 116 |
} else if (model.startsWith('google/')) {
|
| 117 |
aiModel = googleGenerativeAI(model.replace('google/', ''));
|
| 118 |
} else {
|
| 119 |
-
// Default to
|
| 120 |
-
aiModel =
|
| 121 |
}
|
| 122 |
|
| 123 |
console.log('[analyze-edit-intent] Using AI model:', model);
|
|
|
|
| 1 |
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
| 2 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 3 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 4 |
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
|
|
| 10 |
const isUsingAIGateway = !!process.env.AI_GATEWAY_API_KEY;
|
| 11 |
const aiGatewayBaseURL = 'https://ai-gateway.vercel.sh/v1';
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
const anthropic = createAnthropic({
|
| 14 |
apiKey: process.env.AI_GATEWAY_API_KEY ?? process.env.ANTHROPIC_API_KEY,
|
| 15 |
baseURL: isUsingAIGateway ? aiGatewayBaseURL : (process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1'),
|
|
|
|
| 102 |
if (model.startsWith('anthropic/')) {
|
| 103 |
aiModel = anthropic(model.replace('anthropic/', ''));
|
| 104 |
} else if (model.startsWith('openai/')) {
|
| 105 |
+
aiModel = openai(model.replace('openai/', ''));
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
} else if (model.startsWith('google/')) {
|
| 107 |
aiModel = googleGenerativeAI(model.replace('google/', ''));
|
| 108 |
} else {
|
| 109 |
+
// Default to openai if model format is unclear
|
| 110 |
+
aiModel = openai(model);
|
| 111 |
}
|
| 112 |
|
| 113 |
console.log('[analyze-edit-intent] Using AI model:', model);
|
app/api/generate-ai-code-stream/route.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
import { NextRequest, NextResponse } from 'next/server';
|
| 2 |
-
import { createGroq } from '@ai-sdk/groq';
|
| 3 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 4 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 5 |
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
@@ -20,15 +19,9 @@ const aiGatewayBaseURL = 'https://ai-gateway.vercel.sh/v1';
|
|
| 20 |
|
| 21 |
console.log('[generate-ai-code-stream] AI Gateway config:', {
|
| 22 |
isUsingAIGateway,
|
| 23 |
-
hasGroqKey: !!process.env.GROQ_API_KEY,
|
| 24 |
hasAIGatewayKey: !!process.env.AI_GATEWAY_API_KEY
|
| 25 |
});
|
| 26 |
|
| 27 |
-
const groq = createGroq({
|
| 28 |
-
apiKey: process.env.AI_GATEWAY_API_KEY ?? process.env.GROQ_API_KEY,
|
| 29 |
-
baseURL: isUsingAIGateway ? aiGatewayBaseURL : undefined,
|
| 30 |
-
});
|
| 31 |
-
|
| 32 |
const anthropic = createAnthropic({
|
| 33 |
apiKey: process.env.AI_GATEWAY_API_KEY ?? process.env.ANTHROPIC_API_KEY,
|
| 34 |
baseURL: isUsingAIGateway ? aiGatewayBaseURL : (process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1'),
|
|
@@ -1216,11 +1209,10 @@ MORPH FAST APPLY MODE (EDIT-ONLY):
|
|
| 1216 |
const isAnthropic = model.startsWith('anthropic/');
|
| 1217 |
const isGoogle = model.startsWith('google/');
|
| 1218 |
const isOpenAI = model.startsWith('openai/');
|
| 1219 |
-
const isKimiGroq = model === 'moonshotai/kimi-k2-instruct-0905';
|
| 1220 |
const modelProvider = isAnthropic ? anthropic :
|
| 1221 |
(isOpenAI ? openai :
|
| 1222 |
(isGoogle ? googleGenerativeAI :
|
| 1223 |
-
(
|
| 1224 |
|
| 1225 |
// Fix model name transformation for different providers
|
| 1226 |
let actualModel: string;
|
|
@@ -1228,9 +1220,6 @@ MORPH FAST APPLY MODE (EDIT-ONLY):
|
|
| 1228 |
actualModel = model.replace('anthropic/', '');
|
| 1229 |
} else if (isOpenAI) {
|
| 1230 |
actualModel = model.replace('openai/', '');
|
| 1231 |
-
} else if (isKimiGroq) {
|
| 1232 |
-
// Kimi on Groq - use full model string
|
| 1233 |
-
actualModel = 'moonshotai/kimi-k2-instruct-0905';
|
| 1234 |
} else if (isGoogle) {
|
| 1235 |
// Google uses specific model names - convert our naming to theirs
|
| 1236 |
actualModel = model.replace('google/', '');
|
|
@@ -1238,7 +1227,7 @@ MORPH FAST APPLY MODE (EDIT-ONLY):
|
|
| 1238 |
actualModel = model;
|
| 1239 |
}
|
| 1240 |
|
| 1241 |
-
console.log(`[generate-ai-code-stream] Using provider: ${isAnthropic ? 'Anthropic' : isGoogle ? 'Google' : isOpenAI ? 'OpenAI' : '
|
| 1242 |
console.log(`[generate-ai-code-stream] AI Gateway enabled: ${isUsingAIGateway}`);
|
| 1243 |
console.log(`[generate-ai-code-stream] Model string: ${model}`);
|
| 1244 |
|
|
@@ -1336,8 +1325,6 @@ It's better to have 3 complete files than 10 incomplete files.`
|
|
| 1336 |
} catch (streamError: any) {
|
| 1337 |
console.error(`[generate-ai-code-stream] Error calling streamText (attempt ${retryCount + 1}/${maxRetries + 1}):`, streamError);
|
| 1338 |
|
| 1339 |
-
// Check if this is a Groq service unavailable error
|
| 1340 |
-
const isGroqServiceError = isKimiGroq && streamError.message?.includes('Service unavailable');
|
| 1341 |
const isRetryableError = streamError.message?.includes('Service unavailable') ||
|
| 1342 |
streamError.message?.includes('rate limit') ||
|
| 1343 |
streamError.message?.includes('timeout');
|
|
@@ -1355,17 +1342,11 @@ It's better to have 3 complete files than 10 incomplete files.`
|
|
| 1355 |
// Wait before retry with exponential backoff
|
| 1356 |
await new Promise(resolve => setTimeout(resolve, retryCount * 2000));
|
| 1357 |
|
| 1358 |
-
// If Groq fails, try switching to a fallback model
|
| 1359 |
-
if (isGroqServiceError && retryCount === maxRetries) {
|
| 1360 |
-
console.log('[generate-ai-code-stream] Groq service unavailable, falling back to GPT-4');
|
| 1361 |
-
streamOptions.model = openai('gpt-4-turbo');
|
| 1362 |
-
actualModel = 'gpt-4-turbo';
|
| 1363 |
-
}
|
| 1364 |
} else {
|
| 1365 |
// Final error, send to user
|
| 1366 |
await sendProgress({
|
| 1367 |
type: 'error',
|
| 1368 |
-
message: `Failed to initialize ${isGoogle ? 'Gemini' : isAnthropic ? 'Claude' : isOpenAI ? 'GPT-5' :
|
| 1369 |
});
|
| 1370 |
|
| 1371 |
// If this is a Google model error, provide helpful info
|
|
@@ -1731,17 +1712,13 @@ Provide the complete file content without any truncation. Include all necessary
|
|
| 1731 |
completionClient = openai;
|
| 1732 |
} else if (model.includes('claude')) {
|
| 1733 |
completionClient = anthropic;
|
| 1734 |
-
} else if (model === 'moonshotai/kimi-k2-instruct-0905') {
|
| 1735 |
-
completionClient = groq;
|
| 1736 |
} else {
|
| 1737 |
-
completionClient =
|
| 1738 |
}
|
| 1739 |
|
| 1740 |
// Determine the correct model name for the completion
|
| 1741 |
let completionModelName: string;
|
| 1742 |
-
if (model
|
| 1743 |
-
completionModelName = 'moonshotai/kimi-k2-instruct-0905';
|
| 1744 |
-
} else if (model.includes('openai')) {
|
| 1745 |
completionModelName = model.replace('openai/', '');
|
| 1746 |
} else if (model.includes('anthropic')) {
|
| 1747 |
completionModelName = model.replace('anthropic/', '');
|
|
|
|
| 1 |
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
| 2 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 3 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 4 |
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
|
|
| 19 |
|
| 20 |
console.log('[generate-ai-code-stream] AI Gateway config:', {
|
| 21 |
isUsingAIGateway,
|
|
|
|
| 22 |
hasAIGatewayKey: !!process.env.AI_GATEWAY_API_KEY
|
| 23 |
});
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
const anthropic = createAnthropic({
|
| 26 |
apiKey: process.env.AI_GATEWAY_API_KEY ?? process.env.ANTHROPIC_API_KEY,
|
| 27 |
baseURL: isUsingAIGateway ? aiGatewayBaseURL : (process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1'),
|
|
|
|
| 1209 |
const isAnthropic = model.startsWith('anthropic/');
|
| 1210 |
const isGoogle = model.startsWith('google/');
|
| 1211 |
const isOpenAI = model.startsWith('openai/');
|
|
|
|
| 1212 |
const modelProvider = isAnthropic ? anthropic :
|
| 1213 |
(isOpenAI ? openai :
|
| 1214 |
(isGoogle ? googleGenerativeAI :
|
| 1215 |
+
(openai)));
|
| 1216 |
|
| 1217 |
// Fix model name transformation for different providers
|
| 1218 |
let actualModel: string;
|
|
|
|
| 1220 |
actualModel = model.replace('anthropic/', '');
|
| 1221 |
} else if (isOpenAI) {
|
| 1222 |
actualModel = model.replace('openai/', '');
|
|
|
|
|
|
|
|
|
|
| 1223 |
} else if (isGoogle) {
|
| 1224 |
// Google uses specific model names - convert our naming to theirs
|
| 1225 |
actualModel = model.replace('google/', '');
|
|
|
|
| 1227 |
actualModel = model;
|
| 1228 |
}
|
| 1229 |
|
| 1230 |
+
console.log(`[generate-ai-code-stream] Using provider: ${isAnthropic ? 'Anthropic' : isGoogle ? 'Google' : isOpenAI ? 'OpenAI' : 'OpenAI'}, model: ${actualModel}`);
|
| 1231 |
console.log(`[generate-ai-code-stream] AI Gateway enabled: ${isUsingAIGateway}`);
|
| 1232 |
console.log(`[generate-ai-code-stream] Model string: ${model}`);
|
| 1233 |
|
|
|
|
| 1325 |
} catch (streamError: any) {
|
| 1326 |
console.error(`[generate-ai-code-stream] Error calling streamText (attempt ${retryCount + 1}/${maxRetries + 1}):`, streamError);
|
| 1327 |
|
|
|
|
|
|
|
| 1328 |
const isRetryableError = streamError.message?.includes('Service unavailable') ||
|
| 1329 |
streamError.message?.includes('rate limit') ||
|
| 1330 |
streamError.message?.includes('timeout');
|
|
|
|
| 1342 |
// Wait before retry with exponential backoff
|
| 1343 |
await new Promise(resolve => setTimeout(resolve, retryCount * 2000));
|
| 1344 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1345 |
} else {
|
| 1346 |
// Final error, send to user
|
| 1347 |
await sendProgress({
|
| 1348 |
type: 'error',
|
| 1349 |
+
message: `Failed to initialize ${isGoogle ? 'Gemini' : isAnthropic ? 'Claude' : isOpenAI ? 'GPT-5' : 'AI'} streaming: ${streamError.message}`
|
| 1350 |
});
|
| 1351 |
|
| 1352 |
// If this is a Google model error, provide helpful info
|
|
|
|
| 1712 |
completionClient = openai;
|
| 1713 |
} else if (model.includes('claude')) {
|
| 1714 |
completionClient = anthropic;
|
|
|
|
|
|
|
| 1715 |
} else {
|
| 1716 |
+
completionClient = openai;
|
| 1717 |
}
|
| 1718 |
|
| 1719 |
// Determine the correct model name for the completion
|
| 1720 |
let completionModelName: string;
|
| 1721 |
+
if (model.includes('openai')) {
|
|
|
|
|
|
|
| 1722 |
completionModelName = model.replace('openai/', '');
|
| 1723 |
} else if (model.includes('anthropic')) {
|
| 1724 |
completionModelName = model.replace('anthropic/', '');
|
lib/ai/blablador-provider.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
| 1 |
-
import { createOpenAI } from '@ai-sdk/openai';
|
| 2 |
-
|
| 3 |
-
export const blabladorProvider = createOpenAI({
|
| 4 |
-
apiKey: process.env.BLABLADOR_API_KEY || '',
|
| 5 |
-
baseURL: 'https://api.openai.com/v1', // Trick the SDK
|
| 6 |
-
fetch: async (url, options) => {
|
| 7 |
-
const newUrl = url.toString().replace('https://api.openai.com/v1', 'https://api.helmholtz-blablador.fz-juelich.de/v1');
|
| 8 |
-
return fetch(newUrl, options);
|
| 9 |
-
},
|
| 10 |
-
});
|
| 11 |
-
|
| 12 |
-
export type BlabladorClient = typeof blabladorProvider;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/ai/provider-manager.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
| 1 |
import { appConfig } from '@/config/app.config';
|
| 2 |
-
import { createGroq } from '@ai-sdk/groq';
|
| 3 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 4 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 5 |
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
| 6 |
|
| 7 |
-
type ProviderName = 'openai' | 'anthropic' | '
|
| 8 |
|
| 9 |
// Client function type returned by @ai-sdk providers
|
| 10 |
export type ProviderClient =
|
| 11 |
| ReturnType<typeof createOpenAI>
|
| 12 |
| ReturnType<typeof createAnthropic>
|
| 13 |
-
| ReturnType<typeof createGroq>
|
| 14 |
| ReturnType<typeof createGoogleGenerativeAI>;
|
| 15 |
|
| 16 |
export interface ProviderResolution {
|
|
@@ -36,8 +34,6 @@ function getEnvDefaults(provider: ProviderName): { apiKey?: string; baseURL?: st
|
|
| 36 |
case 'anthropic':
|
| 37 |
// Default Anthropic base URL mirrors existing routes
|
| 38 |
return { apiKey: process.env.ANTHROPIC_API_KEY, baseURL: process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1' };
|
| 39 |
-
case 'groq':
|
| 40 |
-
return { apiKey: process.env.GROQ_API_KEY, baseURL: process.env.GROQ_BASE_URL };
|
| 41 |
case 'google':
|
| 42 |
return { apiKey: process.env.GEMINI_API_KEY, baseURL: process.env.GEMINI_BASE_URL };
|
| 43 |
case 'helmholtz':
|
|
@@ -64,9 +60,6 @@ function getOrCreateClient(provider: ProviderName, apiKey?: string, baseURL?: st
|
|
| 64 |
case 'anthropic':
|
| 65 |
client = createAnthropic({ apiKey: effective.apiKey || getEnvDefaults('anthropic').apiKey, baseURL: effective.baseURL ?? getEnvDefaults('anthropic').baseURL });
|
| 66 |
break;
|
| 67 |
-
case 'groq':
|
| 68 |
-
client = createGroq({ apiKey: effective.apiKey || getEnvDefaults('groq').apiKey, baseURL: effective.baseURL ?? getEnvDefaults('groq').baseURL });
|
| 69 |
-
break;
|
| 70 |
case 'google':
|
| 71 |
client = createGoogleGenerativeAI({ apiKey: effective.apiKey || getEnvDefaults('google').apiKey, baseURL: effective.baseURL ?? getEnvDefaults('google').baseURL });
|
| 72 |
break;
|
|
@@ -91,12 +84,6 @@ export function getProviderForModel(modelId: string): ProviderResolution {
|
|
| 91 |
const isAnthropic = modelId.startsWith('anthropic/');
|
| 92 |
const isOpenAI = modelId.startsWith('openai/');
|
| 93 |
const isGoogle = modelId.startsWith('google/');
|
| 94 |
-
const isKimiGroq = modelId === 'moonshotai/kimi-k2-instruct-0905';
|
| 95 |
-
|
| 96 |
-
if (isKimiGroq) {
|
| 97 |
-
const client = getOrCreateClient('groq');
|
| 98 |
-
return { client, actualModel: 'moonshotai/kimi-k2-instruct-0905' };
|
| 99 |
-
}
|
| 100 |
|
| 101 |
if (isAnthropic) {
|
| 102 |
const client = getOrCreateClient('anthropic');
|
|
|
|
| 1 |
import { appConfig } from '@/config/app.config';
|
|
|
|
| 2 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 3 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 4 |
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
| 5 |
|
| 6 |
+
type ProviderName = 'openai' | 'anthropic' | 'google' | 'helmholtz';
|
| 7 |
|
| 8 |
// Client function type returned by @ai-sdk providers
|
| 9 |
export type ProviderClient =
|
| 10 |
| ReturnType<typeof createOpenAI>
|
| 11 |
| ReturnType<typeof createAnthropic>
|
|
|
|
| 12 |
| ReturnType<typeof createGoogleGenerativeAI>;
|
| 13 |
|
| 14 |
export interface ProviderResolution {
|
|
|
|
| 34 |
case 'anthropic':
|
| 35 |
// Default Anthropic base URL mirrors existing routes
|
| 36 |
return { apiKey: process.env.ANTHROPIC_API_KEY, baseURL: process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1' };
|
|
|
|
|
|
|
| 37 |
case 'google':
|
| 38 |
return { apiKey: process.env.GEMINI_API_KEY, baseURL: process.env.GEMINI_BASE_URL };
|
| 39 |
case 'helmholtz':
|
|
|
|
| 60 |
case 'anthropic':
|
| 61 |
client = createAnthropic({ apiKey: effective.apiKey || getEnvDefaults('anthropic').apiKey, baseURL: effective.baseURL ?? getEnvDefaults('anthropic').baseURL });
|
| 62 |
break;
|
|
|
|
|
|
|
|
|
|
| 63 |
case 'google':
|
| 64 |
client = createGoogleGenerativeAI({ apiKey: effective.apiKey || getEnvDefaults('google').apiKey, baseURL: effective.baseURL ?? getEnvDefaults('google').baseURL });
|
| 65 |
break;
|
|
|
|
| 84 |
const isAnthropic = modelId.startsWith('anthropic/');
|
| 85 |
const isOpenAI = modelId.startsWith('openai/');
|
| 86 |
const isGoogle = modelId.startsWith('google/');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
|
| 88 |
if (isAnthropic) {
|
| 89 |
const client = getOrCreateClient('anthropic');
|