fix: 复用现有 Qwen VL 模型调用方式
This commit is contained in:
parent
3558eed251
commit
f7debfb55f
@ -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 ? '右' : '中央';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user