改为 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

View File

@@ -1,12 +0,0 @@
{
"permissions": {
"allow": [
"Bash(mkdir:*)"
],
"deny": []
},
"env": {
"ANTHROPIC_AUTH_TOKEN": "sk-zpZrOa1KqxkLCBH0eMMiIxvyLONJ9SAglhktSGKNNjCuKQQn",
"ANTHROPIC_BASE_URL":"https://instcopilot-api.com"
}
}

14
.kilocode/mcp.json Normal file
View File

@@ -0,0 +1,14 @@
{
"mcpServers": {
"superdesign": {
"command": "node",
"args": [
"E:/我的项目/superdesign-mcp-claude-code/dist/index.js"
],
"env": {},
"alwaysAllow": [
"superdesign_generate"
]
}
}
}

1
.roo/mcp.json Normal file
View File

@@ -0,0 +1 @@
{"mcpServers":{}}

View File

@@ -1,23 +1,28 @@
{
"app": {
"name": "OpenRouter Image Generator",
"version": "1.0.0",
"description": "基于OpenRouter API的图像生成Web应用",
"name": "Grok Image Generator",
"version": "2.0.0",
"description": "基于 Grok API 的图像生成 Web 应用",
"author": "OVINC CN",
"license": "MIT"
},
"api": {
"default_base_url": "https://openrouter.ai/api/v1",
"default_base_url": "",
"default_timeout": 600,
"default_model": "google/gemini-2.5-flash-image-preview:free",
"default_model": "grok-imagine-1.0",
"default_response_format": "b64_json",
"default_n": 1,
"supported_models": [
{
"id": "google/gemini-2.5-flash-image-preview:free",
"name": "Google Gemini 2.5 Flash Image Preview",
"description": "免费的Google Gemini模型,支持图像生成和视觉理解",
"pricing": "free"
"id": "grok-imagine-1.0",
"name": "Grok Imagine 1.0",
"description": "Grok 图像生成模型,支持文本到图像生成",
"pricing": "paid",
"capabilities": ["text-to-image"]
}
]
],
"supported_response_formats": ["url", "b64_json"],
"max_images_per_request": 10
},
"ui": {
"theme": {
@@ -42,22 +47,23 @@
}
},
"storage": {
"settings_key": "openRouterSettings",
"chat_history_key": "openRouterChatHistory",
"generated_images_key": "openRouterGeneratedImages"
"settings_key": "grokImageSettings",
"chat_history_key": "grokImageChatHistory",
"generated_images_key": "grokGeneratedImages"
},
"endpoints": {
"models": "/models",
"chat_completions": "/chat/completions",
"image_generation": "/images/generations"
"models": "/v1/models",
"image_generation": "/v1/images/generations"
},
"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 不支持图像编辑,仅支持文本生成图像"
}
}

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenRouter Image Generator</title>
<title>Grok Image Generator</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<link href="styles.css" rel="stylesheet">
@@ -16,9 +16,9 @@
<div class="card-header">
<h1 class="mb-0">
<i class="fas fa-image me-2"></i>
OpenRouter Image Generator
Grok Image Generator
</h1>
<p class="mb-0 mt-2">基于OpenRouter API的智能图像生成工具</p>
<p class="mb-0 mt-2">基于 Grok API 的智能图像生成工具</p>
</div>
<div class="card-body">
<!-- 设置面板 -->
@@ -35,30 +35,39 @@
<div class="col-md-6">
<div class="mb-3">
<label for="apiKey" class="form-label">API Key</label>
<input type="password" class="form-control" id="apiKey" placeholder="输入您的OpenRouter API Key">
<input type="password" class="form-control" id="apiKey" placeholder="输入您的 API Key">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="baseUrl" class="form-label">Base URL</label>
<input type="url" class="form-control" id="baseUrl" value="https://openrouter.ai/api/v1">
<label for="baseUrl" class="form-label">API 地址</label>
<input type="url" class="form-control" id="baseUrl" placeholder="输入 API 地址,如 http://localhost:8000">
</div>
</div>
<div class="col-md-4">
<div class="col-md-3">
<div class="mb-3">
<label for="model" class="form-label">模型</label>
<select class="form-select" id="model">
<option value="google/gemini-2.5-flash-image-preview:free">Google Gemini 2.5 Flash Image Preview (Free)</option>
<option value="grok-imagine-1.0">Grok Imagine 1.0</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="col-md-3">
<div class="mb-3">
<label for="responseFormat" class="form-label">响应格式</label>
<select class="form-select" id="responseFormat">
<option value="b64_json">Base64 (推荐)</option>
<option value="url">URL</option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="timeout" class="form-label">超时时间 (秒)</label>
<input type="number" class="form-control" id="timeout" value="600">
</div>
</div>
<div class="col-md-4">
<div class="col-md-3">
<div class="mb-3">
<label for="proxy" class="form-label">代理 (可选)</label>
<input type="url" class="form-control" id="proxy" placeholder="http://proxy:port">
@@ -84,17 +93,17 @@
</div>
</div>
<!-- 图像上传区域 -->
<!-- 图像上传区域(当前 API 不支持) -->
<div class="mb-4">
<h5><i class="fas fa-upload me-2"></i>上传参考图像</h5>
<h5><i class="fas fa-upload me-2"></i>上传参考图像 <span class="badge bg-secondary">暂不支持</span></h5>
<div class="row">
<div class="col-md-4">
<div class="border-2 border-dashed rounded p-4 text-center h-100 d-flex flex-column justify-content-center" id="dropZone">
<div class="border-2 border-dashed rounded p-4 text-center h-100 d-flex flex-column justify-content-center bg-light" id="dropZone" style="opacity: 0.6;">
<i class="fas fa-cloud-upload-alt fa-3x text-muted mb-3"></i>
<p class="text-muted">拖拽图像到此处或点击选择文件 (最多10张)</p>
<input type="file" class="d-none" id="imageInput" accept="image/*" multiple>
<button class="btn btn-outline-primary" onclick="document.getElementById('imageInput').click()">
选择图像
<p class="text-muted">当前 API 仅支持文本生成图像,暂不支持图像编辑</p>
<input type="file" class="d-none" id="imageInput" accept="image/*" multiple disabled>
<button class="btn btn-outline-secondary" disabled>
功能暂不可用
</button>
</div>
</div>

117
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 }
]
// 检查是否有上传的图像,如果有则提示不支持
if (images && images.length > 0) {
console.warn('当前 API 不支持图像编辑,将忽略上传的图像');
}
];
// 添加上传的图像
images.forEach(img => {
messages[0].content.push({
type: 'image_url',
image_url: { url: img.data }
});
});
// 构建请求 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 = [];
let hasError = false;
// 提取图像数据并转换为Blob URL但保留原始base64数据
if (choice.message.images) {
choice.message.images.forEach(img => {
// 确保原始数据是base64格式
const originalBase64 = img.image_url.url;
const blobUrl = utils.base64ToBlobUrl(originalBase64);
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,6 +1769,7 @@ 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) {
@@ -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();