diff --git a/app/api/pick-object/route.ts b/app/api/pick-object/route.ts index 03fab8d..c5e2a73 100644 --- a/app/api/pick-object/route.ts +++ b/app/api/pick-object/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from "next/server"; -import { db } from "@/lib/db"; -import { aiProvider } from "@/lib/db/schema"; +import { generateText } from "ai"; +import { getEnabledAiModelsWithProvider } from "@/lib/db/queries"; +import { getLanguageModelById } from "@/lib/ai/dynamic-provider"; export const runtime = "nodejs"; export const maxDuration = 30; @@ -13,7 +14,7 @@ const POSITION_OPTIONS = [ ] as const; interface PickObjectRequest { - imageUrl: string; // 图片 URL(不再使用 Base64) + imageUrl: string; // 图片 URL clickX: number; // 点击位置 X (0-1) clickY: number; // 点击位置 Y (0-1) } @@ -52,17 +53,28 @@ export async function POST(request: Request) { }, { status: 400 }); } - // 获取 Qwen-VL 配置 - 使用原生 SQL 查询 - const providers = await db.select().from(aiProvider); - const qwenProvider = providers.find(p => p.providerId === 'qwen'); + // 获取 Qwen VL 模型(复用现有逻辑) + const allModels = await getEnabledAiModelsWithProvider(); + const qwenModel = allModels.find( + (m) => m.provider.type === "alibaba" && m.model.supportsVision + ); - console.log('[PickObject] 找到 providers:', providers.length, '个'); - console.log('[PickObject] Qwen provider:', qwenProvider ? '已找到' : '未找到'); - - if (!qwenProvider || !qwenProvider.isEnabled || !qwenProvider.apiKey) { + if (!qwenModel) { + console.log("[PickObject] No Qwen VL model found"); return NextResponse.json({ success: false, - error: 'Qwen 服务未配置或未启用', + error: 'Qwen VL 模型未配置', + }, { status: 500 }); + } + + console.log('[PickObject] 使用模型:', qwenModel.model.modelId, qwenModel.model.displayName); + + const model = await getLanguageModelById(qwenModel.model.id); + if (!model) { + console.log("[PickObject] Failed to get language model"); + return NextResponse.json({ + success: false, + error: '无法加载模型', }, { status: 500 }); } @@ -89,56 +101,33 @@ ${POSITION_OPTIONS.join('、')} 【boundingBox】相对坐标 0-1,精确到小数点后2位 `.trim(); - const apiUrl = `${qwenProvider.apiBaseUrl || 'https://dashscope.aliyuncs.com/compatible-mode/v1'}/chat/completions`; - console.log('[PickObject] 调用 Qwen API:', apiUrl); + console.log('[PickObject] 调用 Qwen VL 模型...'); - // 调用 Qwen-VL API(使用图片 URL) - const response = await fetch(apiUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${qwenProvider.apiKey}`, - }, - body: JSON.stringify({ - model: 'qwen-vl-max', - messages: [ - { - role: 'user', - content: [ - { - type: 'image_url', - image_url: { - url: imageUrl, // 直接使用图片 URL - }, - }, - { - type: 'text', - text: prompt, - }, - ], - }, - ], - max_tokens: 200, - }), - }); + // 调用 Qwen VL 模型(复用现有的 generateText) + const { text: responseText } = await generateText({ + model, + messages: [ + { + role: 'user', + content: [ + { + type: 'image', + image: imageUrl, // 直接使用图片 URL + }, + { + type: 'text', + text: prompt, + }, + ], + }, + ], + temperature: 0.1, + maxTokens: 300, + } as any); - console.log('[PickObject] Qwen API 响应状态:', response.status); + console.log('[PickObject] Qwen 返回内容:', responseText?.substring(0, 200)); - if (!response.ok) { - const errorText = await response.text(); - console.error('[PickObject] Qwen API error:', errorText); - return NextResponse.json({ - success: false, - error: `AI 识别服务错误: ${response.status}`, - }, { status: 500 }); - } - - const data = await response.json(); - const content = data.choices?.[0]?.message?.content; - - console.log('[PickObject] Qwen 返回内容:', content?.substring(0, 200)); - - if (!content) { + if (!responseText) { return NextResponse.json({ success: false, error: 'AI 未返回结果', @@ -149,7 +138,7 @@ ${POSITION_OPTIONS.join('、')} let result: PickObjectResult; try { // 尝试从返回内容中提取 JSON - const jsonMatch = content.match(/\{[\s\S]*\}/); + const jsonMatch = responseText.match(/\{[\s\S]*\}/); if (!jsonMatch) { throw new Error('未找到 JSON'); } @@ -190,7 +179,7 @@ ${POSITION_OPTIONS.join('、')} } } catch (parseError) { - console.error('[PickObject] JSON parse error:', parseError, 'Content:', content); + console.error('[PickObject] JSON parse error:', parseError, 'Content:', responseText); // 返回默认结果 const posX = clickX < 0.33 ? '左' : clickX > 0.66 ? '右' : '中央';