改为 grok 了

This commit is contained in:
2026-02-05 17:46:08 +08:00
parent b69b7782e5
commit d6e43d5324
6 changed files with 145 additions and 98 deletions

127
script.js
View File

@@ -1,4 +1,4 @@
// OpenRouter Image Generator - 主要JavaScript逻辑
// Grok Image Generator - 主要JavaScript逻辑
// 全局变量
let uploadedImages = [];
@@ -6,10 +6,12 @@ let chatHistory = [];
let generatedImages = [];
let currentSettings = {
apiKey: '',
baseUrl: 'https://openrouter.ai/api/v1',
model: 'google/gemini-2.5-flash-image-preview:free',
baseUrl: '',
model: 'grok-imagine-1.0',
timeout: 600,
proxy: ''
proxy: '',
responseFormat: 'b64_json',
n: 1
};
let currentImageIndex = 0; // 当前查看的图像索引
let currentModalInstance = null; // 当前模态框实例
@@ -22,12 +24,12 @@ const CONFIG = {
MAX_CHAT_HISTORY: 50, // 减少聊天历史记录数量以节省存储空间
MAX_GENERATED_IMAGES: 600, // 减少存储的图像数量以防止存储空间溢出
STORAGE_KEYS: {
SETTINGS: 'openRouterSettings',
CHAT_HISTORY: 'openRouterChatHistory',
GENERATED_IMAGES: 'openRouterGeneratedImages'
SETTINGS: 'grokImageSettings',
CHAT_HISTORY: 'grokImageChatHistory',
GENERATED_IMAGES: 'grokGeneratedImages'
},
INDEXED_DB: {
NAME: 'OpenRouterImageDB',
NAME: 'GrokImageDB',
VERSION: 1,
STORES: {
SETTINGS: 'settings',
@@ -39,13 +41,15 @@ const CONFIG = {
// 错误消息
const ERROR_MESSAGES = {
NO_API_KEY: '请先输入API Key',
CONNECTION_FAILED: '连接失败请检查网络和API设置',
INVALID_RESPONSE: 'API响应格式错误',
NO_API_KEY: '请先输入 API Key',
NO_BASE_URL: '请先配置 API 地址',
CONNECTION_FAILED: '连接失败,请检查网络和 API 设置',
INVALID_RESPONSE: 'API 响应格式错误',
IMAGE_GENERATION_FAILED: '图像生成失败',
FILE_TOO_LARGE: '文件大小超过限制',
UNSUPPORTED_FORMAT: '不支持的文件格式',
UPLOAD_FAILED: '文件上传失败'
UPLOAD_FAILED: '文件上传失败',
IMAGE_EDIT_NOT_SUPPORTED: '当前 API 不支持图像编辑,仅支持文本生成图像'
};
// 工具函数
@@ -698,35 +702,24 @@ const apiService = {
// 生成图像
generateImage: async function(message, images, settings) {
const messages = [
{
role: 'user',
content: [
{ type: 'text', text: message }
]
}
];
// 添加上传的图像
images.forEach(img => {
messages[0].content.push({
type: 'image_url',
image_url: { url: img.data }
});
});
// 检查是否有上传的图像,如果有则提示不支持
if (images && images.length > 0) {
console.warn('当前 API 不支持图像编辑,将忽略上传的图像');
}
// 构建请求 payload符合 OpenAI 图像生成 API 格式)
const payload = {
model: settings.model,
messages: messages,
stream: false,
"modalities": ["image","text"]
prompt: message,
n: settings.n || 1,
response_format: settings.responseFormat || 'b64_json'
};
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), settings.timeout * 1000);
try {
const response = await fetch(`${settings.baseUrl}/chat/completions`, {
const response = await fetch(`${settings.baseUrl}/v1/images/generations`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${settings.apiKey}`,
@@ -739,31 +732,50 @@ const apiService = {
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error?.message || `HTTP error! status: ${response.status}`);
}
const data = await response.json();
// 解析响应
const choice = data.choices[0];
const messageContent = choice.message.content;
// 解析响应OpenAI 图像生成 API 格式)
const images = [];
// 提取图像数据并转换为Blob URL但保留原始base64数据
if (choice.message.images) {
choice.message.images.forEach(img => {
// 确保原始数据是base64格式
const originalBase64 = img.image_url.url;
const blobUrl = utils.base64ToBlobUrl(originalBase64);
images.push(blobUrl);
let hasError = false;
if (data.data && Array.isArray(data.data)) {
data.data.forEach(item => {
if (item.b64_json) {
// 检测 API 返回的错误标记
if (item.b64_json === 'error' || item.b64_json === 'Error') {
hasError = true;
return;
}
// base64 格式响应
const base64Data = `data:image/png;base64,${item.b64_json}`;
const blobUrl = utils.base64ToBlobUrl(base64Data);
images.push(blobUrl);
} else if (item.url) {
// 检测 URL 格式的错误标记
if (item.url === 'error' || item.url === 'Error') {
hasError = true;
return;
}
// URL 格式响应
images.push(item.url);
}
});
}
// 如果检测到错误标记,抛出错误以触发重试
if (hasError) {
throw new Error('API 返回错误标记,需要重试');
}
return {
success: true,
content: messageContent,
content: `已生成 ${images.length} 张图像`,
images: images,
usage: data.usage
usage: data.usage || null
};
} catch (error) {
clearTimeout(timeoutId);
@@ -1578,6 +1590,7 @@ const uiController = {
document.getElementById('model').value = currentSettings.model;
document.getElementById('timeout').value = currentSettings.timeout;
document.getElementById('proxy').value = currentSettings.proxy;
document.getElementById('responseFormat').value = currentSettings.responseFormat || 'b64_json';
// 加载聊天历史
const indexedChatHistory = await indexedDBStorage.getChatHistory();
@@ -1756,7 +1769,8 @@ const uiController = {
currentSettings.model = document.getElementById('model').value;
currentSettings.timeout = parseInt(document.getElementById('timeout').value);
currentSettings.proxy = document.getElementById('proxy').value;
currentSettings.responseFormat = document.getElementById('responseFormat').value;
const saved = await indexedDBStorage.saveSettings(currentSettings);
if (!saved) {
console.error('IndexedDB 保存设置失败');
@@ -1856,7 +1870,7 @@ const app = {
// 初始化"全部下载"按钮的可见性
uiController.updateDownloadAllButtonVisibility();
console.log('OpenRouter Image Generator initialized');
console.log('Grok Image Generator initialized');
},
// 初始化事件监听器
@@ -1969,6 +1983,21 @@ const app = {
return;
}
// 检查 API 地址是否已配置
const baseUrl = document.getElementById('baseUrl').value;
if (!baseUrl) {
utils.showNotification(ERROR_MESSAGES.NO_BASE_URL, 'warning');
return;
}
// 检查是否有上传的图像,如果有则提示不支持
if (uploadedImages && uploadedImages.length > 0) {
utils.showNotification(ERROR_MESSAGES.IMAGE_EDIT_NOT_SUPPORTED, 'warning');
// 清空上传的图像
uploadedImages = [];
uiController.updateUploadedImagesDisplay();
}
// 隐藏传统加载状态,使用占位图像代替
uiController.hideTraditionalLoading();