mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Add Roo Code Cloud as an imagegen provider (#9528)
This commit is contained in:
parent
a20d047417
commit
a8b366f3dd
48 changed files with 673 additions and 192 deletions
|
|
@ -59,6 +59,7 @@ export const globalSettingsSchema = z.object({
|
|||
dismissedUpsells: z.array(z.string()).optional(),
|
||||
|
||||
// Image generation settings (experimental) - flattened for simplicity
|
||||
imageGenerationProvider: z.enum(["openrouter", "roo"]).optional(),
|
||||
openRouterImageApiKey: z.string().optional(),
|
||||
openRouterImageGenerationSelectedModel: z.string().optional(),
|
||||
|
||||
|
|
|
|||
|
|
@ -5,16 +5,39 @@
|
|||
export interface ImageGenerationModel {
|
||||
value: string
|
||||
label: string
|
||||
provider: ImageGenerationProvider
|
||||
}
|
||||
|
||||
export const IMAGE_GENERATION_MODELS: ImageGenerationModel[] = [
|
||||
{ value: "google/gemini-2.5-flash-image", label: "Gemini 2.5 Flash Image" },
|
||||
{ value: "google/gemini-3-pro-image-preview", label: "Gemini 3 Pro Image Preview" },
|
||||
{ value: "openai/gpt-5-image", label: "GPT-5 Image" },
|
||||
{ value: "openai/gpt-5-image-mini", label: "GPT-5 Image Mini" },
|
||||
// OpenRouter models
|
||||
{ value: "google/gemini-2.5-flash-image", label: "Gemini 2.5 Flash Image", provider: "openrouter" },
|
||||
{ value: "google/gemini-3-pro-image-preview", label: "Gemini 3 Pro Image Preview", provider: "openrouter" },
|
||||
{ value: "openai/gpt-5-image", label: "GPT-5 Image", provider: "openrouter" },
|
||||
{ value: "openai/gpt-5-image-mini", label: "GPT-5 Image Mini", provider: "openrouter" },
|
||||
// Roo Code Cloud models
|
||||
{ value: "google/gemini-2.5-flash-image", label: "Gemini 2.5 Flash Image", provider: "roo" },
|
||||
{ value: "google/gemini-3-pro-image", label: "Gemini 3 Pro Image", provider: "roo" },
|
||||
]
|
||||
|
||||
/**
|
||||
* Get array of model values only (for backend validation)
|
||||
*/
|
||||
export const IMAGE_GENERATION_MODEL_IDS = IMAGE_GENERATION_MODELS.map((m) => m.value)
|
||||
|
||||
/**
|
||||
* Image generation provider type
|
||||
*/
|
||||
export type ImageGenerationProvider = "openrouter" | "roo"
|
||||
|
||||
/**
|
||||
* Get the image generation provider with backwards compatibility
|
||||
* - If provider is explicitly set, use it
|
||||
* - If a model is already configured (existing users), default to "openrouter"
|
||||
* - Otherwise default to "roo" (new users)
|
||||
*/
|
||||
export function getImageGenerationProvider(
|
||||
explicitProvider: ImageGenerationProvider | undefined,
|
||||
hasExistingModel: boolean,
|
||||
): ImageGenerationProvider {
|
||||
return explicitProvider !== undefined ? explicitProvider : hasExistingModel ? "openrouter" : "roo"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,33 +28,7 @@ import { DEFAULT_HEADERS } from "./constants"
|
|||
import { BaseProvider } from "./base-provider"
|
||||
import type { ApiHandlerCreateMessageMetadata, SingleCompletionHandler } from "../index"
|
||||
import { handleOpenAIError } from "./utils/openai-error-handler"
|
||||
|
||||
// Image generation types
|
||||
interface ImageGenerationResponse {
|
||||
choices?: Array<{
|
||||
message?: {
|
||||
content?: string
|
||||
images?: Array<{
|
||||
type?: string
|
||||
image_url?: {
|
||||
url?: string
|
||||
}
|
||||
}>
|
||||
}
|
||||
}>
|
||||
error?: {
|
||||
message?: string
|
||||
type?: string
|
||||
code?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ImageGenerationResult {
|
||||
success: boolean
|
||||
imageData?: string
|
||||
imageFormat?: string
|
||||
error?: string
|
||||
}
|
||||
import { generateImageWithProvider, ImageGenerationResult } from "./utils/image-generation"
|
||||
|
||||
// Add custom interface for OpenRouter params.
|
||||
type OpenRouterChatCompletionParams = OpenAI.Chat.ChatCompletionCreateParams & {
|
||||
|
|
@ -519,103 +493,13 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const baseURL = this.options.openRouterBaseUrl || "https://openrouter.ai/api/v1"
|
||||
const response = await fetch(`${baseURL}/chat/completions`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
"Content-Type": "application/json",
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Code",
|
||||
"X-Title": "Roo Code",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model,
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: inputImage
|
||||
? [
|
||||
{
|
||||
type: "text",
|
||||
text: prompt,
|
||||
},
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: inputImage,
|
||||
},
|
||||
},
|
||||
]
|
||||
: prompt,
|
||||
},
|
||||
],
|
||||
modalities: ["image", "text"],
|
||||
}),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
let errorMessage = `Failed to generate image: ${response.status} ${response.statusText}`
|
||||
try {
|
||||
const errorJson = JSON.parse(errorText)
|
||||
if (errorJson.error?.message) {
|
||||
errorMessage = `Failed to generate image: ${errorJson.error.message}`
|
||||
}
|
||||
} catch {
|
||||
// Use default error message
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
}
|
||||
}
|
||||
|
||||
const result: ImageGenerationResponse = await response.json()
|
||||
|
||||
if (result.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: `Failed to generate image: ${result.error.message}`,
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the generated image from the response
|
||||
const images = result.choices?.[0]?.message?.images
|
||||
if (!images || images.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
error: "No image was generated in the response",
|
||||
}
|
||||
}
|
||||
|
||||
const imageData = images[0]?.image_url?.url
|
||||
if (!imageData) {
|
||||
return {
|
||||
success: false,
|
||||
error: "Invalid image data in response",
|
||||
}
|
||||
}
|
||||
|
||||
// Extract base64 data from data URL
|
||||
const base64Match = imageData.match(/^data:image\/(png|jpeg|jpg);base64,(.+)$/)
|
||||
if (!base64Match) {
|
||||
return {
|
||||
success: false,
|
||||
error: "Invalid image format received",
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
imageData: imageData,
|
||||
imageFormat: base64Match[1],
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : "Unknown error occurred",
|
||||
}
|
||||
}
|
||||
const baseURL = this.options.openRouterBaseUrl || "https://openrouter.ai/api/v1"
|
||||
return generateImageWithProvider({
|
||||
baseURL,
|
||||
authToken: apiKey,
|
||||
model,
|
||||
prompt,
|
||||
inputImage,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import type { ApiHandlerCreateMessageMetadata } from "../index"
|
|||
import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"
|
||||
import { getModels, getModelsFromCache } from "../providers/fetchers/modelCache"
|
||||
import { handleOpenAIError } from "./utils/openai-error-handler"
|
||||
import { generateImageWithProvider, ImageGenerationResult } from "./utils/image-generation"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
// Extend OpenAI's CompletionUsage to include Roo specific fields
|
||||
interface RooUsage extends OpenAI.CompletionUsage {
|
||||
|
|
@ -305,4 +307,30 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
|
|||
info: fallbackInfo,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an image using Roo Code Cloud's image generation API
|
||||
* @param prompt The text prompt for image generation
|
||||
* @param model The model to use for generation
|
||||
* @param inputImage Optional base64 encoded input image data URL
|
||||
* @returns The generated image data and format, or an error
|
||||
*/
|
||||
async generateImage(prompt: string, model: string, inputImage?: string): Promise<ImageGenerationResult> {
|
||||
const sessionToken = getSessionToken()
|
||||
|
||||
if (!sessionToken || sessionToken === "unauthenticated") {
|
||||
return {
|
||||
success: false,
|
||||
error: t("tools:generateImage.roo.authRequired"),
|
||||
}
|
||||
}
|
||||
|
||||
return generateImageWithProvider({
|
||||
baseURL: `${this.fetcherBaseURL}/v1`,
|
||||
authToken: sessionToken,
|
||||
model,
|
||||
prompt,
|
||||
inputImage,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
149
src/api/providers/utils/image-generation.ts
Normal file
149
src/api/providers/utils/image-generation.ts
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
import { t } from "../../../i18n"
|
||||
|
||||
// Image generation types
|
||||
interface ImageGenerationResponse {
|
||||
choices?: Array<{
|
||||
message?: {
|
||||
content?: string
|
||||
images?: Array<{
|
||||
type?: string
|
||||
image_url?: {
|
||||
url?: string
|
||||
}
|
||||
}>
|
||||
}
|
||||
}>
|
||||
error?: {
|
||||
message?: string
|
||||
type?: string
|
||||
code?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ImageGenerationResult {
|
||||
success: boolean
|
||||
imageData?: string
|
||||
imageFormat?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
interface ImageGenerationOptions {
|
||||
baseURL: string
|
||||
authToken: string
|
||||
model: string
|
||||
prompt: string
|
||||
inputImage?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared image generation implementation for OpenRouter and Roo Code Cloud providers
|
||||
*/
|
||||
export async function generateImageWithProvider(options: ImageGenerationOptions): Promise<ImageGenerationResult> {
|
||||
const { baseURL, authToken, model, prompt, inputImage } = options
|
||||
|
||||
try {
|
||||
const response = await fetch(`${baseURL}/chat/completions`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Code",
|
||||
"X-Title": "Roo Code",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model,
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: inputImage
|
||||
? [
|
||||
{
|
||||
type: "text",
|
||||
text: prompt,
|
||||
},
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: inputImage,
|
||||
},
|
||||
},
|
||||
]
|
||||
: prompt,
|
||||
},
|
||||
],
|
||||
modalities: ["image", "text"],
|
||||
}),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
let errorMessage = t("tools:generateImage.failedWithStatus", {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
})
|
||||
|
||||
try {
|
||||
const errorJson = JSON.parse(errorText)
|
||||
if (errorJson.error?.message) {
|
||||
errorMessage = t("tools:generateImage.failedWithMessage", {
|
||||
message: errorJson.error.message,
|
||||
})
|
||||
}
|
||||
} catch {
|
||||
// Use default error message
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
}
|
||||
}
|
||||
|
||||
const result: ImageGenerationResponse = await response.json()
|
||||
|
||||
if (result.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: t("tools:generateImage.failedWithMessage", {
|
||||
message: result.error.message,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the generated image from the response
|
||||
const images = result.choices?.[0]?.message?.images
|
||||
if (!images || images.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
error: t("tools:generateImage.noImageGenerated"),
|
||||
}
|
||||
}
|
||||
|
||||
const imageData = images[0]?.image_url?.url
|
||||
if (!imageData) {
|
||||
return {
|
||||
success: false,
|
||||
error: t("tools:generateImage.invalidImageData"),
|
||||
}
|
||||
}
|
||||
|
||||
// Extract base64 data from data URL
|
||||
const base64Match = imageData.match(/^data:image\/(png|jpeg|jpg);base64,(.+)$/)
|
||||
if (!base64Match) {
|
||||
return {
|
||||
success: false,
|
||||
error: t("tools:generateImage.invalidImageFormat"),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
imageData: imageData,
|
||||
imageFormat: base64Match[1],
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : t("tools:generateImage.unknownError"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,12 @@
|
|||
import path from "path"
|
||||
import fs from "fs/promises"
|
||||
import * as vscode from "vscode"
|
||||
import { GenerateImageParams, IMAGE_GENERATION_MODEL_IDS } from "@roo-code/types"
|
||||
import {
|
||||
GenerateImageParams,
|
||||
IMAGE_GENERATION_MODEL_IDS,
|
||||
IMAGE_GENERATION_MODELS,
|
||||
getImageGenerationProvider,
|
||||
} from "@roo-code/types"
|
||||
import { Task } from "../task/Task"
|
||||
import { formatResponse } from "../prompts/responses"
|
||||
import { fileExistsAtPath } from "../../utils/fs"
|
||||
|
|
@ -9,8 +14,10 @@ import { getReadablePath } from "../../utils/path"
|
|||
import { isPathOutsideWorkspace } from "../../utils/pathUtils"
|
||||
import { EXPERIMENT_IDS, experiments } from "../../shared/experiments"
|
||||
import { OpenRouterHandler } from "../../api/providers/openrouter"
|
||||
import { RooHandler } from "../../api/providers/roo"
|
||||
import { BaseTool, ToolCallbacks } from "./BaseTool"
|
||||
import type { ToolUse } from "../../shared/tools"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
export class GenerateImageTool extends BaseTool<"generate_image"> {
|
||||
readonly name = "generate_image" as const
|
||||
|
|
@ -120,22 +127,42 @@ export class GenerateImageTool extends BaseTool<"generate_image"> {
|
|||
|
||||
const isWriteProtected = task.rooProtectedController?.isWriteProtected(relPath) || false
|
||||
|
||||
const openRouterApiKey = state?.openRouterImageApiKey
|
||||
// Use shared utility for backwards compatibility logic
|
||||
const imageProvider = getImageGenerationProvider(
|
||||
state?.imageGenerationProvider,
|
||||
!!state?.openRouterImageGenerationSelectedModel,
|
||||
)
|
||||
|
||||
if (!openRouterApiKey) {
|
||||
await task.say(
|
||||
"error",
|
||||
"OpenRouter API key is required for image generation. Please configure it in the Image Generation experimental settings.",
|
||||
)
|
||||
pushToolResult(
|
||||
formatResponse.toolError(
|
||||
"OpenRouter API key is required for image generation. Please configure it in the Image Generation experimental settings.",
|
||||
),
|
||||
)
|
||||
return
|
||||
// Get the selected model
|
||||
let selectedModel = state?.openRouterImageGenerationSelectedModel
|
||||
|
||||
// Verify the selected model matches the selected provider
|
||||
// If not, default to first model of the selected provider
|
||||
if (selectedModel) {
|
||||
const modelInfo = IMAGE_GENERATION_MODELS.find((m) => m.value === selectedModel)
|
||||
if (!modelInfo || modelInfo.provider !== imageProvider) {
|
||||
// Model doesn't match provider, use first model for selected provider
|
||||
const providerModels = IMAGE_GENERATION_MODELS.filter((m) => m.provider === imageProvider)
|
||||
selectedModel = providerModels[0]?.value || IMAGE_GENERATION_MODEL_IDS[0]
|
||||
}
|
||||
} else {
|
||||
// No model selected, use first model for selected provider
|
||||
const providerModels = IMAGE_GENERATION_MODELS.filter((m) => m.provider === imageProvider)
|
||||
selectedModel = providerModels[0]?.value || IMAGE_GENERATION_MODEL_IDS[0]
|
||||
}
|
||||
|
||||
const selectedModel = state?.openRouterImageGenerationSelectedModel || IMAGE_GENERATION_MODEL_IDS[0]
|
||||
// Use the provider selection
|
||||
const modelProvider = imageProvider
|
||||
|
||||
// Validate API key for OpenRouter
|
||||
const openRouterApiKey = state?.openRouterImageApiKey
|
||||
|
||||
if (imageProvider === "openrouter" && !openRouterApiKey) {
|
||||
const errorMessage = t("tools:generateImage.openRouterApiKeyRequired")
|
||||
await task.say("error", errorMessage)
|
||||
pushToolResult(formatResponse.toolError(errorMessage))
|
||||
return
|
||||
}
|
||||
|
||||
const fullPath = path.resolve(task.cwd, removeClosingTag("path", relPath))
|
||||
const isOutsideWorkspace = isPathOutsideWorkspace(fullPath)
|
||||
|
|
@ -163,14 +190,16 @@ export class GenerateImageTool extends BaseTool<"generate_image"> {
|
|||
return
|
||||
}
|
||||
|
||||
const openRouterHandler = new OpenRouterHandler({} as any)
|
||||
|
||||
const result = await openRouterHandler.generateImage(
|
||||
prompt,
|
||||
selectedModel,
|
||||
openRouterApiKey,
|
||||
inputImageData,
|
||||
)
|
||||
let result
|
||||
if (modelProvider === "roo") {
|
||||
// Use Roo Code Cloud provider
|
||||
const rooHandler = new RooHandler({} as any)
|
||||
result = await rooHandler.generateImage(prompt, selectedModel, inputImageData)
|
||||
} else {
|
||||
// Use OpenRouter provider
|
||||
const openRouterHandler = new OpenRouterHandler({} as any)
|
||||
result = await openRouterHandler.generateImage(prompt, selectedModel, openRouterApiKey!, inputImageData)
|
||||
}
|
||||
|
||||
if (!result.success) {
|
||||
await task.say("error", result.error || "Failed to generate image")
|
||||
|
|
|
|||
|
|
@ -1921,6 +1921,7 @@ export class ClineProvider
|
|||
maxGitStatusFiles,
|
||||
taskSyncEnabled,
|
||||
remoteControlEnabled,
|
||||
imageGenerationProvider,
|
||||
openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel,
|
||||
openRouterUseMiddleOutTransform,
|
||||
|
|
@ -2088,6 +2089,7 @@ export class ClineProvider
|
|||
maxGitStatusFiles: maxGitStatusFiles ?? 0,
|
||||
taskSyncEnabled,
|
||||
remoteControlEnabled,
|
||||
imageGenerationProvider,
|
||||
openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel,
|
||||
openRouterUseMiddleOutTransform,
|
||||
|
|
@ -2318,6 +2320,7 @@ export class ClineProvider
|
|||
return false
|
||||
}
|
||||
})(),
|
||||
imageGenerationProvider: stateValues.imageGenerationProvider,
|
||||
openRouterImageApiKey: stateValues.openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel: stateValues.openRouterImageGenerationSelectedModel,
|
||||
featureRoomoteControlEnabled: (() => {
|
||||
|
|
|
|||
12
src/i18n/locales/ca/tools.json
generated
12
src/i18n/locales/ca/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "No s'ha pogut crear una nova tasca a causa de restriccions de política."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "Es requereix la clau API d'OpenRouter per a la generació d'imatges amb models d'OpenRouter. Configura-la a la configuració experimental de Generació d'Imatges.",
|
||||
"failedWithStatus": "Error en generar imatge: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Error en generar imatge: {{message}}",
|
||||
"noImageGenerated": "No s'ha generat cap imatge en la resposta",
|
||||
"invalidImageData": "Dades d'imatge no vàlides en la resposta",
|
||||
"invalidImageFormat": "Format d'imatge no vàlid rebut",
|
||||
"unknownError": "S'ha produït un error desconegut",
|
||||
"roo": {
|
||||
"authRequired": "Es requereix autenticació de Roo Code Cloud per a la generació d'imatges. Inicia sessió a Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/de/tools.json
generated
12
src/i18n/locales/de/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Neue Aufgabe konnte aufgrund von Richtlinienbeschränkungen nicht erstellt werden."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouter API-Schlüssel ist für die Bildgenerierung mit OpenRouter-Modellen erforderlich. Bitte konfiguriere ihn in den Experimentellen Einstellungen für Bildgenerierung.",
|
||||
"failedWithStatus": "Bildgenerierung fehlgeschlagen: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Bildgenerierung fehlgeschlagen: {{message}}",
|
||||
"noImageGenerated": "In der Antwort wurde kein Bild generiert",
|
||||
"invalidImageData": "Ungültige Bilddaten in der Antwort",
|
||||
"invalidImageFormat": "Ungültiges Bildformat erhalten",
|
||||
"unknownError": "Unbekannter Fehler aufgetreten",
|
||||
"roo": {
|
||||
"authRequired": "Roo Code Cloud-Authentifizierung ist für die Bildgenerierung erforderlich. Bitte melde dich bei Roo Code Cloud an."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Failed to create new task due to policy restrictions."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouter API key is required for image generation with OpenRouter models. Please configure it in the Image Generation experimental settings.",
|
||||
"failedWithStatus": "Failed to generate image: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Failed to generate image: {{message}}",
|
||||
"noImageGenerated": "No image was generated in the response",
|
||||
"invalidImageData": "Invalid image data in response",
|
||||
"invalidImageFormat": "Invalid image format received",
|
||||
"unknownError": "Unknown error occurred",
|
||||
"roo": {
|
||||
"authRequired": "Roo Code Cloud authentication is required for image generation. Please sign in to Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/es/tools.json
generated
12
src/i18n/locales/es/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "No se pudo crear una nueva tarea debido a restricciones de política."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "Se requiere la clave API de OpenRouter para la generación de imágenes con modelos de OpenRouter. Por favor, configúrala en la configuración experimental de Generación de Imágenes.",
|
||||
"failedWithStatus": "Error al generar imagen: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Error al generar imagen: {{message}}",
|
||||
"noImageGenerated": "No se generó ninguna imagen en la respuesta",
|
||||
"invalidImageData": "Datos de imagen no válidos en la respuesta",
|
||||
"invalidImageFormat": "Formato de imagen no válido recibido",
|
||||
"unknownError": "Ocurrió un error desconocido",
|
||||
"roo": {
|
||||
"authRequired": "Se requiere autenticación de Roo Code Cloud para la generación de imágenes. Por favor, inicia sesión en Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/fr/tools.json
generated
12
src/i18n/locales/fr/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Impossible de créer une nouvelle tâche en raison de restrictions de politique."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "La clé API OpenRouter est requise pour la génération d'images avec les modèles OpenRouter. Veuillez la configurer dans les paramètres expérimentaux de Génération d'Images.",
|
||||
"failedWithStatus": "Échec de génération de l'image : {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Échec de génération de l'image : {{message}}",
|
||||
"noImageGenerated": "Aucune image n'a été générée dans la réponse",
|
||||
"invalidImageData": "Données d'image non valides dans la réponse",
|
||||
"invalidImageFormat": "Format d'image non valide reçu",
|
||||
"unknownError": "Une erreur inconnue s'est produite",
|
||||
"roo": {
|
||||
"authRequired": "L'authentification Roo Code Cloud est requise pour la génération d'images. Veuillez vous connecter à Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/hi/tools.json
generated
12
src/i18n/locales/hi/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "नीति प्रतिबंधों के कारण नया कार्य बनाने में विफल।"
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouter मॉडल के साथ छवि निर्माण के लिए OpenRouter API कुंजी आवश्यक है। कृपया इसे छवि निर्माण प्रयोगात्मक सेटिंग में कॉन्फ़िगर करें।",
|
||||
"failedWithStatus": "छवि निर्माण विफल: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "छवि निर्माण विफल: {{message}}",
|
||||
"noImageGenerated": "प्रतिक्रिया में कोई छवि उत्पन्न नहीं हुई",
|
||||
"invalidImageData": "प्रतिक्रिया में अमान्य छवि डेटा",
|
||||
"invalidImageFormat": "अमान्य छवि प्रारूप प्राप्त हुआ",
|
||||
"unknownError": "एक अज्ञात त्रुटि हुई",
|
||||
"roo": {
|
||||
"authRequired": "छवि निर्माण के लिए Roo Code Cloud प्रमाणीकरण आवश्यक है। कृपया Roo Code Cloud में साइन इन करें।"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/id/tools.json
generated
12
src/i18n/locales/id/tools.json
generated
|
|
@ -17,5 +17,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Gagal membuat tugas baru karena pembatasan kebijakan."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "Kunci API OpenRouter diperlukan untuk menghasilkan gambar dengan model OpenRouter. Silakan konfigurasikan di pengaturan eksperimental Pembuatan Gambar.",
|
||||
"failedWithStatus": "Gagal menghasilkan gambar: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Gagal menghasilkan gambar: {{message}}",
|
||||
"noImageGenerated": "Tidak ada gambar yang dihasilkan dalam respons",
|
||||
"invalidImageData": "Data gambar tidak valid dalam respons",
|
||||
"invalidImageFormat": "Format gambar tidak valid diterima",
|
||||
"unknownError": "Terjadi kesalahan yang tidak diketahui",
|
||||
"roo": {
|
||||
"authRequired": "Autentikasi Roo Code Cloud diperlukan untuk menghasilkan gambar. Silakan masuk ke Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/it/tools.json
generated
12
src/i18n/locales/it/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Impossibile creare una nuova attività a causa di restrizioni di policy."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "La chiave API OpenRouter è richiesta per la generazione di immagini con i modelli OpenRouter. Configurala nelle impostazioni sperimentali di Generazione Immagini.",
|
||||
"failedWithStatus": "Generazione immagine fallita: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Generazione immagine fallita: {{message}}",
|
||||
"noImageGenerated": "Nessuna immagine è stata generata nella risposta",
|
||||
"invalidImageData": "Dati immagine non validi nella risposta",
|
||||
"invalidImageFormat": "Formato immagine non valido ricevuto",
|
||||
"unknownError": "Si è verificato un errore sconosciuto",
|
||||
"roo": {
|
||||
"authRequired": "L'autenticazione Roo Code Cloud è richiesta per la generazione di immagini. Accedi a Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/ja/tools.json
generated
12
src/i18n/locales/ja/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "ポリシー制限により新しいタスクを作成できませんでした。"
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouterモデルでの画像生成にはOpenRouter APIキーが必要です。画像生成の実験設定で設定してください。",
|
||||
"failedWithStatus": "画像生成に失敗しました: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "画像生成に失敗しました: {{message}}",
|
||||
"noImageGenerated": "レスポンスに画像が生成されませんでした",
|
||||
"invalidImageData": "レスポンスに無効な画像データがあります",
|
||||
"invalidImageFormat": "無効な画像フォーマットを受信しました",
|
||||
"unknownError": "不明なエラーが発生しました",
|
||||
"roo": {
|
||||
"authRequired": "画像生成にはRoo Code Cloud認証が必要です。Roo Code Cloudにサインインしてください。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/ko/tools.json
generated
12
src/i18n/locales/ko/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "정책 제한으로 인해 새 작업을 생성하지 못했습니다."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouter 모델로 이미지를 생성하려면 OpenRouter API 키가 필요합니다. 이미지 생성 실험 설정에서 구성하세요.",
|
||||
"failedWithStatus": "이미지 생성 실패: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "이미지 생성 실패: {{message}}",
|
||||
"noImageGenerated": "응답에서 이미지가 생성되지 않았습니다",
|
||||
"invalidImageData": "응답에 잘못된 이미지 데이터가 있습니다",
|
||||
"invalidImageFormat": "잘못된 이미지 형식을 받았습니다",
|
||||
"unknownError": "알 수 없는 오류가 발생했습니다",
|
||||
"roo": {
|
||||
"authRequired": "이미지 생성에는 Roo Code Cloud 인증이 필요합니다. Roo Code Cloud에 로그인하세요."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/nl/tools.json
generated
12
src/i18n/locales/nl/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Kan geen nieuwe taak aanmaken vanwege beleidsbeperkingen."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouter API-sleutel is vereist voor het genereren van afbeeldingen met OpenRouter-modellen. Configureer deze in de Experimentele Instellingen voor Afbeeldingsgeneratie.",
|
||||
"failedWithStatus": "Afbeelding genereren mislukt: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Afbeelding genereren mislukt: {{message}}",
|
||||
"noImageGenerated": "Er is geen afbeelding gegenereerd in het antwoord",
|
||||
"invalidImageData": "Ongeldige afbeeldingsgegevens in het antwoord",
|
||||
"invalidImageFormat": "Ongeldig afbeeldingsformaat ontvangen",
|
||||
"unknownError": "Er is een onbekende fout opgetreden",
|
||||
"roo": {
|
||||
"authRequired": "Roo Code Cloud-authenticatie is vereist voor het genereren van afbeeldingen. Log in bij Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/pl/tools.json
generated
12
src/i18n/locales/pl/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Nie udało się utworzyć nowego zadania z powodu ograniczeń polityki."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "Klucz API OpenRouter jest wymagany do generowania obrazów z modelami OpenRouter. Skonfiguruj go w eksperymentalnych ustawieniach generowania obrazów.",
|
||||
"failedWithStatus": "Nie udało się wygenerować obrazu: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Nie udało się wygenerować obrazu: {{message}}",
|
||||
"noImageGenerated": "W odpowiedzi nie wygenerowano żadnego obrazu",
|
||||
"invalidImageData": "Nieprawidłowe dane obrazu w odpowiedzi",
|
||||
"invalidImageFormat": "Otrzymano nieprawidłowy format obrazu",
|
||||
"unknownError": "Wystąpił nieznany błąd",
|
||||
"roo": {
|
||||
"authRequired": "Uwierzytelnienie Roo Code Cloud jest wymagane do generowania obrazów. Zaloguj się do Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/pt-BR/tools.json
generated
12
src/i18n/locales/pt-BR/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Falha ao criar nova tarefa devido a restrições de política."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "A chave API do OpenRouter é necessária para geração de imagens com modelos OpenRouter. Configure-a nas configurações experimentais de Geração de Imagens.",
|
||||
"failedWithStatus": "Falha ao gerar imagem: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Falha ao gerar imagem: {{message}}",
|
||||
"noImageGenerated": "Nenhuma imagem foi gerada na resposta",
|
||||
"invalidImageData": "Dados de imagem inválidos na resposta",
|
||||
"invalidImageFormat": "Formato de imagem inválido recebido",
|
||||
"unknownError": "Ocorreu um erro desconhecido",
|
||||
"roo": {
|
||||
"authRequired": "A autenticação do Roo Code Cloud é necessária para geração de imagens. Faça login no Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/ru/tools.json
generated
12
src/i18n/locales/ru/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Не удалось создать новую задачу из-за ограничений политики."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "Для генерации изображений с моделями OpenRouter требуется API-ключ OpenRouter. Настройте его в экспериментальных настройках генерации изображений.",
|
||||
"failedWithStatus": "Не удалось сгенерировать изображение: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Не удалось сгенерировать изображение: {{message}}",
|
||||
"noImageGenerated": "В ответе не было сгенерировано изображение",
|
||||
"invalidImageData": "Недопустимые данные изображения в ответе",
|
||||
"invalidImageFormat": "Получен недопустимый формат изображения",
|
||||
"unknownError": "Произошла неизвестная ошибка",
|
||||
"roo": {
|
||||
"authRequired": "Для генерации изображений требуется аутентификация Roo Code Cloud. Войдите в Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/tr/tools.json
generated
12
src/i18n/locales/tr/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Politika kısıtlamaları nedeniyle yeni görev oluşturulamadı."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "OpenRouter modelleriyle görüntü oluşturma için OpenRouter API anahtarı gereklidir. Lütfen Görüntü Oluşturma deneysel ayarlarında yapılandırın.",
|
||||
"failedWithStatus": "Görüntü oluşturma başarısız: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Görüntü oluşturma başarısız: {{message}}",
|
||||
"noImageGenerated": "Yanıtta görüntü oluşturulmadı",
|
||||
"invalidImageData": "Yanıtta geçersiz görüntü verisi",
|
||||
"invalidImageFormat": "Geçersiz görüntü formatı alındı",
|
||||
"unknownError": "Bilinmeyen bir hata oluştu",
|
||||
"roo": {
|
||||
"authRequired": "Görüntü oluşturma için Roo Code Cloud kimlik doğrulaması gereklidir. Lütfen Roo Code Cloud'da oturum açın."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/vi/tools.json
generated
12
src/i18n/locales/vi/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Không thể tạo nhiệm vụ mới do hạn chế chính sách."
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "Yêu cầu khóa API OpenRouter để tạo hình ảnh với các mô hình OpenRouter. Vui lòng cấu hình trong cài đặt thử nghiệm Tạo hình ảnh.",
|
||||
"failedWithStatus": "Tạo hình ảnh thất bại: {{status}} {{statusText}}",
|
||||
"failedWithMessage": "Tạo hình ảnh thất bại: {{message}}",
|
||||
"noImageGenerated": "Không có hình ảnh nào được tạo trong phản hồi",
|
||||
"invalidImageData": "Dữ liệu hình ảnh không hợp lệ trong phản hồi",
|
||||
"invalidImageFormat": "Nhận được định dạng hình ảnh không hợp lệ",
|
||||
"unknownError": "Đã xảy ra lỗi không xác định",
|
||||
"roo": {
|
||||
"authRequired": "Yêu cầu xác thực Roo Code Cloud để tạo hình ảnh. Vui lòng đăng nhập vào Roo Code Cloud."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/zh-CN/tools.json
generated
12
src/i18n/locales/zh-CN/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "由于策略限制,无法创建新任务。"
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "使用 OpenRouter 模型生成图像需要 OpenRouter API 密钥。请在图像生成实验设置中配置。",
|
||||
"failedWithStatus": "图像生成失败:{{status}} {{statusText}}",
|
||||
"failedWithMessage": "图像生成失败:{{message}}",
|
||||
"noImageGenerated": "响应中未生成图像",
|
||||
"invalidImageData": "响应中的图像数据无效",
|
||||
"invalidImageFormat": "收到的图像格式无效",
|
||||
"unknownError": "发生未知错误",
|
||||
"roo": {
|
||||
"authRequired": "图像生成需要 Roo Code Cloud 认证。请登录 Roo Code Cloud。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/i18n/locales/zh-TW/tools.json
generated
12
src/i18n/locales/zh-TW/tools.json
generated
|
|
@ -14,5 +14,17 @@
|
|||
"errors": {
|
||||
"policy_restriction": "由於政策限制,無法建立新工作。"
|
||||
}
|
||||
},
|
||||
"generateImage": {
|
||||
"openRouterApiKeyRequired": "使用 OpenRouter 模型生成圖像需要 OpenRouter API 金鑰。請在圖像生成實驗設定中配置。",
|
||||
"failedWithStatus": "圖像生成失敗:{{status}} {{statusText}}",
|
||||
"failedWithMessage": "圖像生成失敗:{{message}}",
|
||||
"noImageGenerated": "回應中未生成圖像",
|
||||
"invalidImageData": "回應中的圖像資料無效",
|
||||
"invalidImageFormat": "收到的圖像格式無效",
|
||||
"unknownError": "發生未知錯誤",
|
||||
"roo": {
|
||||
"authRequired": "圖像生成需要 Roo Code Cloud 認證。請登入 Roo Code Cloud。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ export type ExtensionState = Pick<
|
|||
| "profileThresholds"
|
||||
| "includeDiagnosticMessages"
|
||||
| "maxDiagnosticMessages"
|
||||
| "imageGenerationProvider"
|
||||
| "openRouterImageGenerationSelectedModel"
|
||||
| "includeTaskHistoryInEnhance"
|
||||
| "reasoningBlockCollapsed"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { HTMLAttributes } from "react"
|
||||
import { FlaskConical } from "lucide-react"
|
||||
|
||||
import type { Experiments } from "@roo-code/types"
|
||||
import type { Experiments, ImageGenerationProvider } from "@roo-code/types"
|
||||
|
||||
import { EXPERIMENT_IDS, experimentConfigsMap } from "@roo/experiments"
|
||||
|
||||
|
|
@ -19,8 +19,10 @@ type ExperimentalSettingsProps = HTMLAttributes<HTMLDivElement> & {
|
|||
setExperimentEnabled: SetExperimentEnabled
|
||||
apiConfiguration?: any
|
||||
setApiConfigurationField?: any
|
||||
imageGenerationProvider?: ImageGenerationProvider
|
||||
openRouterImageApiKey?: string
|
||||
openRouterImageGenerationSelectedModel?: string
|
||||
setImageGenerationProvider?: (provider: ImageGenerationProvider) => void
|
||||
setOpenRouterImageApiKey?: (apiKey: string) => void
|
||||
setImageGenerationSelectedModel?: (model: string) => void
|
||||
}
|
||||
|
|
@ -30,8 +32,10 @@ export const ExperimentalSettings = ({
|
|||
setExperimentEnabled,
|
||||
apiConfiguration,
|
||||
setApiConfigurationField,
|
||||
imageGenerationProvider,
|
||||
openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel,
|
||||
setImageGenerationProvider,
|
||||
setOpenRouterImageApiKey,
|
||||
setImageGenerationSelectedModel,
|
||||
className,
|
||||
|
|
@ -66,6 +70,7 @@ export const ExperimentalSettings = ({
|
|||
}
|
||||
if (
|
||||
config[0] === "IMAGE_GENERATION" &&
|
||||
setImageGenerationProvider &&
|
||||
setOpenRouterImageApiKey &&
|
||||
setImageGenerationSelectedModel
|
||||
) {
|
||||
|
|
@ -76,8 +81,10 @@ export const ExperimentalSettings = ({
|
|||
onChange={(enabled) =>
|
||||
setExperimentEnabled(EXPERIMENT_IDS.IMAGE_GENERATION, enabled)
|
||||
}
|
||||
imageGenerationProvider={imageGenerationProvider}
|
||||
openRouterImageApiKey={openRouterImageApiKey}
|
||||
openRouterImageGenerationSelectedModel={openRouterImageGenerationSelectedModel}
|
||||
setImageGenerationProvider={setImageGenerationProvider}
|
||||
setOpenRouterImageApiKey={setOpenRouterImageApiKey}
|
||||
setImageGenerationSelectedModel={setImageGenerationSelectedModel}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import React, { useState, useEffect } from "react"
|
||||
import React, { useMemo } from "react"
|
||||
import { VSCodeCheckbox, VSCodeTextField, VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"
|
||||
import { IMAGE_GENERATION_MODELS } from "@roo-code/types"
|
||||
import { IMAGE_GENERATION_MODELS, type ImageGenerationProvider, getImageGenerationProvider } from "@roo-code/types"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
|
||||
interface ImageGenerationSettingsProps {
|
||||
enabled: boolean
|
||||
onChange: (enabled: boolean) => void
|
||||
imageGenerationProvider?: ImageGenerationProvider
|
||||
openRouterImageApiKey?: string
|
||||
openRouterImageGenerationSelectedModel?: string
|
||||
setImageGenerationProvider: (provider: ImageGenerationProvider) => void
|
||||
setOpenRouterImageApiKey: (apiKey: string) => void
|
||||
setImageGenerationSelectedModel: (model: string) => void
|
||||
}
|
||||
|
|
@ -15,36 +17,79 @@ interface ImageGenerationSettingsProps {
|
|||
export const ImageGenerationSettings = ({
|
||||
enabled,
|
||||
onChange,
|
||||
imageGenerationProvider,
|
||||
openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel,
|
||||
setImageGenerationProvider,
|
||||
setOpenRouterImageApiKey,
|
||||
setImageGenerationSelectedModel,
|
||||
}: ImageGenerationSettingsProps) => {
|
||||
const { t } = useAppTranslation()
|
||||
|
||||
const [apiKey, setApiKey] = useState(openRouterImageApiKey || "")
|
||||
const [selectedModel, setSelectedModel] = useState(
|
||||
openRouterImageGenerationSelectedModel || IMAGE_GENERATION_MODELS[0].value,
|
||||
// Use shared utility for backwards compatibility logic
|
||||
const currentProvider = getImageGenerationProvider(
|
||||
imageGenerationProvider,
|
||||
!!openRouterImageGenerationSelectedModel,
|
||||
)
|
||||
|
||||
// Update local state when props change (e.g., when switching profiles)
|
||||
useEffect(() => {
|
||||
setApiKey(openRouterImageApiKey || "")
|
||||
setSelectedModel(openRouterImageGenerationSelectedModel || IMAGE_GENERATION_MODELS[0].value)
|
||||
}, [openRouterImageApiKey, openRouterImageGenerationSelectedModel])
|
||||
const availableModels = useMemo(() => {
|
||||
return IMAGE_GENERATION_MODELS.filter((model) => model.provider === currentProvider)
|
||||
}, [currentProvider])
|
||||
|
||||
// Derive the current model value - either from props or first available
|
||||
const currentModel = useMemo(() => {
|
||||
// If we have a stored model, verify it exists for the current provider
|
||||
// (check both value and provider since some models have duplicate values)
|
||||
if (openRouterImageGenerationSelectedModel) {
|
||||
// Find a model that matches BOTH the value AND the current provider
|
||||
const modelInfo = IMAGE_GENERATION_MODELS.find(
|
||||
(m) => m.value === openRouterImageGenerationSelectedModel && m.provider === currentProvider,
|
||||
)
|
||||
if (modelInfo) {
|
||||
return openRouterImageGenerationSelectedModel
|
||||
}
|
||||
}
|
||||
// Otherwise use first available model for current provider
|
||||
return availableModels[0]?.value || IMAGE_GENERATION_MODELS[0].value
|
||||
}, [openRouterImageGenerationSelectedModel, availableModels, currentProvider])
|
||||
|
||||
// Handle provider changes
|
||||
const handleProviderChange = (value: string) => {
|
||||
const newProvider = value as ImageGenerationProvider
|
||||
setImageGenerationProvider(newProvider)
|
||||
|
||||
// Smart model selection when switching providers:
|
||||
// 1. If current model exists for new provider (same model name), keep it
|
||||
// 2. Otherwise, switch to first available model for new provider
|
||||
const providerModels = IMAGE_GENERATION_MODELS.filter((m) => m.provider === newProvider)
|
||||
if (providerModels.length > 0) {
|
||||
// Check if current model exists for new provider
|
||||
const currentModelForNewProvider = providerModels.find(
|
||||
(m) => m.value === openRouterImageGenerationSelectedModel,
|
||||
)
|
||||
if (currentModelForNewProvider) {
|
||||
// Current model exists for new provider, keep it
|
||||
// No need to call setImageGenerationSelectedModel since the value doesn't change
|
||||
} else {
|
||||
// Current model doesn't exist for new provider, switch to first available
|
||||
setImageGenerationSelectedModel(providerModels[0].value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle API key changes
|
||||
const handleApiKeyChange = (value: string) => {
|
||||
setApiKey(value)
|
||||
setOpenRouterImageApiKey(value)
|
||||
}
|
||||
|
||||
// Handle model selection changes
|
||||
const handleModelChange = (value: string) => {
|
||||
setSelectedModel(value)
|
||||
setImageGenerationSelectedModel(value)
|
||||
}
|
||||
|
||||
const requiresApiKey = currentProvider === "openrouter"
|
||||
const isConfigured = !requiresApiKey || (requiresApiKey && openRouterImageApiKey)
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
|
|
@ -60,40 +105,63 @@ export const ImageGenerationSettings = ({
|
|||
|
||||
{enabled && (
|
||||
<div className="ml-2 space-y-3">
|
||||
{/* API Key Configuration */}
|
||||
{/* Provider Selection */}
|
||||
<div>
|
||||
<label className="block font-medium mb-1">
|
||||
{t("settings:experimental.IMAGE_GENERATION.openRouterApiKeyLabel")}
|
||||
{t("settings:experimental.IMAGE_GENERATION.providerLabel")}
|
||||
</label>
|
||||
<VSCodeTextField
|
||||
value={apiKey}
|
||||
onInput={(e: any) => handleApiKeyChange(e.target.value)}
|
||||
placeholder={t("settings:experimental.IMAGE_GENERATION.openRouterApiKeyPlaceholder")}
|
||||
className="w-full"
|
||||
type="password"
|
||||
/>
|
||||
<VSCodeDropdown
|
||||
value={currentProvider}
|
||||
onChange={(e: any) => handleProviderChange(e.target.value)}
|
||||
className="w-full">
|
||||
<VSCodeOption value="roo" className="py-2 px-3">
|
||||
Roo Code Cloud
|
||||
</VSCodeOption>
|
||||
<VSCodeOption value="openrouter" className="py-2 px-3">
|
||||
OpenRouter
|
||||
</VSCodeOption>
|
||||
</VSCodeDropdown>
|
||||
<p className="text-vscode-descriptionForeground text-xs mt-1">
|
||||
{t("settings:experimental.IMAGE_GENERATION.getApiKeyText")}{" "}
|
||||
<a
|
||||
href="https://openrouter.ai/keys"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground">
|
||||
openrouter.ai/keys
|
||||
</a>
|
||||
{t("settings:experimental.IMAGE_GENERATION.providerDescription")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* API Key Configuration (only for OpenRouter) */}
|
||||
{currentProvider === "openrouter" && (
|
||||
<div>
|
||||
<label className="block font-medium mb-1">
|
||||
{t("settings:experimental.IMAGE_GENERATION.openRouterApiKeyLabel")}
|
||||
</label>
|
||||
<VSCodeTextField
|
||||
value={openRouterImageApiKey || ""}
|
||||
onInput={(e: any) => handleApiKeyChange(e.target.value)}
|
||||
placeholder={t("settings:experimental.IMAGE_GENERATION.openRouterApiKeyPlaceholder")}
|
||||
className="w-full"
|
||||
type="password"
|
||||
/>
|
||||
<p className="text-vscode-descriptionForeground text-xs mt-1">
|
||||
{t("settings:experimental.IMAGE_GENERATION.getApiKeyText")}{" "}
|
||||
<a
|
||||
href="https://openrouter.ai/keys"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground">
|
||||
openrouter.ai/keys
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Model Selection */}
|
||||
<div>
|
||||
<label className="block font-medium mb-1">
|
||||
{t("settings:experimental.IMAGE_GENERATION.modelSelectionLabel")}
|
||||
</label>
|
||||
<VSCodeDropdown
|
||||
value={selectedModel}
|
||||
value={currentModel}
|
||||
onChange={(e: any) => handleModelChange(e.target.value)}
|
||||
className="w-full">
|
||||
{IMAGE_GENERATION_MODELS.map((model) => (
|
||||
{availableModels.map((model) => (
|
||||
<VSCodeOption key={model.value} value={model.value} className="py-2 px-3">
|
||||
{model.label}
|
||||
</VSCodeOption>
|
||||
|
|
@ -105,13 +173,13 @@ export const ImageGenerationSettings = ({
|
|||
</div>
|
||||
|
||||
{/* Status Message */}
|
||||
{enabled && !apiKey && (
|
||||
{enabled && !isConfigured && (
|
||||
<div className="p-2 bg-vscode-editorWarning-background text-vscode-editorWarning-foreground rounded text-sm">
|
||||
{t("settings:experimental.IMAGE_GENERATION.warningMissingKey")}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{enabled && apiKey && (
|
||||
{enabled && isConfigured && (
|
||||
<div className="p-2 bg-vscode-editorInfo-background text-vscode-editorInfo-foreground rounded text-sm">
|
||||
{t("settings:experimental.IMAGE_GENERATION.successConfigured")}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import {
|
|||
type ExperimentId,
|
||||
type TelemetrySetting,
|
||||
DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
|
||||
ImageGenerationProvider,
|
||||
} from "@roo-code/types"
|
||||
|
||||
import { vscode } from "@src/utils/vscode"
|
||||
|
|
@ -198,6 +199,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
includeTaskHistoryInEnhance,
|
||||
imageGenerationProvider,
|
||||
openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel,
|
||||
reasoningBlockCollapsed,
|
||||
|
|
@ -289,6 +291,16 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
})
|
||||
}, [])
|
||||
|
||||
const setImageGenerationProvider = useCallback((provider: ImageGenerationProvider) => {
|
||||
setCachedState((prevState) => {
|
||||
if (prevState.imageGenerationProvider !== provider) {
|
||||
setChangeDetected(true)
|
||||
}
|
||||
|
||||
return { ...prevState, imageGenerationProvider: provider }
|
||||
})
|
||||
}, [])
|
||||
|
||||
const setOpenRouterImageApiKey = useCallback((apiKey: string) => {
|
||||
setCachedState((prevState) => {
|
||||
if (prevState.openRouterImageApiKey !== apiKey) {
|
||||
|
|
@ -398,6 +410,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
includeCurrentCost: includeCurrentCost ?? true,
|
||||
maxGitStatusFiles: maxGitStatusFiles ?? 0,
|
||||
profileThresholds,
|
||||
imageGenerationProvider,
|
||||
openRouterImageApiKey,
|
||||
openRouterImageGenerationSelectedModel,
|
||||
experiments,
|
||||
|
|
@ -816,10 +829,12 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
experiments={experiments}
|
||||
apiConfiguration={apiConfiguration}
|
||||
setApiConfigurationField={setApiConfigurationField}
|
||||
imageGenerationProvider={imageGenerationProvider}
|
||||
openRouterImageApiKey={openRouterImageApiKey as string | undefined}
|
||||
openRouterImageGenerationSelectedModel={
|
||||
openRouterImageGenerationSelectedModel as string | undefined
|
||||
}
|
||||
setImageGenerationProvider={setImageGenerationProvider}
|
||||
setOpenRouterImageApiKey={setOpenRouterImageApiKey}
|
||||
setImageGenerationSelectedModel={setImageGenerationSelectedModel}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ vi.mock("@/i18n/TranslationContext", () => ({
|
|||
}))
|
||||
|
||||
describe("ImageGenerationSettings", () => {
|
||||
const mockSetImageGenerationProvider = vi.fn()
|
||||
const mockSetOpenRouterImageApiKey = vi.fn()
|
||||
const mockSetImageGenerationSelectedModel = vi.fn()
|
||||
const mockOnChange = vi.fn()
|
||||
|
|
@ -17,8 +18,10 @@ describe("ImageGenerationSettings", () => {
|
|||
const defaultProps = {
|
||||
enabled: false,
|
||||
onChange: mockOnChange,
|
||||
imageGenerationProvider: undefined,
|
||||
openRouterImageApiKey: undefined,
|
||||
openRouterImageGenerationSelectedModel: undefined,
|
||||
setImageGenerationProvider: mockSetImageGenerationProvider,
|
||||
setOpenRouterImageApiKey: mockSetOpenRouterImageApiKey,
|
||||
setImageGenerationSelectedModel: mockSetImageGenerationSelectedModel,
|
||||
}
|
||||
|
|
@ -32,6 +35,7 @@ describe("ImageGenerationSettings", () => {
|
|||
render(<ImageGenerationSettings {...defaultProps} />)
|
||||
|
||||
// Should NOT call setter functions on initial mount to prevent dirty state
|
||||
expect(mockSetImageGenerationProvider).not.toHaveBeenCalled()
|
||||
expect(mockSetOpenRouterImageApiKey).not.toHaveBeenCalled()
|
||||
expect(mockSetImageGenerationSelectedModel).not.toHaveBeenCalled()
|
||||
})
|
||||
|
|
@ -46,6 +50,7 @@ describe("ImageGenerationSettings", () => {
|
|||
)
|
||||
|
||||
// Should NOT call setter functions on initial mount to prevent dirty state
|
||||
expect(mockSetImageGenerationProvider).not.toHaveBeenCalled()
|
||||
expect(mockSetOpenRouterImageApiKey).not.toHaveBeenCalled()
|
||||
expect(mockSetImageGenerationSelectedModel).not.toHaveBeenCalled()
|
||||
})
|
||||
|
|
@ -53,7 +58,10 @@ describe("ImageGenerationSettings", () => {
|
|||
|
||||
describe("User Interaction Behavior", () => {
|
||||
it("should call setimageGenerationSettings when user changes API key", async () => {
|
||||
const { getByPlaceholderText } = render(<ImageGenerationSettings {...defaultProps} enabled={true} />)
|
||||
// Set provider to "openrouter" so the API key field renders
|
||||
const { getByPlaceholderText } = render(
|
||||
<ImageGenerationSettings {...defaultProps} enabled={true} imageGenerationProvider="openrouter" />,
|
||||
)
|
||||
|
||||
const apiKeyInput = getByPlaceholderText(
|
||||
"settings:experimental.IMAGE_GENERATION.openRouterApiKeyPlaceholder",
|
||||
|
|
@ -71,14 +79,27 @@ describe("ImageGenerationSettings", () => {
|
|||
})
|
||||
|
||||
describe("Conditional Rendering", () => {
|
||||
it("should render input fields when enabled is true", () => {
|
||||
const { getByPlaceholderText } = render(<ImageGenerationSettings {...defaultProps} enabled={true} />)
|
||||
it("should render input fields when enabled is true and provider is openrouter", () => {
|
||||
// Set provider to "openrouter" so the API key field renders
|
||||
const { getByPlaceholderText } = render(
|
||||
<ImageGenerationSettings {...defaultProps} enabled={true} imageGenerationProvider="openrouter" />,
|
||||
)
|
||||
|
||||
expect(
|
||||
getByPlaceholderText("settings:experimental.IMAGE_GENERATION.openRouterApiKeyPlaceholder"),
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("should not render API key field when provider is roo", () => {
|
||||
const { queryByPlaceholderText } = render(
|
||||
<ImageGenerationSettings {...defaultProps} enabled={true} imageGenerationProvider="roo" />,
|
||||
)
|
||||
|
||||
expect(
|
||||
queryByPlaceholderText("settings:experimental.IMAGE_GENERATION.openRouterApiKeyPlaceholder"),
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("should not render input fields when enabled is false", () => {
|
||||
const { queryByPlaceholderText } = render(<ImageGenerationSettings {...defaultProps} enabled={false} />)
|
||||
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/ca/settings.json
generated
2
webview-ui/src/i18n/locales/ca/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"name": "Habilitar generació d'imatges amb IA",
|
||||
"providerLabel": "Proveïdor",
|
||||
"providerDescription": "Selecciona el proveïdor per a la generació d'imatges.",
|
||||
"description": "Quan estigui habilitat, Roo pot generar imatges a partir de prompts de text utilitzant els models de generació d'imatges d'OpenRouter. Requereix que es configuri una clau d'API d'OpenRouter.",
|
||||
"openRouterApiKeyLabel": "Clau API d'OpenRouter",
|
||||
"openRouterApiKeyPlaceholder": "Introdueix la teva clau API d'OpenRouter",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/de/settings.json
generated
4
webview-ui/src/i18n/locales/de/settings.json
generated
|
|
@ -773,7 +773,9 @@
|
|||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"name": "KI-Bildgenerierung aktivieren",
|
||||
"description": "Wenn aktiviert, kann Roo Bilder aus Textprompts mit OpenRouters Bildgenerierungsmodellen erstellen. Erfordert einen konfigurierten OpenRouter API-Schlüssel.",
|
||||
"description": "Wenn aktiviert, kann Roo Bilder aus Textprompts mit Bildgenerierungsmodellen erstellen.",
|
||||
"providerLabel": "Anbieter",
|
||||
"providerDescription": "Wähle den Anbieter für die Bildgenerierung.",
|
||||
"openRouterApiKeyLabel": "OpenRouter API-Schlüssel",
|
||||
"openRouterApiKeyPlaceholder": "Gib deinen OpenRouter API-Schlüssel ein",
|
||||
"getApiKeyText": "Hol dir deinen API-Schlüssel von",
|
||||
|
|
|
|||
|
|
@ -778,13 +778,15 @@
|
|||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"name": "Enable AI image generation",
|
||||
"description": "When enabled, Roo can generate images from text prompts using OpenRouter's image generation models. Requires an OpenRouter API key to be configured.",
|
||||
"description": "When enabled, Roo can generate images from text prompts using image generation models.",
|
||||
"providerLabel": "Provider",
|
||||
"providerDescription": "Select which provider to use for image generation.",
|
||||
"openRouterApiKeyLabel": "OpenRouter API Key",
|
||||
"openRouterApiKeyPlaceholder": "Enter your OpenRouter API key",
|
||||
"getApiKeyText": "Get your API key from",
|
||||
"modelSelectionLabel": "Image Generation Model",
|
||||
"modelSelectionDescription": "Select the model to use for image generation",
|
||||
"warningMissingKey": "⚠️ OpenRouter API key is required for image generation. Please configure it above.",
|
||||
"warningMissingKey": "⚠️ OpenRouter API key is required for OpenRouter image generation. Please configure it above.",
|
||||
"successConfigured": "✓ Image generation is configured and ready to use"
|
||||
},
|
||||
"RUN_SLASH_COMMAND": {
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/es/settings.json
generated
2
webview-ui/src/i18n/locales/es/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"name": "Habilitar generación de imágenes con IA",
|
||||
"providerLabel": "Proveedor",
|
||||
"providerDescription": "Selecciona el proveedor para la generación de imágenes.",
|
||||
"description": "Cuando esté habilitado, Roo puede generar imágenes a partir de prompts de texto usando los modelos de generación de imágenes de OpenRouter. Requiere que se configure una clave de API de OpenRouter.",
|
||||
"openRouterApiKeyLabel": "Clave API de OpenRouter",
|
||||
"openRouterApiKeyPlaceholder": "Introduce tu clave API de OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/fr/settings.json
generated
2
webview-ui/src/i18n/locales/fr/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"name": "Activer la génération d'images IA",
|
||||
"providerLabel": "Fournisseur",
|
||||
"providerDescription": "Sélectionnez le fournisseur pour la génération d'images.",
|
||||
"description": "Lorsqu'activé, Roo peut générer des images à partir de prompts textuels en utilisant les modèles de génération d'images d'OpenRouter. Nécessite qu'une clé API OpenRouter soit configurée.",
|
||||
"openRouterApiKeyLabel": "Clé API OpenRouter",
|
||||
"openRouterApiKeyPlaceholder": "Entrez votre clé API OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/hi/settings.json
generated
2
webview-ui/src/i18n/locales/hi/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "जब सक्षम किया जाता है, तो new_task टूल को todos पैरामीटर प्रदान करने की आवश्यकता होगी। यह सुनिश्चित करता है कि सभी नए कार्य स्पष्ट उद्देश्यों की सूची के साथ शुरू हों। जब अक्षम किया जाता है (डिफ़ॉल्ट), तो todos पैरामीटर पिछड़े संगतता के लिए वैकल्पिक रहता है।"
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "प्रदाता",
|
||||
"providerDescription": "छवि निर्माण के लिए प्रदाता चुनें।",
|
||||
"name": "AI छवि निर्माण सक्षम करें",
|
||||
"description": "जब सक्षम किया जाता है, तो Roo OpenRouter के छवि निर्माण मॉडल का उपयोग करके टेक्स्ट प्रॉम्प्ट से छवियां उत्पन्न कर सकता है। एक कॉन्फ़िगर किए गए OpenRouter API कुंजी की आवश्यकता होती है।",
|
||||
"openRouterApiKeyLabel": "OpenRouter API कुंजी",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/id/settings.json
generated
4
webview-ui/src/i18n/locales/id/settings.json
generated
|
|
@ -803,7 +803,9 @@
|
|||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"name": "Aktifkan pembuatan gambar AI",
|
||||
"description": "Ketika diaktifkan, Roo dapat menghasilkan gambar dari prompt teks menggunakan model pembuatan gambar OpenRouter. Memerlukan kunci API OpenRouter yang dikonfigurasi.",
|
||||
"description": "Ketika diaktifkan, Roo dapat menghasilkan gambar dari prompt teks menggunakan model pembuatan gambar.",
|
||||
"providerLabel": "Penyedia",
|
||||
"providerDescription": "Pilih penyedia untuk menghasilkan gambar.",
|
||||
"openRouterApiKeyLabel": "Kunci API OpenRouter",
|
||||
"openRouterApiKeyPlaceholder": "Masukkan kunci API OpenRouter Anda",
|
||||
"getApiKeyText": "Dapatkan kunci API Anda dari",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/it/settings.json
generated
2
webview-ui/src/i18n/locales/it/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Quando abilitato, lo strumento new_task richiederà la fornitura di un parametro todos. Ciò garantisce che tutte le nuove attività inizino con un elenco chiaro di obiettivi. Quando disabilitato (impostazione predefinita), il parametro todos rimane facoltativo per la compatibilità con le versioni precedenti."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Provider",
|
||||
"providerDescription": "Seleziona il provider per la generazione di immagini.",
|
||||
"name": "Abilita generazione immagini AI",
|
||||
"description": "Quando abilitato, Roo può generare immagini da prompt di testo utilizzando i modelli di generazione immagini di OpenRouter. Richiede una chiave API OpenRouter configurata.",
|
||||
"openRouterApiKeyLabel": "Chiave API OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/ja/settings.json
generated
2
webview-ui/src/i18n/locales/ja/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "有効にすると、new_taskツールはtodosパラメータの提供が必須になります。これにより、すべての新しいタスクが明確な目的のリストで開始されることが保証されます。無効(デフォルト)の場合、下位互換性のためにtodosパラメータはオプションのままです。"
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "プロバイダー",
|
||||
"providerDescription": "画像生成に使用するプロバイダーを選択",
|
||||
"name": "AI画像生成を有効にする",
|
||||
"description": "有効にすると、RooはOpenRouterの画像生成モデルを使用してテキストプロンプトから画像を生成できます。OpenRouter APIキーの設定が必要です。",
|
||||
"openRouterApiKeyLabel": "OpenRouter APIキー",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/ko/settings.json
generated
2
webview-ui/src/i18n/locales/ko/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "활성화하면 new_task 도구에 todos 매개변수를 제공해야 합니다. 이렇게 하면 모든 새 작업이 명확한 목표 목록으로 시작됩니다. 비활성화하면(기본값) 이전 버전과의 호환성을 위해 todos 매개변수는 선택 사항으로 유지됩니다."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "제공업체",
|
||||
"providerDescription": "이미지 생성에 사용할 제공업체를 선택하세요.",
|
||||
"name": "AI 이미지 생성 활성화",
|
||||
"description": "활성화하면 Roo는 OpenRouter의 이미지 생성 모델을 사용하여 텍스트 프롬프트에서 이미지를 생성할 수 있습니다. OpenRouter API 키 구성이 필요합니다.",
|
||||
"openRouterApiKeyLabel": "OpenRouter API 키",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/nl/settings.json
generated
2
webview-ui/src/i18n/locales/nl/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Wanneer ingeschakeld, vereist de new_task-tool dat een todos-parameter wordt opgegeven. Dit zorgt ervoor dat alle nieuwe taken beginnen met een duidelijke lijst met doelstellingen. Wanneer uitgeschakeld (standaard), blijft de todos-parameter optioneel voor achterwaartse compatibiliteit."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Provider",
|
||||
"providerDescription": "Selecteer de provider voor het genereren van afbeeldingen.",
|
||||
"name": "AI-afbeeldingsgeneratie inschakelen",
|
||||
"description": "Wanneer ingeschakeld, kan Roo afbeeldingen genereren van tekstprompts met behulp van OpenRouter's afbeeldingsgeneratiemodellen. Vereist een geconfigureerde OpenRouter API-sleutel.",
|
||||
"openRouterApiKeyLabel": "OpenRouter API-sleutel",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/pl/settings.json
generated
2
webview-ui/src/i18n/locales/pl/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Gdy włączone, narzędzie new_task będzie wymagało podania parametru todos. Zapewnia to, że wszystkie nowe zadania rozpoczynają się od jasnej listy celów. Gdy wyłączone (domyślnie), parametr todos pozostaje opcjonalny dla zachowania kompatybilności wstecznej."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Dostawca",
|
||||
"providerDescription": "Wybierz dostawcę do generowania obrazów.",
|
||||
"name": "Włącz generowanie obrazów AI",
|
||||
"description": "Gdy włączone, Roo może generować obrazy z promptów tekstowych używając modeli generowania obrazów OpenRouter. Wymaga skonfigurowanego klucza API OpenRouter.",
|
||||
"openRouterApiKeyLabel": "Klucz API OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/pt-BR/settings.json
generated
2
webview-ui/src/i18n/locales/pt-BR/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Quando ativado, a ferramenta new_task exigirá que um parâmetro todos seja fornecido. Isso garante que todas as novas tarefas comecem com uma lista clara de objetivos. Quando desativado (padrão), o parâmetro todos permanece opcional para compatibilidade com versões anteriores."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Provedor",
|
||||
"providerDescription": "Selecione o provedor para geração de imagens.",
|
||||
"name": "Habilitar geração de imagens com IA",
|
||||
"description": "Quando habilitado, Roo pode gerar imagens a partir de prompts de texto usando os modelos de geração de imagens do OpenRouter. Requer uma chave de API do OpenRouter configurada.",
|
||||
"openRouterApiKeyLabel": "Chave de API do OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/ru/settings.json
generated
2
webview-ui/src/i18n/locales/ru/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Если включено, инструмент new_task будет требовать предоставления параметра todos. Это гарантирует, что все новые задачи начинаются с четкого списка целей. Когда отключено (по умолчанию), параметр todos остается необязательным для обратной совместимости."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Провайдер",
|
||||
"providerDescription": "Выберите провайдера для генерации изображений.",
|
||||
"name": "Включить генерацию изображений ИИ",
|
||||
"description": "Когда включено, Roo может генерировать изображения из текстовых запросов, используя модели генерации изображений OpenRouter. Требует настроенный API-ключ OpenRouter.",
|
||||
"openRouterApiKeyLabel": "API-ключ OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/tr/settings.json
generated
2
webview-ui/src/i18n/locales/tr/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Etkinleştirildiğinde, new_task aracı bir todos parametresi sağlanmasını gerektirir. Bu, tüm yeni görevlerin net bir hedef listesiyle başlamasını sağlar. Devre dışı bırakıldığında (varsayılan), todos parametresi geriye dönük uyumluluk için isteğe bağlı kalır."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Sağlayıcı",
|
||||
"providerDescription": "Görüntü oluşturma için kullanılacak sağlayıcıyı seçin.",
|
||||
"name": "AI görüntü üretimini etkinleştir",
|
||||
"description": "Etkinleştirildiğinde, Roo OpenRouter'ın görüntü üretim modellerini kullanarak metin istemlerinden görüntüler üretebilir. Yapılandırılmış bir OpenRouter API anahtarı gerektirir.",
|
||||
"openRouterApiKeyLabel": "OpenRouter API Anahtarı",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/vi/settings.json
generated
2
webview-ui/src/i18n/locales/vi/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "Khi được bật, công cụ new_task sẽ yêu cầu cung cấp tham số todos. Điều này đảm bảo tất cả các nhiệm vụ mới bắt đầu với một danh sách mục tiêu rõ ràng. Khi bị tắt (mặc định), tham số todos vẫn là tùy chọn để tương thích ngược."
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "Nhà cung cấp",
|
||||
"providerDescription": "Chọn nhà cung cấp để tạo hình ảnh.",
|
||||
"name": "Bật tạo hình ảnh AI",
|
||||
"description": "Khi được bật, Roo có thể tạo hình ảnh từ lời nhắc văn bản bằng các mô hình tạo hình ảnh của OpenRouter. Yêu cầu khóa API OpenRouter được cấu hình.",
|
||||
"openRouterApiKeyLabel": "Khóa API OpenRouter",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/zh-CN/settings.json
generated
2
webview-ui/src/i18n/locales/zh-CN/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "启用后,new_task 工具将需要提供 todos 参数。这可以确保所有新任务都以明确的目标列表开始。禁用时(默认),todos 参数保持可选,以实现向后兼容。"
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "提供商",
|
||||
"providerDescription": "选择用于图像生成的提供商。",
|
||||
"name": "启用 AI 图像生成",
|
||||
"description": "启用后,Roo 可以使用 OpenRouter 的图像生成模型从文本提示生成图像。需要配置 OpenRouter API 密钥。",
|
||||
"openRouterApiKeyLabel": "OpenRouter API 密钥",
|
||||
|
|
|
|||
2
webview-ui/src/i18n/locales/zh-TW/settings.json
generated
2
webview-ui/src/i18n/locales/zh-TW/settings.json
generated
|
|
@ -773,6 +773,8 @@
|
|||
"description": "啟用後,new_task 工具將需要提供 todos 參數。這可以確保所有新工作都以明確的目標列表開始。停用時(預設),todos 參數保持可選,以實現向後相容。"
|
||||
},
|
||||
"IMAGE_GENERATION": {
|
||||
"providerLabel": "提供商",
|
||||
"providerDescription": "選擇用於圖像生成的提供商。",
|
||||
"name": "啟用 AI 圖像生成",
|
||||
"description": "啟用後,Roo 可以使用 OpenRouter 的圖像生成模型從文字提示生成圖像。需要設定 OpenRouter API 金鑰。",
|
||||
"openRouterApiKeyLabel": "OpenRouter API 金鑰",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue