kv-app/lib/api/api34ai.ts

206 lines
No EOL
4.8 KiB
TypeScript

export interface ImageGenerationRequest {
prompt: string;
model?: string;
resolution?: string;
ratio?: string;
quality?: string;
}
export interface VideoGenerationRequest {
prompt: string;
model?: string;
duration?: number;
resolution?: string;
ratio?: string;
quality?: string;
}
export interface TaskStatus {
task_id: string;
status: string;
tasks?: Array<{
task_id: string;
status: string;
result?: {
url?: string;
};
}>;
}
export interface ModelInfo {
model: string;
name: string;
type: string;
resolution_options: string[];
duration_options: number[];
ratios_options: string[];
quality_options: string[];
}
const BASE_URL = 'https://api.34ai.net/api/v1';
export async function generateImage(
apiKey: string,
request: ImageGenerationRequest
): Promise<{ task_id: string }> {
const response = await fetch(`${BASE_URL}/generate-image`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
},
body: JSON.stringify({
prompt: request.prompt,
model: request.model || 'banana_pro_2',
resolution: request.resolution || '1K',
ratio: request.ratio || '1:1',
quality: request.quality,
}),
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.message || `Image generation failed: ${response.status}`);
}
const data = await response.json();
if (!data.success) {
throw new Error(data.message || 'Image generation failed');
}
return { task_id: data.data.tasks[0].task_id };
}
export async function generateVideo(
apiKey: string,
request: VideoGenerationRequest
): Promise<{ task_id: string }> {
const response = await fetch(`${BASE_URL}/generate-video`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
},
body: JSON.stringify({
prompt: request.prompt,
model: request.model || 'veo3.1',
duration: request.duration || 4,
resolution: request.resolution || '720p',
ratio: request.ratio || '16:9',
quality: request.quality || 'fast',
}),
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.message || `Video generation failed: ${response.status}`);
}
const data = await response.json();
if (!data.success) {
throw new Error(data.message || 'Video generation failed');
}
return { task_id: data.data.tasks[0].task_id };
}
export async function checkTask(
apiKey: string,
taskId: string
): Promise<TaskStatus> {
const response = await fetch(`${BASE_URL}/check-task`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
},
body: JSON.stringify({ task_id: taskId }),
});
if (!response.ok) {
throw new Error(`Check task failed: ${response.status}`);
}
const data = await response.json();
if (!data.success) {
throw new Error(data.message || 'Check task failed');
}
const taskData = data.data;
const innerTask = taskData.tasks?.[0];
return {
task_id: taskId,
status: taskData.status,
tasks: taskData.tasks,
};
}
export async function getModels(apiKey: string): Promise<ModelInfo[]> {
const response = await fetch(`${BASE_URL}/models`, {
method: 'GET',
headers: {
'x-api-key': apiKey,
},
});
if (!response.ok) {
throw new Error(`Get models failed: ${response.status}`);
}
const data = await response.json();
if (!data.success) {
throw new Error(data.message || 'Get models failed');
}
return data.data.models.map((m: any) => ({
model: m.model,
name: m.name,
type: m.type,
resolution_options: m.resolution_options || [],
duration_options: m.duration_options || [],
ratios_options: m.ratios_options || [],
quality_options: m.quality_options || [],
}));
}
export async function testConnection(apiKey: string): Promise<boolean> {
try {
const response = await fetch(`${BASE_URL}/models`, {
method: 'GET',
headers: {
'x-api-key': apiKey,
},
});
return response.ok;
} catch {
return false;
}
}
export async function waitForTaskCompletion(
apiKey: string,
taskId: string,
maxAttempts: number = 60,
intervalMs: number = 3000
): Promise<string> {
for (let i = 0; i < maxAttempts; i++) {
const status = await checkTask(apiKey, taskId);
if (status.status === 'completed') {
const result = status.tasks?.[0]?.result;
if (result?.url) {
return result.url;
}
throw new Error('Task completed but no URL in result');
}
if (status.status === 'failed') {
throw new Error('Task failed');
}
await new Promise(resolve => setTimeout(resolve, intervalMs));
}
throw new Error('Task timeout');
}