@goodandready/dsh-image-gen 0.11.36 → 0.11.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -59,6 +59,36 @@ window.__ModuleLoader__.load({
59
59
  }
60
60
  return (k, def) => def || k
61
61
  }
62
+
63
+ async function fetchJson(path, options = {}) {
64
+ const { timeoutMs = 15000, signal, ...rest } = options
65
+ let timer = null
66
+ let sig = signal
67
+
68
+ if (!sig) {
69
+ if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function') {
70
+ sig = AbortSignal.timeout(timeoutMs)
71
+ } else if (typeof AbortController !== 'undefined') {
72
+ const ctrl = new AbortController()
73
+ timer = setTimeout(() => {
74
+ try { ctrl.abort(new Error('Request timeout')) } catch (_) {}
75
+ }, timeoutMs)
76
+ sig = ctrl.signal
77
+ }
78
+ } else if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.any === 'function') {
79
+ const timeoutSig = typeof AbortSignal.timeout === 'function' ? AbortSignal.timeout(timeoutMs) : null
80
+ if (timeoutSig) {
81
+ sig = AbortSignal.any([signal, timeoutSig])
82
+ }
83
+ }
84
+
85
+ try {
86
+ const res = await fetch(path, { ...rest, signal: sig })
87
+ return res
88
+ } finally {
89
+ if (timer) clearTimeout(timer)
90
+ }
91
+ }
62
92
  // -------------------------------------------------------------- CSS & Design System
63
93
  function ensureCss() {
64
94
  if (typeof document === 'undefined') return
@@ -172,7 +202,7 @@ window.__ModuleLoader__.load({
172
202
  .ig-studio-canvas{display:flex;flex-direction:column;gap:12px;padding:16px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:12px;align-items:center;justify-content:center;position:relative}
173
203
 
174
204
  /* Backward-compatibility alias styles for toolview */
175
- .fal_head{font-size:13px;font-weight:600;margin-bottom:8px;color:var(--dsw-alias-label-primary)}
205
+ .ig-card-head{font-size:13px;font-weight:600;margin-bottom:8px;color:var(--dsw-alias-label-primary)}
176
206
  .ig-prompt{font-size:13px;padding:8px 12px;background:var(--dsw-alias-bg-layer-2);border-radius:6px;border:1px solid var(--dsw-alias-border-l2);margin-bottom:8px;word-break:break-word}
177
207
  .ig-meta{font-size:11px;color:var(--dsw-alias-label-secondary);margin-top:6px}
178
208
  .ig-err{padding:10px;border-radius:6px;background:var(--dsw-alias-state-error-bg, color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent));color:var(--dsw-alias-state-error-primary);font-size:12px}
@@ -643,7 +673,7 @@ window.__ModuleLoader__.load({
643
673
  setLoading(true)
644
674
  setMsg(null)
645
675
  try {
646
- const res = await fetch('/api/dsh-image-gen/update', {
676
+ const res = await fetchJson('/api/dsh-image-gen/update', {
647
677
  headers: { accept: 'application/json' },
648
678
  cache: 'no-store',
649
679
  })
@@ -661,7 +691,7 @@ window.__ModuleLoader__.load({
661
691
  setUpdating(true)
662
692
  setMsg(null)
663
693
  try {
664
- const res = await fetch('/api/dsh-image-gen/update', {
694
+ const res = await fetchJson('/api/dsh-image-gen/update', {
665
695
  method: 'POST',
666
696
  headers: {
667
697
  'x-dsh-plugin-update': '1',
@@ -746,7 +776,7 @@ window.__ModuleLoader__.load({
746
776
  setTesting(true)
747
777
  setResult(null)
748
778
  try {
749
- const res = await fetch('/dsh-image-gen/diagnostics/test?provider=' + encodeURIComponent(props.provider || 'fal'))
779
+ const res = await fetchJson('/dsh-image-gen/diagnostics/test?provider=' + encodeURIComponent(props.provider || 'fal'))
750
780
  const data = await res.json()
751
781
  setResult(data)
752
782
  } catch (e) {
@@ -813,7 +843,7 @@ window.__ModuleLoader__.load({
813
843
 
814
844
  const loadHistory = () => {
815
845
  setLoading(true)
816
- fetch('/dsh-image-gen/history')
846
+ fetchJson('/dsh-image-gen/history')
817
847
  .then((r) => r.json())
818
848
  .then((data) => {
819
849
  setItems(Array.isArray(data) ? data : [])
@@ -1263,10 +1293,10 @@ window.__ModuleLoader__.load({
1263
1293
  react.createElement(
1264
1294
  'span',
1265
1295
  { className: qualityGateOn ? 'ig-badge ig-badge-ok' : 'ig-badge ig-badge-warn' },
1266
- qualityGateOn ? 'Gate Active' : 'Off'
1296
+ qualityGateOn ? t('stat.gateActive') : t('stat.gateOff')
1267
1297
  ),
1268
1298
  ' ',
1269
- react.createElement('span', { className: 'ig-badge ig-badge-ok' }, 'Guard ' + loopLimit)
1299
+ react.createElement('span', { className: 'ig-badge ig-badge-ok' }, (t('stat.guard') || '{n}').replace('{n}', loopLimit))
1270
1300
  ),
1271
1301
  react.createElement('div', { className: 'ig-stat-lbl' }, t('stat.safety_status'))
1272
1302
  ),
@@ -1279,10 +1309,10 @@ window.__ModuleLoader__.load({
1279
1309
  react.createElement(
1280
1310
  'span',
1281
1311
  { className: diskCacheOn ? 'ig-badge ig-badge-ok' : 'ig-badge ig-badge-warn' },
1282
- diskCacheOn ? 'Cache ON' : 'Off'
1312
+ diskCacheOn ? t('stat.cacheOn') : t('stat.cacheOff')
1283
1313
  ),
1284
1314
  ' ',
1285
- budgetText !== '0' ? '$' + budgetText : 'No limit'
1315
+ budgetText !== '0' ? '$' + budgetText : t('stat.noLimit')
1286
1316
  ),
1287
1317
  react.createElement('div', { className: 'ig-stat-lbl' }, t('stat.budget_cache'))
1288
1318
  )
@@ -1290,7 +1320,7 @@ window.__ModuleLoader__.load({
1290
1320
  // Tab Navigation
1291
1321
  react.createElement(
1292
1322
  'div',
1293
- { className: 'ig-tabs', role: 'tablist', 'aria-label': 'Settings Sections' },
1323
+ { className: 'ig-tabs', role: 'tablist', 'aria-label': t('label.settingsSections') },
1294
1324
  tabs.map((tab) =>
1295
1325
  react.createElement(
1296
1326
  'button',
@@ -1564,7 +1594,7 @@ window.__ModuleLoader__.load({
1564
1594
 
1565
1595
  const head = react.createElement(
1566
1596
  'div',
1567
- { className: 'fal_head' },
1597
+ { className: 'ig-card-head' },
1568
1598
  running ? '⏳ ' + t('card.generating') : failed ? '❌ ' + t('card.failed') : '🖼️ ' + t('card.image')
1569
1599
  )
1570
1600
 
@@ -2477,7 +2507,7 @@ window.__ModuleLoader__.load({
2477
2507
  return react.createElement(
2478
2508
  'div',
2479
2509
  { className: 'ig-page', style: { padding: '4px 0', gap: '10px' } },
2480
- react.createElement('div', { className: 'fal_head' }, '🌓 ' + (t('themePair.title') || 'Theme Pair Graphic')),
2510
+ react.createElement('div', { className: 'ig-card-head' }, '🌓 ' + (t('themePair.title') || 'Theme Pair Graphic')),
2481
2511
  args.prompt ? react.createElement('div', { className: 'ig-prompt' }, args.prompt) : null,
2482
2512
  react.createElement(
2483
2513
  'div',
@@ -2540,574 +2570,619 @@ window.__ModuleLoader__.load({
2540
2570
  }
2541
2571
  var ThemePairToolView = ThemePairView
2542
2572
  const en = {
2543
- 'settings.navLabel': 'Image Studio',
2544
- 'settings.title': 'Image Studio',
2545
- 'settings.description': 'AI Image generation, inpainting, variations, upscale & vectorization.',
2546
- 'settings.unavailable': 'Plugin settings are unavailable: the host settings namespace is not ready.',
2547
- 'settings.loading': 'Loading plugin settings…',
2548
- 'settings.unsaved': 'Unsaved changes',
2549
- 'settings.saving': 'Saving…',
2550
- 'settings.save': 'Save settings',
2551
- 'settings.discard': 'Discard changes',
2552
- 'settings.saveFailed': 'Failed to save settings. Please check credentials and try again.',
2553
- 'settings.readOnly': 'Settings are read-only in this context.',
2554
- 'settings.overridden': 'overridden',
2555
- 'settings.reset': 'Reset to default',
2556
- 'settings.invalidNumber': 'Please enter a valid number',
2557
- 'settings.collapse': 'Collapse',
2558
- 'settings.expand': 'Expand',
2559
- 'settings.credentialHint': 'API keys are stored in DSH Credentials (~/.dsh/.credentials.yaml) and never leaked in config files.',
2560
-
2561
- 'tab.general': 'General',
2562
- 'tab.provider': 'Provider',
2563
- 'tab.enhancer': 'Prompt & Styles',
2564
- 'tab.safety': 'Safety & Budget',
2565
- 'tab.cache': 'Cache & Storage',
2566
-
2567
- 'stat.active_provider': 'Active Provider',
2568
- 'stat.format_size': 'Default Specs',
2569
- 'stat.safety_status': 'Safety & Loop Guard',
2570
- 'stat.budget_cache': 'Budget & Cache',
2571
-
2572
- 'card.generating': 'Generating image…',
2573
- 'card.failed': 'Generation failed',
2574
- 'card.image': 'Image Studio Result',
2575
- 'card.unknownError': 'An unknown error occurred during generation.',
2576
- 'card.sizePrefix': 'Size',
2577
- 'card.seedPrefix': 'Seed',
2573
+ 'card.actionRemoveBg': 'Remove background',
2578
2574
  'card.actionReroll': 'Reroll image',
2579
2575
  'card.actionUpscale': 'Upscale image',
2580
- 'card.actionRemoveBg': 'Remove background',
2581
- 'card.inpaint': 'Inpaint',
2582
- 'inpaint.title': 'Inpainting Canvas (Paint white mask over region to edit)',
2583
- 'inpaint.brush_size': 'Size',
2584
- 'inpaint.brush': 'Brush',
2585
- 'inpaint.eraser': 'Eraser',
2586
- 'inpaint.invert': 'Invert Mask',
2587
- 'inpaint.clear': 'Clear Mask',
2588
- 'inpaint.undo': 'Undo',
2589
- 'inpaint.apply': 'Apply Inpaint',
2590
- 'inpaint.prompt_placeholder': 'Describe what to generate in the masked area...',
2591
- 'inpaint.copied': '✓ Instruction Copied!',
2592
- 'matrix.title': 'Style Matrix Benchmark (2×2)',
2593
- 'matrix.blind_on': 'Blind Mode Active',
2594
- 'matrix.blind_toggle': 'Reveal Styles',
2595
- 'matrix.use_style': 'Use Style',
2596
- 'matrix.copied': '✓ Selected!',
2597
- 'f.fallbackProviders': 'Fallback Providers Chain',
2598
- 'f.fallbackProvidersHint': 'Comma-separated list of fallback providers to cascade to on 429, 5xx, or quota limits (e.g. replicate, custom, gemini).',
2599
- 'p.fallbackProviders': 'replicate, custom, gemini',
2600
-
2601
- 'card.reroll': 'Reroll',
2602
- 'card.upscale': 'Upscale 2x/4x',
2603
- 'card.removeBg': 'Remove BG',
2604
2576
  'card.copyPrompt': 'Copy Prompt',
2577
+ 'card.desc': 'Configure multi-provider image generation, inpainting, upscale, and vectorization settings.',
2578
+ 'card.dirty': 'Unsaved changes',
2579
+ 'card.discard': 'Discard changes',
2580
+ 'card.draftPreview': 'Draft Preview',
2581
+ 'card.failed': 'Generation failed',
2582
+ 'card.generating': 'Generating image…',
2583
+ 'card.image': 'Image Studio Result',
2584
+ 'card.inpaint': 'Inpaint',
2585
+ 'card.nextRevision': 'Next revision',
2605
2586
  'card.origPrompt': 'Original Prompt',
2587
+ 'card.prevRevision': 'Previous revision',
2606
2588
  'card.remix': 'Remix',
2589
+ 'card.removeBg': 'Remove BG',
2590
+ 'card.rendering': 'Rendering…',
2591
+ 'card.reroll': 'Reroll',
2607
2592
  'card.responsiveTabs': 'Responsive viewports',
2608
- 'remix.drawer_title': 'Variations & Style Remix Workbench',
2609
- 'remix.creativity_label': 'Creativity / Denoising Strength',
2610
- 'remix.prompt_placeholder': 'Describe stylistic adjustments, new background, or variations...',
2611
- 'remix.subtle_btn': 'Subtle (0.25)',
2612
- 'remix.creative_btn': 'Creative (0.65)',
2613
- 'remix.copy_instruction': 'Copy Instruction',
2614
- 'remix.copied': '✓ Copied!',
2615
-
2616
- 'f.enabled': 'Master Switch',
2617
- 'f.enabledHint': 'Enable or disable image generation tools across the workspace.',
2618
- 'f.provider': 'Image Provider',
2619
- 'f.providerHint': 'Backend service used for image generation.',
2620
- 'f.inherit': 'Default / Inherit',
2621
- 'f.needFal': 'Requires FAL API key',
2622
- 'f.needCustom': 'Requires OpenAI-compatible endpoint',
2623
- 'f.needCodex': 'Built-in Codex subscription',
2624
- 'f.needGrok': 'Built-in Grok subscription',
2625
- 'f.needLocal': 'Local ComfyUI or A1111',
2626
- 'f.needSeedream': 'Requires SeaDream API key',
2627
- 'f.needGemini': 'Requires Google Gemini API key',
2628
- 'f.needReplicate': 'Requires Replicate API token',
2629
-
2630
- 'f.defaultSize': 'Default Aspect Ratio',
2631
- 'f.defaultSizeHint': 'Aspect ratio and resolution applied when image_size is omitted.',
2632
- 'f.defaultFormat': 'Output Format',
2633
- 'f.defaultFormatHint': 'Target file format (PNG, JPEG, or WEBP).',
2634
- 'f.deliverAs': 'Delivery Mode',
2635
- 'f.deliverAsHint': 'How images reach conversation: "link" (text LLM safe) or "image" (multimodal vision).',
2636
- 'f.outputDir': 'Output Directory',
2637
- 'f.outputDirHint': 'Directory path where generated images are saved on disk.',
2638
- 'p.outputDir': 'generated/images',
2639
- 'f.historyLimit': 'History Limit',
2640
- 'f.historyLimitHint': 'Maximum number of recent generation records kept in memory.',
2641
- 'f.toolsetProfile': 'Toolset Profile',
2642
- 'f.toolsetProfileHint': 'Select which tools to register into context: minimal (<= 3 core tools, saving ~8k prompt tokens), all (30 tools), or custom.',
2643
- 'f.toolsetDesign': 'Design Toolset',
2644
- 'f.toolsetDesignHint': 'Enable design tools: style_matrix, theme_pair, ui_asset, character_sheet, beautify_diagram, anchor.',
2645
- 'f.toolsetProcessing': 'Processing Toolset',
2646
- 'f.toolsetProcessingHint': 'Enable processing tools: remove_background, upscale, vectorize, convert, grid, smart_crop, asset_pack, replace_image_text.',
2647
- 'f.toolsetFrontend': 'Frontend Toolset',
2648
- 'f.toolsetFrontendHint': 'Enable frontend tools: extract_design_tokens, image_to_css_gradient, check_image_contrast, responsive_mockups.',
2649
- 'f.toolsetCreative': 'Creative Toolset',
2650
- 'f.toolsetCreativeHint': 'Enable creative tools: spritesheet, seamless_pattern, sketch_to_image, image_pack.',
2651
- 'p.historyLimit': '50',
2652
-
2653
- 'f.model': 'FAL Model ID',
2654
- 'f.modelHint': 'Target model on FAL endpoint (e.g. fal-ai/flux-2/klein/9b).',
2655
- 'p.model': 'fal-ai/flux-2/klein/9b',
2593
+ 'card.revisions': 'Revisions',
2594
+ 'card.save': 'Save changes',
2595
+ 'card.saving': 'Saving…',
2596
+ 'card.seedPrefix': 'Seed',
2597
+ 'card.sizePrefix': 'Size',
2598
+ 'card.title': 'AI Image Studio',
2599
+ 'card.unknownError': 'An unknown error occurred during generation.',
2600
+ 'card.upscale': 'Upscale 2x/4x',
2601
+ 'diagnostics.desc': 'Instantly check connection status and latency to the selected provider API.',
2602
+ 'diagnostics.ready': 'Ready',
2603
+ 'diagnostics.test': 'Test connection',
2604
+ 'diagnostics.testing': 'Testing…',
2605
+ 'diagnostics.title': 'Provider Connectivity Diagnostics',
2656
2606
  'f.apiKeyEnv': 'FAL Key Reference',
2657
2607
  'f.apiKeyEnvHint': 'Credential reference holding the FAL API key.',
2658
- 'p.apiKeyEnv': 'FAL_API_KEY',
2608
+ 'f.autoEnhancePrompt': 'Auto Enhance Prompt',
2609
+ 'f.autoEnhancePromptHint': 'Enrich prompts with photography, lighting, and composition quality tokens.',
2659
2610
  'f.baseURL': 'FAL Base URL',
2660
2611
  'f.baseURLHint': 'FAL queue service endpoint.',
2661
- 'p.baseURL': 'https://queue.fal.run',
2662
- 'f.pollIntervalMs': 'Poll Interval (ms)',
2663
- 'f.pollIntervalMsHint': 'Frequency of checking task progress on asynchronous queues.',
2664
- 'p.pollIntervalMs': '2000',
2665
- 'f.timeoutMs': 'Timeout (ms)',
2666
- 'f.timeoutMsHint': 'Maximum overall timeout before failing a generation request.',
2667
- 'p.timeoutMs': '180000',
2668
-
2612
+ 'f.cacheByPrompt': 'Cache by Prompt Only',
2613
+ 'f.cacheByPromptHint': 'Reuse existing result if the prompt has already been generated.',
2614
+ 'f.cacheBySeed': 'Cache by Seed + Prompt',
2615
+ 'f.cacheBySeedHint': 'Reuse existing result if the exact same seed and prompt are requested.',
2616
+ 'f.cacheTtlDays': 'Cache Retention (Legacy)',
2617
+ 'f.cacheTtlDaysHint': 'Legacy name for retention period in days.',
2618
+ 'f.comfyWorkflowJson': 'ComfyUI Workflow JSON',
2619
+ 'f.comfyWorkflowJsonHint': 'Custom ComfyUI API workflow graph (JSON) with {{prompt}} placeholders.',
2669
2620
  'f.customBaseURL': 'Custom API Base URL',
2670
2621
  'f.customBaseURLHint': 'OpenAI-compatible image endpoint root (e.g. https://api.openai.com/v1).',
2671
- 'p.customBaseURL': 'https://api.openai.com/v1',
2672
- 'f.customModel': 'Custom Model ID',
2673
- 'f.customModelHint': 'Model name sent to custom images endpoint.',
2674
- 'p.customModel': 'dall-e-3',
2675
2622
  'f.customKeyEnv': 'Custom Key Reference',
2676
2623
  'f.customKeyEnvHint': 'Credential reference holding the API key for custom endpoint.',
2677
- 'p.customKeyEnv': 'OPENAI_API_KEY',
2624
+ 'f.customModel': 'Custom Model ID',
2625
+ 'f.customModelHint': 'Model name sent to custom images endpoint.',
2678
2626
  'f.customSize': 'Custom Image Size',
2679
2627
  'f.customSizeHint': 'Fixed dimension sent to custom endpoint (e.g. 1024x1024).',
2680
- 'p.customSize': '1024x1024',
2681
-
2682
- 'f.replicateModel': 'Replicate Model ID',
2683
- 'f.replicateModelHint': 'Target model identifier on Replicate.',
2684
- 'p.replicateModel': 'black-forest-labs/flux-schnell',
2685
- 'f.replicateKeyEnv': 'Replicate Key Reference',
2686
- 'f.replicateKeyEnvHint': 'Credential reference holding the Replicate API token.',
2687
- 'p.replicateKeyEnv': 'REPLICATE_API_TOKEN',
2688
-
2689
- 'f.seedreamModel': 'SeaDream Model ID',
2690
- 'f.seedreamModelHint': 'ByteDance SeaDream model identifier.',
2691
- 'p.seedreamModel': 'seedream-4.0',
2692
- 'f.seedreamKeyEnv': 'SeaDream Key Reference',
2693
- 'f.seedreamKeyEnvHint': 'Credential reference holding the SeaDream API key.',
2694
- 'p.seedreamKeyEnv': 'SEEDREAM_API_KEY',
2695
- 'f.seedreamBaseURL': 'SeaDream Base URL',
2696
- 'f.seedreamBaseURLHint': 'SeaDream API endpoint URL (ByteDance/Volcengine Ark).',
2697
- 'p.seedreamBaseURL': 'https://api.bytedanceapi.com/v1',
2698
-
2699
- 'f.geminiModel': 'Gemini Model ID',
2700
- 'f.geminiModelHint': 'Google Gemini image generation model identifier.',
2701
- 'p.geminiModel': 'gemini-3.1-flash-image',
2628
+ 'f.dailyBudgetUsd': 'Daily Spend Budget ($ USD)',
2629
+ 'f.dailyBudgetUsdHint': 'Hard spending cap per day across all visual generation tools (0 = no limit).',
2630
+ 'f.defaultFormat': 'Output Format',
2631
+ 'f.defaultFormatHint': 'Target file format (PNG, JPEG, or WEBP).',
2632
+ 'f.defaultSize': 'Default Aspect Ratio',
2633
+ 'f.defaultSizeHint': 'Aspect ratio and resolution applied when image_size is omitted.',
2634
+ 'f.defaultStylePreset': 'Default Style Preset',
2635
+ 'f.defaultStylePresetHint': 'Default style preset applied to generations (e.g. cinematic, anime, photorealistic).',
2636
+ 'f.deliverAs': 'Delivery Mode',
2637
+ 'f.deliverAsHint': 'How images reach conversation: "link" (text LLM safe) or "image" (multimodal vision).',
2638
+ 'f.diskCache': 'Content-Addressed Disk Cache',
2639
+ 'f.diskCacheHint': 'Instant <50ms retrieval and zero API cost for repeated identical generations.',
2640
+ 'f.enableLlmEnhancer': 'Enable LLM Enhancer (Legacy)',
2641
+ 'f.enableLlmEnhancerHint': 'Legacy toggle for LLM prompt expansion.',
2642
+ 'f.enabled': 'Master Switch',
2643
+ 'f.enabledHint': 'Enable or disable image generation tools across the workspace.',
2644
+ 'f.enhanceBelowChars': 'Enhancement Threshold',
2645
+ 'f.enhanceBelowCharsHint': 'Prompts longer than this character count will skip expansion.',
2646
+ 'f.enhanceModel': 'Enhancement Model',
2647
+ 'f.enhanceModelHint': 'Dedicated LLM model used to expand prompts (empty = conversation model).',
2648
+ 'f.enhancePrompt': 'LLM Prompt Enhancer',
2649
+ 'f.enhancePromptHint': 'Expand concise prompts with rich artistic details before generation.',
2650
+ 'f.fallbackProviders': 'Fallback Providers Chain',
2651
+ 'f.fallbackProvidersHint': 'Comma-separated list of fallback providers to cascade to on 429, 5xx, or quota limits (e.g. replicate, custom, gemini).',
2702
2652
  'f.geminiKeyEnv': 'Gemini Key Reference',
2703
2653
  'f.geminiKeyEnvHint': 'Credential reference holding Google Gemini API key.',
2704
- 'p.geminiKeyEnv': 'GEMINI_API_KEY',
2705
-
2706
- 'f.localKind': 'Local Engine Architecture',
2707
- 'f.localKindHint': 'Select between ComfyUI API or Automatic1111 WebUI backend.',
2654
+ 'f.geminiModel': 'Gemini Model ID',
2655
+ 'f.geminiModelHint': 'Google Gemini image generation model identifier.',
2656
+ 'f.historyLimit': 'History Limit',
2657
+ 'f.historyLimitHint': 'Maximum number of recent generation records kept in memory.',
2658
+ 'f.inherit': 'Default / Inherit',
2659
+ 'f.localA1111Url': 'Local A1111 URL (Legacy)',
2660
+ 'f.localA1111UrlHint': 'Direct Automatic1111 endpoint URL.',
2708
2661
  'f.localBaseURL': 'Local Server URL',
2709
2662
  'f.localBaseURLHint': 'Server address (e.g. http://127.0.0.1:8188 for ComfyUI, http://127.0.0.1:7860 for A1111).',
2710
- 'p.localBaseURL': 'http://127.0.0.1:8188',
2711
- 'f.localModel': 'Local Model / Checkpoint',
2712
- 'f.localModelHint': 'Checkpoint name or ComfyUI workflow name.',
2713
- 'p.localModel': 'v1-5-pruned-emaonly.safetensors',
2714
- 'f.localSteps': 'Sampling Steps',
2715
- 'f.localStepsHint': 'Number of denoising sampling steps.',
2716
- 'p.localSteps': '20',
2717
2663
  'f.localCfg': 'CFG Scale',
2718
2664
  'f.localCfgHint': 'Classifier-free guidance scale.',
2719
- 'p.localCfg': '7',
2720
2665
  'f.localComfyUrl': 'Local ComfyUI URL (Legacy)',
2721
2666
  'f.localComfyUrlHint': 'Direct ComfyUI endpoint URL.',
2722
- 'p.localComfyUrl': 'http://127.0.0.1:8188',
2723
- 'f.localA1111Url': 'Local A1111 URL (Legacy)',
2724
- 'f.localA1111UrlHint': 'Direct Automatic1111 endpoint URL.',
2725
- 'p.localA1111Url': 'http://127.0.0.1:7860',
2726
- 'f.comfyWorkflowJson': 'ComfyUI Workflow JSON',
2727
- 'f.comfyWorkflowJsonHint': 'Custom ComfyUI API workflow graph (JSON) with {{prompt}} placeholders.',
2728
- 'p.comfyWorkflowJson': '{"3": {"class_type": "KSampler", ...}}',
2729
-
2730
- 'f.subscriptionQuality': 'Subscription Quality',
2731
- 'f.subscriptionQualityHint': 'Target quality profile when using Codex or Grok subscriptions.',
2732
-
2733
- 'f.autoEnhancePrompt': 'Auto Enhance Prompt',
2734
- 'f.autoEnhancePromptHint': 'Enrich prompts with photography, lighting, and composition quality tokens.',
2735
- 'f.defaultStylePreset': 'Default Style Preset',
2736
- 'f.defaultStylePresetHint': 'Default style preset applied to generations (e.g. cinematic, anime, photorealistic).',
2737
- 'p.defaultStylePreset': 'none',
2738
-
2739
- 'updater.title': 'Plugin Updates',
2740
- 'updater.check': 'Check updates',
2741
- 'updater.checking': 'Checking…',
2742
- 'updater.current': 'Current version',
2743
- 'updater.latest': 'Latest version',
2744
- 'updater.upToDate': 'Up to date',
2745
- 'updater.updateNow': 'Update to v{version}',
2746
- 'updater.updating': 'Updating…',
2747
- 'updater.success': 'Plugin updated successfully! Please restart DSH service.',
2748
- 'updater.failed': 'Update check failed: ',
2749
-
2750
- 'f.enhancePrompt': 'LLM Prompt Enhancer',
2751
- 'f.enhancePromptHint': 'Expand concise prompts with rich artistic details before generation.',
2752
- 'f.enableLlmEnhancer': 'Enable LLM Enhancer (Legacy)',
2753
- 'f.enableLlmEnhancerHint': 'Legacy toggle for LLM prompt expansion.',
2754
- 'f.enhanceModel': 'Enhancement Model',
2755
- 'f.enhanceModelHint': 'Dedicated LLM model used to expand prompts (empty = conversation model).',
2756
- 'p.enhanceModel': 'Leave empty for default chat model',
2757
- 'f.enhanceBelowChars': 'Enhancement Threshold',
2758
- 'f.enhanceBelowCharsHint': 'Prompts longer than this character count will skip expansion.',
2759
- 'p.enhanceBelowChars': '200',
2760
- 'f.stylePreset': 'Artistic Style Preset',
2761
- 'f.stylePresetHint': 'Automatic visual style suffix added to all generated prompts.',
2762
-
2763
- 'f.qualityGate': 'Silent Quality Gate',
2764
- 'f.qualityGateHint': 'Automatically inspects generated frames and silently re-rolls blank or broken outputs.',
2765
- 'f.dailyBudgetUsd': 'Daily Spend Budget ($ USD)',
2766
- 'f.dailyBudgetUsdHint': 'Hard spending cap per day across all visual generation tools (0 = no limit).',
2767
- 'p.dailyBudgetUsd': '0.00',
2667
+ 'f.localKind': 'Local Engine Architecture',
2668
+ 'f.localKindHint': 'Select between ComfyUI API or Automatic1111 WebUI backend.',
2669
+ 'f.localModel': 'Local Model / Checkpoint',
2670
+ 'f.localModelHint': 'Checkpoint name or ComfyUI workflow name.',
2671
+ 'f.localSteps': 'Sampling Steps',
2672
+ 'f.localStepsHint': 'Number of denoising sampling steps.',
2768
2673
  'f.loopGuardLimit': 'Session Loop Guard Limit',
2769
2674
  'f.loopGuardLimitHint': 'Maximum consecutive image generations allowed before requiring user input (0 = off).',
2770
- 'p.loopGuardLimit': '3',
2771
-
2772
- 'f.diskCache': 'Content-Addressed Disk Cache',
2773
- 'f.diskCacheHint': 'Instant <50ms retrieval and zero API cost for repeated identical generations.',
2774
- 'f.cacheBySeed': 'Cache by Seed + Prompt',
2775
- 'f.cacheBySeedHint': 'Reuse existing result if the exact same seed and prompt are requested.',
2776
- 'f.cacheByPrompt': 'Cache by Prompt Only',
2777
- 'f.cacheByPromptHint': 'Reuse existing result if the prompt has already been generated.',
2675
+ 'f.model': 'FAL Model ID',
2676
+ 'f.modelHint': 'Target model on FAL endpoint (e.g. fal-ai/flux-2/klein/9b).',
2677
+ 'f.needCodex': 'Built-in Codex subscription',
2678
+ 'f.needCustom': 'Requires OpenAI-compatible endpoint',
2679
+ 'f.needFal': 'Requires FAL API key',
2680
+ 'f.needGemini': 'Requires Google Gemini API key',
2681
+ 'f.needGrok': 'Built-in Grok subscription',
2682
+ 'f.needLocal': 'Local ComfyUI or A1111',
2683
+ 'f.needReplicate': 'Requires Replicate API token',
2684
+ 'f.needSeedream': 'Requires SeaDream API key',
2685
+ 'f.outputDir': 'Output Directory',
2686
+ 'f.outputDirHint': 'Directory path where generated images are saved on disk.',
2687
+ 'f.pollIntervalMs': 'Poll Interval (ms)',
2688
+ 'f.pollIntervalMsHint': 'Frequency of checking task progress on asynchronous queues.',
2689
+ 'f.provider': 'Image Provider',
2690
+ 'f.providerHint': 'Backend service used for image generation.',
2778
2691
  'f.pruneDays': 'Retention Period (Days)',
2779
2692
  'f.pruneDaysHint': 'Automatically delete image files and cache older than this many days (0 = keep forever).',
2780
- 'p.pruneDays': '0',
2781
- 'f.cacheTtlDays': 'Cache Retention (Legacy)',
2782
- 'f.cacheTtlDaysHint': 'Legacy name for retention period in days.',
2693
+ 'f.qualityGate': 'Silent Quality Gate',
2694
+ 'f.qualityGateHint': 'Automatically inspects generated frames and silently re-rolls blank or broken outputs.',
2695
+ 'f.replicateKeyEnv': 'Replicate Key Reference',
2696
+ 'f.replicateKeyEnvHint': 'Credential reference holding the Replicate API token.',
2697
+ 'f.replicateModel': 'Replicate Model ID',
2698
+ 'f.replicateModelHint': 'Target model identifier on Replicate.',
2699
+ 'f.seedreamBaseURL': 'SeaDream Base URL',
2700
+ 'f.seedreamBaseURLHint': 'SeaDream API endpoint URL (ByteDance/Volcengine Ark).',
2701
+ 'f.seedreamKeyEnv': 'SeaDream Key Reference',
2702
+ 'f.seedreamKeyEnvHint': 'Credential reference holding the SeaDream API key.',
2703
+ 'f.seedreamModel': 'SeaDream Model ID',
2704
+ 'f.seedreamModelHint': 'ByteDance SeaDream model identifier.',
2705
+ 'f.stylePreset': 'Artistic Style Preset',
2706
+ 'f.stylePresetHint': 'Automatic visual style suffix added to all generated prompts.',
2707
+ 'f.subscriptionQuality': 'Subscription Quality',
2708
+ 'f.subscriptionQualityHint': 'Target quality profile when using Codex or Grok subscriptions.',
2709
+ 'f.timeoutMs': 'Timeout (ms)',
2710
+ 'f.timeoutMsHint': 'Maximum overall timeout before failing a generation request.',
2711
+ 'f.toolsetCreative': 'Creative Toolset',
2712
+ 'f.toolsetCreativeHint': 'Enable creative tools: spritesheet, seamless_pattern, sketch_to_image, image_pack.',
2713
+ 'f.toolsetDesign': 'Design Toolset',
2714
+ 'f.toolsetDesignHint': 'Enable design tools: style_matrix, theme_pair, ui_asset, character_sheet, beautify_diagram, anchor.',
2715
+ 'f.toolsetFrontend': 'Frontend Toolset',
2716
+ 'f.toolsetFrontendHint': 'Enable frontend tools: extract_design_tokens, image_to_css_gradient, check_image_contrast, responsive_mockups.',
2717
+ 'f.toolsetProcessing': 'Processing Toolset',
2718
+ 'f.toolsetProcessingHint': 'Enable processing tools: remove_background, upscale, vectorize, convert, grid, smart_crop, asset_pack, replace_image_text.',
2719
+ 'f.toolsetProfile': 'Toolset Profile',
2720
+ 'f.toolsetProfileHint': 'Select which tools to register into context: minimal (<= 3 core tools, saving ~8k prompt tokens), all (30 tools), or custom.',
2721
+ 'gallery.copy_link': 'Copy Markdown Link',
2722
+ 'gallery.copy_prompt': 'Copy Prompt',
2723
+ 'gallery.empty': 'No generations yet. Generated images will appear here.',
2724
+ 'gallery.inspector': 'Generation Details',
2725
+ 'gallery.title': 'Recent Generations',
2726
+ 'inpaint.apply': 'Apply Inpaint',
2727
+ 'inpaint.brush': 'Brush',
2728
+ 'inpaint.brush_size': 'Size',
2729
+ 'inpaint.clear': 'Clear Mask',
2730
+ 'inpaint.copied': '✓ Instruction Copied!',
2731
+ 'inpaint.eraser': 'Eraser',
2732
+ 'inpaint.invert': 'Invert Mask',
2733
+ 'inpaint.prompt_placeholder': 'Describe what to generate in the masked area...',
2734
+ 'inpaint.title': 'Inpainting Canvas (Paint white mask over region to edit)',
2735
+ 'inpaint.undo': 'Undo',
2736
+ 'label.settingsSections': 'Settings Sections',
2737
+ 'matrix.blind_on': 'Blind Mode Active',
2738
+ 'matrix.blind_toggle': 'Reveal Styles',
2739
+ 'matrix.copied': '✓ Selected!',
2740
+ 'matrix.title': 'Style Matrix Benchmark (2×2)',
2741
+ 'matrix.use_style': 'Use Style',
2742
+ 'p.apiKeyEnv': 'FAL_API_KEY',
2743
+ 'p.baseURL': 'https://queue.fal.run',
2783
2744
  'p.cacheTtlDays': '0',
2784
-
2785
- 'studio.title': 'Image Studio',
2745
+ 'p.comfyWorkflowJson': '{"3": {"class_type": "KSampler", ...}}',
2746
+ 'p.customBaseURL': 'https://api.openai.com/v1',
2747
+ 'p.customKeyEnv': 'OPENAI_API_KEY',
2748
+ 'p.customModel': 'dall-e-3',
2749
+ 'p.customSize': '1024x1024',
2750
+ 'p.dailyBudgetUsd': '0.00',
2751
+ 'p.defaultStylePreset': 'none',
2752
+ 'p.enhanceBelowChars': '200',
2753
+ 'p.enhanceModel': 'Leave empty for default chat model',
2754
+ 'p.fallbackProviders': 'replicate, custom, gemini',
2755
+ 'p.geminiKeyEnv': 'GEMINI_API_KEY',
2756
+ 'p.geminiModel': 'gemini-3.1-flash-image',
2757
+ 'p.historyLimit': '50',
2758
+ 'p.localA1111Url': 'http://127.0.0.1:7860',
2759
+ 'p.localBaseURL': 'http://127.0.0.1:8188',
2760
+ 'p.localCfg': '7',
2761
+ 'p.localComfyUrl': 'http://127.0.0.1:8188',
2762
+ 'p.localModel': 'v1-5-pruned-emaonly.safetensors',
2763
+ 'p.localSteps': '20',
2764
+ 'p.loopGuardLimit': '3',
2765
+ 'p.model': 'fal-ai/flux-2/klein/9b',
2766
+ 'p.outputDir': 'generated/images',
2767
+ 'p.pollIntervalMs': '2000',
2768
+ 'p.pruneDays': '0',
2769
+ 'p.replicateKeyEnv': 'REPLICATE_API_TOKEN',
2770
+ 'p.replicateModel': 'black-forest-labs/flux-schnell',
2771
+ 'p.seedreamBaseURL': 'https://api.bytedanceapi.com/v1',
2772
+ 'p.seedreamKeyEnv': 'SEEDREAM_API_KEY',
2773
+ 'p.seedreamModel': 'seedream-4.0',
2774
+ 'p.timeoutMs': '180000',
2775
+ 'remix.copied': '✓ Copied!',
2776
+ 'remix.copy_instruction': 'Copy Instruction',
2777
+ 'remix.creative_btn': 'Creative (0.65)',
2778
+ 'remix.creativity_label': 'Creativity / Denoising Strength',
2779
+ 'remix.drawer_title': 'Variations & Style Remix Workbench',
2780
+ 'remix.prompt_placeholder': 'Describe stylistic adjustments, new background, or variations...',
2781
+ 'remix.subtle_btn': 'Subtle (0.25)',
2782
+ 'settings.collapse': 'Collapse',
2783
+ 'settings.credentialHint': 'API keys are stored in DSH Credentials (~/.dsh/.credentials.yaml) and never leaked in config files.',
2784
+ 'settings.description': 'AI Image generation, inpainting, variations, upscale & vectorization.',
2785
+ 'settings.discard': 'Discard changes',
2786
+ 'settings.expand': 'Expand',
2787
+ 'settings.invalidNumber': 'Please enter a valid number',
2788
+ 'settings.loading': 'Loading plugin settings…',
2789
+ 'settings.navLabel': 'Image Studio',
2790
+ 'settings.overridden': 'overridden',
2791
+ 'settings.readOnly': 'Settings are read-only in this context.',
2792
+ 'settings.reset': 'Reset to default',
2793
+ 'settings.save': 'Save settings',
2794
+ 'settings.saveFailed': 'Failed to save settings. Please check credentials and try again.',
2795
+ 'settings.saving': 'Saving…',
2796
+ 'settings.title': 'Image Studio',
2797
+ 'settings.unavailable': 'Plugin settings are unavailable: the host settings namespace is not ready.',
2798
+ 'settings.unsaved': 'Unsaved changes',
2799
+ 'stat.active_provider': 'Active Provider',
2800
+ 'stat.budget_cache': 'Budget & Cache',
2801
+ 'stat.cacheOff': 'Off',
2802
+ 'stat.cacheOn': 'Cache ON',
2803
+ 'stat.format_size': 'Default Specs',
2804
+ 'stat.gateActive': 'Gate Active',
2805
+ 'stat.gateOff': 'Off',
2806
+ 'stat.guard': 'Guard {n}',
2807
+ 'stat.noLimit': 'No limit',
2808
+ 'stat.safety_status': 'Safety & Loop Guard',
2809
+ 'studio.aspectRatio': 'Aspect Ratio:',
2786
2810
  'studio.canvas': 'Studio Canvas',
2787
- 'studio.vault': 'Asset Vault',
2788
- 'studio.parameters': 'Generation Parameters',
2811
+ 'studio.copiedCommand': 'Copied generation command to clipboard!',
2812
+ 'studio.copiedSnippet': 'Copied snippet to clipboard!',
2813
+ 'studio.copyHtml': 'Copy HTML',
2814
+ 'studio.copyMarkdown': 'Copy Markdown',
2815
+ 'studio.download': 'Download',
2816
+ 'studio.emptyCanvas': 'Select an image from the recent strip below or click Generate.',
2817
+ 'studio.exitFullscreen': 'Exit Fullscreen',
2818
+ 'studio.fullscreen': 'Fullscreen',
2789
2819
  'studio.generate': 'Generate in Chat',
2790
- 'studio.recent': 'Recent Generations',
2820
+ 'studio.parameters': 'Generation Parameters',
2791
2821
  'studio.prompt': 'Prompt:',
2792
2822
  'studio.promptPlaceholder': 'Describe your vision...',
2793
- 'studio.stylePreset': 'Style Preset:',
2794
- 'studio.aspectRatio': 'Aspect Ratio:',
2795
2823
  'studio.provider': 'Provider:',
2796
- 'studio.seed': 'Seed (optional):',
2797
2824
  'studio.random': 'Random',
2798
2825
  'studio.randomizeSeed': 'Randomize seed',
2799
- 'studio.fullscreen': 'Fullscreen',
2800
- 'studio.exitFullscreen': 'Exit Fullscreen',
2801
- 'studio.copyMarkdown': 'Copy Markdown',
2802
- 'studio.copyHtml': 'Copy HTML',
2803
- 'studio.download': 'Download',
2804
- 'studio.emptyCanvas': 'Select an image from the recent strip below or click Generate.',
2805
- 'studio.copiedCommand': 'Copied generation command to clipboard!',
2806
- 'studio.copiedSnippet': 'Copied snippet to clipboard!',
2807
-
2808
- 'vault.title': 'Asset Browser & Vault',
2809
- 'vault.search': 'Search prompt or tags...',
2810
- 'vault.loadMore': 'Load more assets',
2811
- 'vault.empty': 'No assets found in vault.',
2812
- 'vault.inspector': 'Asset Inspector',
2813
- 'vault.reroll': 'Re-roll with seed',
2814
- 'vault.insert': 'Insert in Chat',
2815
- 'vault.download': 'Download',
2816
- 'vault.delete': 'Delete',
2826
+ 'studio.recent': 'Recent Generations',
2827
+ 'studio.seed': 'Seed (optional):',
2828
+ 'studio.stylePreset': 'Style Preset:',
2829
+ 'studio.title': 'Image Studio',
2830
+ 'studio.vault': 'Asset Vault',
2831
+ 'subtitle': 'Multi-provider AI image generation, editing, upscale & vectorization.',
2832
+ 'tab.cache': 'Cache & Storage',
2833
+ 'tab.enhancer': 'Prompt & Styles',
2834
+ 'tab.gallery': 'Gallery',
2835
+ 'tab.general': 'General',
2836
+ 'tab.provider': 'Provider',
2837
+ 'tab.safety': 'Safety & Budget',
2838
+ 'themePair.copiedCss': 'Copied CSS!',
2839
+ 'themePair.copiedHtml': 'Copied HTML!',
2840
+ 'themePair.copyCss': 'Copy CSS',
2841
+ 'themePair.copyHtml': 'Copy HTML',
2842
+ 'themePair.dark': 'Dark',
2843
+ 'themePair.light': 'Light',
2844
+ 'themePair.title': 'Theme Pair Graphic',
2845
+ 'title': 'AI Image Studio',
2846
+ 'updater.check': 'Check updates',
2847
+ 'updater.checking': 'Checking…',
2848
+ 'updater.current': 'Current version',
2849
+ 'updater.failed': 'Update check failed: ',
2850
+ 'updater.latest': 'Latest version',
2851
+ 'updater.success': 'Plugin updated successfully! Please restart DSH service.',
2852
+ 'updater.title': 'Plugin Updates',
2853
+ 'updater.upToDate': 'Up to date',
2854
+ 'updater.updateNow': 'Update to v{version}',
2855
+ 'updater.updating': 'Updating…',
2817
2856
  'vault.allProviders': 'All Providers',
2818
2857
  'vault.allRatios': 'All Ratios',
2819
- 'vault.newest': 'Newest',
2820
- 'vault.oldest': 'Oldest',
2821
- 'vault.loading': 'Loading...',
2822
2858
  'vault.confirmDelete': 'Are you sure you want to delete this asset?',
2823
- 'vault.deleted': 'Asset deleted',
2824
- 'vault.deleteFailed': 'Failed to delete asset',
2825
2859
  'vault.copiedMarkdown': 'Markdown snippet copied to clipboard!',
2826
2860
  'vault.copiedPrompt': 'Prompt & seed copied to clipboard!',
2861
+ 'vault.delete': 'Delete',
2862
+ 'vault.deleteFailed': 'Failed to delete asset',
2863
+ 'vault.deleted': 'Asset deleted',
2864
+ 'vault.download': 'Download',
2865
+ 'vault.empty': 'No assets found in vault.',
2866
+ 'vault.insert': 'Insert in Chat',
2867
+ 'vault.inspector': 'Asset Inspector',
2868
+ 'vault.loadMore': 'Load more assets',
2869
+ 'vault.loading': 'Loading...',
2870
+ 'vault.newest': 'Newest',
2827
2871
  'vault.noPrompt': 'No prompt',
2828
- 'vault.seed': 'Seed',
2872
+ 'vault.oldest': 'Oldest',
2829
2873
  'vault.provider': 'Provider',
2874
+ 'vault.reroll': 'Re-roll with seed',
2875
+ 'vault.search': 'Search prompt or tags...',
2876
+ 'vault.seed': 'Seed',
2877
+ 'vault.title': 'Asset Browser & Vault',
2830
2878
  }
2831
-
2832
2879
  const zh = {
2833
- 'tab.general': '常规',
2834
- 'tab.provider': '提供商',
2835
- 'tab.gallery': '图库',
2836
- 'tab.enhancer': '提示词增强',
2837
- 'tab.safety': '安全与预算',
2838
- 'tab.cache': '缓存与性能',
2839
-
2840
- 'diagnostics.title': '提供商连接诊断',
2841
- 'diagnostics.desc': '即时检查与所选生成服务 API 的连接状态和延迟。',
2842
- 'diagnostics.test': '测试连接',
2843
- 'diagnostics.testing': '测试中...',
2844
- 'diagnostics.ready': '正常',
2845
-
2846
- 'gallery.title': '最近生成记录',
2847
- 'gallery.empty': '暂无生成记录。生成一张图片后将显示在此处。',
2848
- 'gallery.inspector': '生成记录详情',
2849
- 'gallery.copy_prompt': '复制提示词',
2850
- 'gallery.copy_link': '复制 Markdown 链接',
2851
-
2852
- 'title': 'AI 图像工坊',
2853
- 'subtitle': '多提供商支持的图像生成、编辑、局部重绘与矢量化。',
2854
- 'card.title': 'AI 图像工坊',
2880
+ 'card.actionRemoveBg': '移除背景',
2881
+ 'card.actionReroll': '重新生成图像',
2882
+ 'card.actionUpscale': '放大图像',
2883
+ 'card.copyPrompt': '复制提示词',
2855
2884
  'card.desc': '配置多提供商图像生成、局部重绘、放大及矢量化设置。',
2856
2885
  'card.dirty': '有未保存的修改',
2857
- 'card.saving': '保存中...',
2858
- 'card.save': '保存修改',
2859
2886
  'card.discard': '放弃修改',
2887
+ 'card.draftPreview': '草稿预览',
2860
2888
  'card.failed': '保存失败,请检查填写内容。',
2861
- 'card.actionReroll': '重新生成图像',
2862
- 'card.actionUpscale': '放大图像',
2863
- 'card.actionRemoveBg': '移除背景',
2889
+ 'card.generating': '正在生成图片…',
2890
+ 'card.image': 'AI 图像工坊生成结果',
2864
2891
  'card.inpaint': '局部重绘',
2865
- 'inpaint.title': '画布局部重绘(涂抹白色蒙版标记区域)',
2866
- 'inpaint.brush_size': '大小',
2867
- 'inpaint.brush': '画笔',
2868
- 'inpaint.eraser': '橡皮擦',
2869
- 'inpaint.invert': '反转蒙版',
2870
- 'inpaint.clear': '清空蒙版',
2871
- 'inpaint.undo': '撤销',
2872
- 'inpaint.apply': '生成局部重绘',
2873
- 'inpaint.prompt_placeholder': '描述在涂抹区域生成的内容...',
2874
- 'inpaint.copied': '✓ 已复制重绘指令!',
2875
- 'matrix.title': '2×2 风格探索矩阵',
2876
- 'matrix.blind_on': '盲测模式进行中',
2877
- 'matrix.blind_toggle': '显示风格标签',
2878
- 'matrix.use_style': '使用此风格',
2879
- 'matrix.copied': '✓ 风格已选定!',
2880
- 'f.fallbackProviders': '备用提供商级联',
2881
- 'f.fallbackProvidersHint': '当主提供商遇到 429 限流、5xx 故障或余额不足时依次自动切换的备用服务商列表(如 replicate, custom, gemini)。',
2882
- 'p.fallbackProviders': 'replicate, custom, gemini',
2883
-
2884
- 'card.reroll': '重绘',
2885
- 'card.upscale': '放大 2x/4x',
2886
- 'card.removeBg': '抠图背景',
2887
- 'card.copyPrompt': '复制提示词',
2892
+ 'card.nextRevision': '下一版本',
2888
2893
  'card.origPrompt': '原始提示词',
2894
+ 'card.prevRevision': '上一版本',
2889
2895
  'card.remix': '重混变体',
2896
+ 'card.removeBg': '抠图背景',
2897
+ 'card.rendering': '渲染中…',
2898
+ 'card.reroll': '重绘',
2890
2899
  'card.responsiveTabs': '响应式视口',
2891
- 'remix.drawer_title': '变体与风格重混工作台',
2892
- 'remix.creativity_label': '创意度 / 去噪强度',
2893
- 'remix.prompt_placeholder': '描述风格调整、新背景或变体细节...',
2894
- 'remix.subtle_btn': '微调 (0.25)',
2895
- 'remix.creative_btn': '强创意 (0.65)',
2896
- 'remix.copy_instruction': '复制指令',
2897
- 'remix.copied': '✓ 已复制!',
2898
-
2899
- 'settings.overridden': '已自定义',
2900
- 'settings.reset': '重置',
2901
- 'settings.invalidNumber': '请输入有效数值',
2902
- 'settings.unavailable': '设置命名空间当前不可用。',
2903
- 'settings.loading': '正在加载插件设置…',
2904
-
2905
- 'f.enabled': '启用图像生成',
2906
- 'f.enabledHint': '关闭后将禁用所有图像生成及处理工具。',
2907
- 'f.provider': '默认图像提供商',
2908
- 'f.providerHint': '用于图像生成的默认引擎(fal, custom, replicate, seedream, gemini, local, codex, grok)。',
2909
- 'f.defaultSize': '默认图像尺寸',
2910
- 'f.defaultSizeHint': '未指定尺寸时的默认生成分辨率。',
2911
- 'f.defaultFormat': '输出格式',
2912
- 'f.defaultFormatHint': '生成图像的默认文件格式(png 或 webp)。',
2913
- 'f.deliverAs': '输出投递方式',
2914
- 'f.deliverAsHint': 'link 模式仅返回链接;image 模式同时返回图像自身数据。',
2915
- 'f.outputDir': '存储目录',
2916
- 'f.outputDirHint': '已生成图像在会话工作空间内的保存目录。',
2917
- 'p.outputDir': 'generated/images',
2918
- 'f.historyLimit': '历史记录数量',
2919
- 'f.historyLimitHint': '保存在内存历史列表中的最大条目数。',
2920
- 'f.toolsetProfile': '工具集配置档',
2921
- 'f.toolsetProfileHint': '选择注册到对话上下文的工具集:minimal(<= 3个核心工具,节省~8k提示词tokens),all(所有30个工具),或custom。',
2922
- 'f.toolsetDesign': '设计工具集',
2923
- 'f.toolsetDesignHint': '启用设计工具:style_matrix, theme_pair, ui_asset, character_sheet, beautify_diagram, anchor。',
2924
- 'f.toolsetProcessing': '图像处理工具集',
2925
- 'f.toolsetProcessingHint': '启用处理工具:remove_background, upscale, vectorize, convert, grid, smart_crop, asset_pack, replace_image_text。',
2926
- 'f.toolsetFrontend': '前端工具集',
2927
- 'f.toolsetFrontendHint': '启用前端工具:extract_design_tokens, image_to_css_gradient, check_image_contrast, responsive_mockups。',
2928
- 'f.toolsetCreative': '创意工具集',
2929
- 'f.toolsetCreativeHint': '启用创意工具:spritesheet, seamless_pattern, sketch_to_image, image_pack。',
2930
- 'p.historyLimit': '50',
2931
-
2932
- 'f.model': 'FAL 模型 ID',
2933
- 'f.modelHint': '调用的 FAL 队列模型标识符。',
2934
- 'p.model': 'fal-ai/flux-2/klein/9b',
2900
+ 'card.revisions': '历史版本',
2901
+ 'card.save': '保存修改',
2902
+ 'card.saving': '保存中...',
2903
+ 'card.seedPrefix': '随机种子',
2904
+ 'card.sizePrefix': '尺寸',
2905
+ 'card.title': 'AI 图像工坊',
2906
+ 'card.unknownError': '生成过程中发生未知错误。',
2907
+ 'card.upscale': '放大 2x/4x',
2908
+ 'diagnostics.desc': '即时检查与所选生成服务 API 的连接状态和延迟。',
2909
+ 'diagnostics.ready': '正常',
2910
+ 'diagnostics.test': '测试连接',
2911
+ 'diagnostics.testing': '测试中...',
2912
+ 'diagnostics.title': '提供商连接诊断',
2935
2913
  'f.apiKeyEnv': 'FAL 凭证名称',
2936
2914
  'f.apiKeyEnvHint': '存储 FAL API 密钥的环境变量或凭证名称。',
2937
- 'p.apiKeyEnv': 'FAL_API_KEY',
2915
+ 'f.autoEnhancePrompt': '智能自动增强提示词',
2916
+ 'f.autoEnhancePromptHint': '自动为提示词补充最佳摄影、光影与构图词汇。',
2938
2917
  'f.baseURL': 'FAL 基础地址',
2939
2918
  'f.baseURLHint': 'FAL 队列服务基础 URL。',
2940
- 'p.baseURL': 'https://queue.fal.run',
2941
- 'f.pollIntervalMs': '轮询间隔(毫秒)',
2942
- 'f.pollIntervalMsHint': '异步队列状态检查的时间间隔。',
2943
- 'p.pollIntervalMs': '2000',
2944
- 'f.timeoutMs': '超时上限(毫秒)',
2945
- 'f.timeoutMsHint': '单次生成作业的总执行时限。',
2946
- 'p.timeoutMs': '180000',
2947
-
2919
+ 'f.cacheByPrompt': '按提示词命中缓存',
2920
+ 'f.cacheByPromptHint': '当提示词文本一致时直接命中缓存。',
2921
+ 'f.cacheBySeed': '按 Seed 与提示词命中缓存',
2922
+ 'f.cacheBySeedHint': '当 Seed 和提示词均完全一致时直接命中缓存。',
2923
+ 'f.cacheTtlDays': '缓存生命周期 (Legacy)',
2924
+ 'f.cacheTtlDaysHint': '已废弃的缓存保留时长参数。',
2925
+ 'f.comfyWorkflowJson': 'ComfyUI 工作流 JSON',
2926
+ 'f.comfyWorkflowJsonHint': '包含 {{prompt}} 等占位符的自定义 ComfyUI API 工作流 JSON。',
2948
2927
  'f.customBaseURL': 'Custom API 地址',
2949
2928
  'f.customBaseURLHint': '兼容 OpenAI 图像接口的基础地址。',
2950
- 'p.customBaseURL': 'https://api.openai.com/v1',
2951
- 'f.customModel': 'Custom 模型 ID',
2952
- 'f.customModelHint': '自定义接口的模型标识符。',
2953
- 'p.customModel': 'gpt-image-1',
2954
2929
  'f.customKeyEnv': 'Custom 凭证名称',
2955
2930
  'f.customKeyEnvHint': '存储自定义接口 API 密钥的凭证名称。',
2956
- 'p.customKeyEnv': 'OPENAI_API_KEY',
2931
+ 'f.customModel': 'Custom 模型 ID',
2932
+ 'f.customModelHint': '自定义接口的模型标识符。',
2957
2933
  'f.customSize': 'Custom 固定尺寸',
2958
2934
  'f.customSizeHint': '发送至自定义接口的指定分辨率(如 1024x1024)。',
2959
- 'p.customSize': '1024x1024',
2960
-
2961
- 'f.replicateModel': 'Replicate 模型 ID',
2962
- 'f.replicateModelHint': 'Replicate 平台上的目标模型。',
2963
- 'p.replicateModel': 'black-forest-labs/flux-schnell',
2964
- 'f.replicateKeyEnv': 'Replicate 凭证名称',
2965
- 'f.replicateKeyEnvHint': '存储 Replicate API Token 的凭证名称。',
2966
- 'p.replicateKeyEnv': 'REPLICATE_API_TOKEN',
2967
-
2968
- 'f.seedreamModel': 'SeaDream 模型 ID',
2969
- 'f.seedreamModelHint': '字节跳动 SeaDream 图像模型标识符。',
2970
- 'p.seedreamModel': 'seedream-4.0',
2971
- 'f.seedreamKeyEnv': 'SeaDream 凭证名称',
2972
- 'f.seedreamKeyEnvHint': '存储 SeaDream 接口密钥的凭证名称。',
2973
- 'p.seedreamKeyEnv': 'SEEDREAM_API_KEY',
2974
- 'f.seedreamBaseURL': 'SeaDream 接口地址',
2975
- 'f.seedreamBaseURLHint': 'SeaDream API 基础地址(火山引擎 Ark)。',
2976
- 'p.seedreamBaseURL': 'https://api.bytedanceapi.com/v1',
2977
-
2978
- 'f.geminiModel': 'Gemini 模型 ID',
2979
- 'f.geminiModelHint': 'Google Gemini 图像生成模型标识符。',
2980
- 'p.geminiModel': 'gemini-3.1-flash-image',
2935
+ 'f.dailyBudgetUsd': '每日开销预算 ($ USD)',
2936
+ 'f.dailyBudgetUsdHint': '所有图像工具每 24 小时的支出预算上限(0 为不限制)。',
2937
+ 'f.defaultFormat': '输出格式',
2938
+ 'f.defaultFormatHint': '生成图像的默认文件格式(png 或 webp)。',
2939
+ 'f.defaultSize': '默认图像尺寸',
2940
+ 'f.defaultSizeHint': '未指定尺寸时的默认生成分辨率。',
2941
+ 'f.defaultStylePreset': '默认风格预设',
2942
+ 'f.defaultStylePresetHint': '生成图像时应用的默认艺术或摄影风格(如 cinematic, anime 等)。',
2943
+ 'f.deliverAs': '输出投递方式',
2944
+ 'f.deliverAsHint': 'link 模式仅返回链接;image 模式同时返回图像自身数据。',
2945
+ 'f.diskCache': '按内容哈希的磁盘缓存',
2946
+ 'f.diskCacheHint': '重复生成完全相同的请求时实现毫秒级瞬间返回与零支出。',
2947
+ 'f.enableLlmEnhancer': '启用 LLM 提示词增强 (Legacy)',
2948
+ 'f.enableLlmEnhancerHint': '提示词扩展的历史遗留开关。',
2949
+ 'f.enabled': '启用图像生成',
2950
+ 'f.enabledHint': '关闭后将禁用所有图像生成及处理工具。',
2951
+ 'f.enhanceBelowChars': '扩展长度阈值',
2952
+ 'f.enhanceBelowCharsHint': '长于此字数的提示词将直接生成,不予额外扩展。',
2953
+ 'f.enhanceModel': '增强模型',
2954
+ 'f.enhanceModelHint': '用于扩展提示词的独立大语言模型(留空使用会话模型)。',
2955
+ 'f.enhancePrompt': 'LLM 提示词扩展',
2956
+ 'f.enhancePromptHint': '在生成前由会话模型自动丰富短提示词细节。',
2957
+ 'f.fallbackProviders': '备用提供商级联',
2958
+ 'f.fallbackProvidersHint': '当主提供商遇到 429 限流、5xx 故障或余额不足时依次自动切换的备用服务商列表(如 replicate, custom, gemini)。',
2981
2959
  'f.geminiKeyEnv': 'Gemini 凭证名称',
2982
- 'f.geminiKeyEnvHint': '存储 Google Gemini 密钥的凭证名称。',
2983
- 'p.geminiKeyEnv': 'GEMINI_API_KEY',
2984
-
2985
- 'f.localKind': '本地引擎架构',
2986
- 'f.localKindHint': '在 ComfyUI API 或 Automatic1111 WebUI 架构间选择。',
2960
+ 'f.geminiKeyEnvHint': '存储 Google Gemini 密钥的凭证名称。',
2961
+ 'f.geminiModel': 'Gemini 模型 ID',
2962
+ 'f.geminiModelHint': 'Google Gemini 图像生成模型标识符。',
2963
+ 'f.historyLimit': '历史记录数量',
2964
+ 'f.historyLimitHint': '保存在内存历史列表中的最大条目数。',
2965
+ 'f.inherit': '默认 / 继承',
2966
+ 'f.localA1111Url': '本地 A1111 地址 (Legacy)',
2967
+ 'f.localA1111UrlHint': '直接指向 Automatic1111 的服务地址。',
2987
2968
  'f.localBaseURL': '本地服务地址',
2988
2969
  'f.localBaseURLHint': '服务网络地址(如 http://127.0.0.1:8188)。',
2989
- 'p.localBaseURL': 'http://127.0.0.1:8188',
2990
- 'f.localModel': '本地模型 / Checkpoint',
2991
- 'f.localModelHint': '本地模型文件名或 ComfyUI 工作流名称。',
2992
- 'p.localModel': 'v1-5-pruned-emaonly.safetensors',
2993
- 'f.localSteps': '采样步数',
2994
- 'f.localStepsHint': '去噪采样的计算步数。',
2995
- 'p.localSteps': '20',
2996
2970
  'f.localCfg': 'CFG Scale',
2997
2971
  'f.localCfgHint': '无分类器引导系数。',
2998
- 'p.localCfg': '7',
2999
2972
  'f.localComfyUrl': '本地 ComfyUI 地址 (Legacy)',
3000
2973
  'f.localComfyUrlHint': '直接指向 ComfyUI 的服务地址。',
3001
- 'p.localComfyUrl': 'http://127.0.0.1:8188',
3002
- 'f.localA1111Url': '本地 A1111 地址 (Legacy)',
3003
- 'f.localA1111UrlHint': '直接指向 Automatic1111 的服务地址。',
3004
- 'p.localA1111Url': 'http://127.0.0.1:7860',
3005
- 'f.comfyWorkflowJson': 'ComfyUI 工作流 JSON',
3006
- 'f.comfyWorkflowJsonHint': '包含 {{prompt}} 等占位符的自定义 ComfyUI API 工作流 JSON。',
3007
- 'p.comfyWorkflowJson': '{"3": {"class_type": "KSampler", ...}}',
3008
-
2974
+ 'f.localKind': '本地引擎架构',
2975
+ 'f.localKindHint': '在 ComfyUI API 或 Automatic1111 WebUI 架构间选择。',
2976
+ 'f.localModel': '本地模型 / Checkpoint',
2977
+ 'f.localModelHint': '本地模型文件名或 ComfyUI 工作流名称。',
2978
+ 'f.localSteps': '采样步数',
2979
+ 'f.localStepsHint': '去噪采样的计算步数。',
2980
+ 'f.loopGuardLimit': '防死循环守卫 (Loop Guard)',
2981
+ 'f.loopGuardLimitHint': '无需用户交互的连续生成操作上限(0 为禁用)。',
2982
+ 'f.model': 'FAL 模型 ID',
2983
+ 'f.modelHint': '调用的 FAL 队列模型标识符。',
2984
+ 'f.needCodex': '内置 Codex 订阅',
2985
+ 'f.needCustom': '需要兼容 OpenAI 的端点',
2986
+ 'f.needFal': '需要 FAL API 密钥',
2987
+ 'f.needGemini': '需要 Google Gemini API 密钥',
2988
+ 'f.needGrok': '内置 Grok 订阅',
2989
+ 'f.needLocal': '本地 ComfyUI 或 A1111',
2990
+ 'f.needReplicate': '需要 Replicate API 令牌',
2991
+ 'f.needSeedream': '需要 SeaDream API 密钥',
2992
+ 'f.outputDir': '存储目录',
2993
+ 'f.outputDirHint': '已生成图像在会话工作空间内的保存目录。',
2994
+ 'f.pollIntervalMs': '轮询间隔(毫秒)',
2995
+ 'f.pollIntervalMsHint': '异步队列状态检查的时间间隔。',
2996
+ 'f.provider': '默认图像提供商',
2997
+ 'f.providerHint': '用于图像生成的默认引擎(fal, custom, replicate, seedream, gemini, local, codex, grok)。',
2998
+ 'f.pruneDays': '文件保留天数',
2999
+ 'f.pruneDaysHint': '自动清理超过该天数的已生成图像(0 表示永久保留)。',
3000
+ 'f.qualityGate': '静默质量门禁',
3001
+ 'f.qualityGateHint': '自动检测破损或空白输出,并在后台静默重新生成。',
3002
+ 'f.replicateKeyEnv': 'Replicate 凭证名称',
3003
+ 'f.replicateKeyEnvHint': '存储 Replicate API Token 的凭证名称。',
3004
+ 'f.replicateModel': 'Replicate 模型 ID',
3005
+ 'f.replicateModelHint': 'Replicate 平台上的目标模型。',
3006
+ 'f.seedreamBaseURL': 'SeaDream 接口地址',
3007
+ 'f.seedreamBaseURLHint': 'SeaDream API 基础地址(火山引擎 Ark)。',
3008
+ 'f.seedreamKeyEnv': 'SeaDream 凭证名称',
3009
+ 'f.seedreamKeyEnvHint': '存储 SeaDream 接口密钥的凭证名称。',
3010
+ 'f.seedreamModel': 'SeaDream 模型 ID',
3011
+ 'f.seedreamModelHint': '字节跳动 SeaDream 图像模型标识符。',
3012
+ 'f.stylePreset': '艺术风格后缀',
3013
+ 'f.stylePresetHint': '自动追加到所有生成提示词末尾的风格后缀。',
3009
3014
  'f.subscriptionQuality': '订阅质量',
3010
3015
  'f.subscriptionQualityHint': 'Codex 或 Grok 订阅通道的质量档位。',
3011
-
3012
- 'f.autoEnhancePrompt': '智能自动增强提示词',
3013
- 'f.autoEnhancePromptHint': '自动为提示词补充最佳摄影、光影与构图词汇。',
3014
- 'f.defaultStylePreset': '默认风格预设',
3015
- 'f.defaultStylePresetHint': '生成图像时应用的默认艺术或摄影风格(如 cinematic, anime 等)。',
3016
+ 'f.timeoutMs': '超时上限(毫秒)',
3017
+ 'f.timeoutMsHint': '单次生成作业的总执行时限。',
3018
+ 'f.toolsetCreative': '创意工具集',
3019
+ 'f.toolsetCreativeHint': '启用创意工具:spritesheet, seamless_pattern, sketch_to_image, image_pack。',
3020
+ 'f.toolsetDesign': '设计工具集',
3021
+ 'f.toolsetDesignHint': '启用设计工具:style_matrix, theme_pair, ui_asset, character_sheet, beautify_diagram, anchor。',
3022
+ 'f.toolsetFrontend': '前端工具集',
3023
+ 'f.toolsetFrontendHint': '启用前端工具:extract_design_tokens, image_to_css_gradient, check_image_contrast, responsive_mockups。',
3024
+ 'f.toolsetProcessing': '图像处理工具集',
3025
+ 'f.toolsetProcessingHint': '启用处理工具:remove_background, upscale, vectorize, convert, grid, smart_crop, asset_pack, replace_image_text。',
3026
+ 'f.toolsetProfile': '工具集配置档',
3027
+ 'f.toolsetProfileHint': '选择注册到对话上下文的工具集:minimal(<= 3个核心工具,节省~8k提示词tokens),all(所有30个工具),或custom。',
3028
+ 'gallery.copy_link': '复制 Markdown 链接',
3029
+ 'gallery.copy_prompt': '复制提示词',
3030
+ 'gallery.empty': '暂无生成记录。生成一张图片后将显示在此处。',
3031
+ 'gallery.inspector': '生成记录详情',
3032
+ 'gallery.title': '最近生成记录',
3033
+ 'inpaint.apply': '生成局部重绘',
3034
+ 'inpaint.brush': '画笔',
3035
+ 'inpaint.brush_size': '大小',
3036
+ 'inpaint.clear': '清空蒙版',
3037
+ 'inpaint.copied': '✓ 已复制重绘指令!',
3038
+ 'inpaint.eraser': '橡皮擦',
3039
+ 'inpaint.invert': '反转蒙版',
3040
+ 'inpaint.prompt_placeholder': '描述在涂抹区域生成的内容...',
3041
+ 'inpaint.title': '画布局部重绘(涂抹白色蒙版标记区域)',
3042
+ 'inpaint.undo': '撤销',
3043
+ 'label.settingsSections': '设置分区',
3044
+ 'matrix.blind_on': '盲测模式进行中',
3045
+ 'matrix.blind_toggle': '显示风格标签',
3046
+ 'matrix.copied': '✓ 风格已选定!',
3047
+ 'matrix.title': '2×2 风格探索矩阵',
3048
+ 'matrix.use_style': '使用此风格',
3049
+ 'p.apiKeyEnv': 'FAL_API_KEY',
3050
+ 'p.baseURL': 'https://queue.fal.run',
3051
+ 'p.cacheTtlDays': '0',
3052
+ 'p.comfyWorkflowJson': '{"3": {"class_type": "KSampler", ...}}',
3053
+ 'p.customBaseURL': 'https://api.openai.com/v1',
3054
+ 'p.customKeyEnv': 'OPENAI_API_KEY',
3055
+ 'p.customModel': 'gpt-image-1',
3056
+ 'p.customSize': '1024x1024',
3057
+ 'p.dailyBudgetUsd': '0.00',
3016
3058
  'p.defaultStylePreset': 'none',
3017
-
3018
- 'updater.title': '插件更新',
3019
- 'updater.check': '检查更新',
3020
- 'updater.checking': '正在检查…',
3021
- 'updater.current': '当前版本',
3022
- 'updater.latest': '最新版本',
3023
- 'updater.upToDate': '已是最新',
3024
- 'updater.updateNow': '一键更新至 v{version}',
3025
- 'updater.updating': '正在更新…',
3026
- 'updater.success': '插件更新成功!请重启 DSH 服务以生效。',
3027
- 'updater.failed': '更新检查失败:',
3028
- 'f.enhancePrompt': 'LLM 提示词扩展',
3029
- 'f.enhancePromptHint': '在生成前由会话模型自动丰富短提示词细节。',
3030
- 'f.enableLlmEnhancer': '启用 LLM 提示词增强 (Legacy)',
3031
- 'f.enableLlmEnhancerHint': '提示词扩展的历史遗留开关。',
3032
- 'f.enhanceModel': '增强模型',
3033
- 'f.enhanceModelHint': '用于扩展提示词的独立大语言模型(留空使用会话模型)。',
3034
- 'p.enhanceModel': '留空表示使用当前会话模型',
3035
- 'f.enhanceBelowChars': '扩展长度阈值',
3036
- 'f.enhanceBelowCharsHint': '长于此字数的提示词将直接生成,不予额外扩展。',
3037
3059
  'p.enhanceBelowChars': '200',
3038
- 'f.stylePreset': '艺术风格后缀',
3039
- 'f.stylePresetHint': '自动追加到所有生成提示词末尾的风格后缀。',
3040
-
3041
- 'f.qualityGate': '静默质量门禁',
3042
- 'f.qualityGateHint': '自动检测破损或空白输出,并在后台静默重新生成。',
3043
- 'f.dailyBudgetUsd': '每日开销预算 ($ USD)',
3044
- 'f.dailyBudgetUsdHint': '所有图像工具每 24 小时的支出预算上限(0 为不限制)。',
3045
- 'p.dailyBudgetUsd': '0.00',
3046
- 'f.loopGuardLimit': '防死循环守卫 (Loop Guard)',
3047
- 'f.loopGuardLimitHint': '无需用户交互的连续生成操作上限(0 为禁用)。',
3060
+ 'p.enhanceModel': '留空表示使用当前会话模型',
3061
+ 'p.fallbackProviders': 'replicate, custom, gemini',
3062
+ 'p.geminiKeyEnv': 'GEMINI_API_KEY',
3063
+ 'p.geminiModel': 'gemini-3.1-flash-image',
3064
+ 'p.historyLimit': '50',
3065
+ 'p.localA1111Url': 'http://127.0.0.1:7860',
3066
+ 'p.localBaseURL': 'http://127.0.0.1:8188',
3067
+ 'p.localCfg': '7',
3068
+ 'p.localComfyUrl': 'http://127.0.0.1:8188',
3069
+ 'p.localModel': 'v1-5-pruned-emaonly.safetensors',
3070
+ 'p.localSteps': '20',
3048
3071
  'p.loopGuardLimit': '3',
3049
-
3050
- 'f.diskCache': '按内容哈希的磁盘缓存',
3051
- 'f.diskCacheHint': '重复生成完全相同的请求时实现毫秒级瞬间返回与零支出。',
3052
- 'f.cacheBySeed': '按 Seed 与提示词命中缓存',
3053
- 'f.cacheBySeedHint': '当 Seed 和提示词均完全一致时直接命中缓存。',
3054
- 'f.cacheByPrompt': '按提示词命中缓存',
3055
- 'f.cacheByPromptHint': '当提示词文本一致时直接命中缓存。',
3056
- 'f.pruneDays': '文件保留天数',
3057
- 'f.pruneDaysHint': '自动清理超过该天数的已生成图像(0 表示永久保留)。',
3072
+ 'p.model': 'fal-ai/flux-2/klein/9b',
3073
+ 'p.outputDir': 'generated/images',
3074
+ 'p.pollIntervalMs': '2000',
3058
3075
  'p.pruneDays': '0',
3059
- 'f.cacheTtlDays': '缓存生命周期 (Legacy)',
3060
- 'f.cacheTtlDaysHint': '已废弃的缓存保留时长参数。',
3061
- 'p.cacheTtlDays': '0',
3062
-
3063
- 'studio.title': '图像创作工作台',
3076
+ 'p.replicateKeyEnv': 'REPLICATE_API_TOKEN',
3077
+ 'p.replicateModel': 'black-forest-labs/flux-schnell',
3078
+ 'p.seedreamBaseURL': 'https://api.bytedanceapi.com/v1',
3079
+ 'p.seedreamKeyEnv': 'SEEDREAM_API_KEY',
3080
+ 'p.seedreamModel': 'seedream-4.0',
3081
+ 'p.timeoutMs': '180000',
3082
+ 'remix.copied': '✓ 已复制!',
3083
+ 'remix.copy_instruction': '复制指令',
3084
+ 'remix.creative_btn': '强创意 (0.65)',
3085
+ 'remix.creativity_label': '创意度 / 去噪强度',
3086
+ 'remix.drawer_title': '变体与风格重混工作台',
3087
+ 'remix.prompt_placeholder': '描述风格调整、新背景或变体细节...',
3088
+ 'remix.subtle_btn': '微调 (0.25)',
3089
+ 'settings.collapse': '折叠',
3090
+ 'settings.credentialHint': 'API 密钥存储在 DSH Credentials (~/.dsh/.credentials.yaml) 中,绝不会泄露在配置文件中。',
3091
+ 'settings.description': '多提供商 AI 图像生成、局部重绘、变体、放大及矢量化。',
3092
+ 'settings.discard': '放弃修改',
3093
+ 'settings.expand': '展开',
3094
+ 'settings.invalidNumber': '请输入有效数值',
3095
+ 'settings.loading': '正在加载插件设置…',
3096
+ 'settings.navLabel': 'AI 图像工坊',
3097
+ 'settings.overridden': '已自定义',
3098
+ 'settings.readOnly': '在此上下文中设置只读。',
3099
+ 'settings.reset': '重置',
3100
+ 'settings.save': '保存设置',
3101
+ 'settings.saveFailed': '保存设置失败。请检查凭据后重试。',
3102
+ 'settings.saving': '保存中…',
3103
+ 'settings.title': 'AI 图像工坊',
3104
+ 'settings.unavailable': '设置命名空间当前不可用。',
3105
+ 'settings.unsaved': '未保存的修改',
3106
+ 'stat.active_provider': '当前提供商',
3107
+ 'stat.budget_cache': '预算与缓存',
3108
+ 'stat.cacheOff': '关闭',
3109
+ 'stat.cacheOn': '缓存已开启',
3110
+ 'stat.format_size': '默认规格',
3111
+ 'stat.gateActive': '门禁已启用',
3112
+ 'stat.gateOff': '关闭',
3113
+ 'stat.guard': '防护 {n}',
3114
+ 'stat.noLimit': '无限制',
3115
+ 'stat.safety_status': '安全与防循环保护',
3116
+ 'studio.aspectRatio': '宽高比:',
3064
3117
  'studio.canvas': '创作画布',
3065
- 'studio.vault': '素材资产库',
3066
- 'studio.parameters': '生成参数配置',
3118
+ 'studio.copiedCommand': '已将生成指令复制到剪贴板!',
3119
+ 'studio.copiedSnippet': '代码片段已复制到剪贴板!',
3120
+ 'studio.copyHtml': '复制 HTML',
3121
+ 'studio.copyMarkdown': '复制 Markdown',
3122
+ 'studio.download': '下载图像',
3123
+ 'studio.emptyCanvas': '从下方最近生成列表中选择图像,或点击生成。',
3124
+ 'studio.exitFullscreen': '退出全屏',
3125
+ 'studio.fullscreen': '全屏',
3067
3126
  'studio.generate': '在对话中生成',
3068
- 'studio.recent': '最近生成历史',
3127
+ 'studio.parameters': '生成参数配置',
3069
3128
  'studio.prompt': '提示词:',
3070
3129
  'studio.promptPlaceholder': '描述你想创作的画面...',
3071
- 'studio.stylePreset': '风格预设:',
3072
- 'studio.aspectRatio': '宽高比:',
3073
3130
  'studio.provider': '生成引擎:',
3074
- 'studio.seed': '随机种子 (可选):',
3075
3131
  'studio.random': '随机',
3076
3132
  'studio.randomizeSeed': '随机生成种子',
3077
- 'studio.fullscreen': '全屏',
3078
- 'studio.exitFullscreen': '退出全屏',
3079
- 'studio.copyMarkdown': '复制 Markdown',
3080
- 'studio.copyHtml': '复制 HTML',
3081
- 'studio.download': '下载图像',
3082
- 'studio.emptyCanvas': '从下方最近生成列表中选择图像,或点击生成。',
3083
- 'studio.copiedCommand': '已将生成指令复制到剪贴板!',
3084
- 'studio.copiedSnippet': '代码片段已复制到剪贴板!',
3085
-
3086
- 'vault.title': '图像素材库与浏览器',
3087
- 'vault.search': '搜索提示词或标签...',
3088
- 'vault.loadMore': '加载更多素材',
3089
- 'vault.empty': '素材库中暂无图像。',
3090
- 'vault.inspector': '素材检查器',
3091
- 'vault.reroll': '使用此种子重新生成',
3092
- 'vault.insert': '插入到当前对话',
3093
- 'vault.download': '下载图像',
3094
- 'vault.delete': '删除',
3133
+ 'studio.recent': '最近生成历史',
3134
+ 'studio.seed': '随机种子 (可选):',
3135
+ 'studio.stylePreset': '风格预设:',
3136
+ 'studio.title': '图像创作工作台',
3137
+ 'studio.vault': '素材资产库',
3138
+ 'subtitle': '多提供商支持的图像生成、编辑、局部重绘与矢量化。',
3139
+ 'tab.cache': '缓存与性能',
3140
+ 'tab.enhancer': '提示词增强',
3141
+ 'tab.gallery': '图库',
3142
+ 'tab.general': '常规',
3143
+ 'tab.provider': '提供商',
3144
+ 'tab.safety': '安全与预算',
3145
+ 'themePair.copiedCss': '已复制 CSS!',
3146
+ 'themePair.copiedHtml': '已复制 HTML!',
3147
+ 'themePair.copyCss': '复制 CSS',
3148
+ 'themePair.copyHtml': '复制 HTML',
3149
+ 'themePair.dark': '深色模式',
3150
+ 'themePair.light': '浅色模式',
3151
+ 'themePair.title': '主题双色图形',
3152
+ 'title': 'AI 图像工坊',
3153
+ 'updater.check': '检查更新',
3154
+ 'updater.checking': '正在检查…',
3155
+ 'updater.current': '当前版本',
3156
+ 'updater.failed': '更新检查失败:',
3157
+ 'updater.latest': '最新版本',
3158
+ 'updater.success': '插件更新成功!请重启 DSH 服务以生效。',
3159
+ 'updater.title': '插件更新',
3160
+ 'updater.upToDate': '已是最新',
3161
+ 'updater.updateNow': '一键更新至 v{version}',
3162
+ 'updater.updating': '正在更新…',
3095
3163
  'vault.allProviders': '所有引擎',
3096
3164
  'vault.allRatios': '所有比例',
3097
- 'vault.newest': '最新',
3098
- 'vault.oldest': '最早',
3099
- 'vault.loading': '加载中...',
3100
3165
  'vault.confirmDelete': '确定要删除此素材吗?',
3101
- 'vault.deleted': '素材已删除',
3102
- 'vault.deleteFailed': '删除素材失败',
3103
3166
  'vault.copiedMarkdown': 'Markdown 片段已复制到剪贴板!',
3104
3167
  'vault.copiedPrompt': '提示词与种子已复制到剪贴板!',
3168
+ 'vault.delete': '删除',
3169
+ 'vault.deleteFailed': '删除素材失败',
3170
+ 'vault.deleted': '素材已删除',
3171
+ 'vault.download': '下载图像',
3172
+ 'vault.empty': '素材库中暂无图像。',
3173
+ 'vault.insert': '插入到当前对话',
3174
+ 'vault.inspector': '素材检查器',
3175
+ 'vault.loadMore': '加载更多素材',
3176
+ 'vault.loading': '加载中...',
3177
+ 'vault.newest': '最新',
3105
3178
  'vault.noPrompt': '无提示词',
3106
- 'vault.seed': '种子',
3179
+ 'vault.oldest': '最早',
3107
3180
  'vault.provider': '引擎',
3181
+ 'vault.reroll': '使用此种子重新生成',
3182
+ 'vault.search': '搜索提示词或标签...',
3183
+ 'vault.seed': '种子',
3184
+ 'vault.title': '图像素材库与浏览器',
3108
3185
  }
3109
-
3110
- // -------------------------------------------------------------- Registration & Apply
3111
3186
  // Dual compatibility with DSH 0.1.5-rc.3 (settingsScope) and 0.1.6+ (configForms) (#291, #295)
3112
3187
  const inject = ['slots', 'locale', 'sessions']
3113
3188
 
@@ -3134,7 +3209,7 @@ window.__ModuleLoader__.load({
3134
3209
 
3135
3210
  const syncHttpConfig = () => {
3136
3211
  if (typeof fetch !== 'function') return
3137
- fetch('/dsh-image-gen/config', { cache: 'no-store' })
3212
+ fetchJson('/dsh-image-gen/config', { cache: 'no-store' })
3138
3213
  .then((r) => r.json())
3139
3214
  .then((data) => {
3140
3215
  if (data && data.ok && data.config) {
@@ -3194,7 +3269,7 @@ window.__ModuleLoader__.load({
3194
3269
  httpSnapshot = { ...httpSnapshot, value: { ...httpSnapshot.value, [key]: val } }
3195
3270
  notify()
3196
3271
  try {
3197
- const res = await fetch('/dsh-image-gen/config', {
3272
+ const res = await fetchJson('/dsh-image-gen/config', {
3198
3273
  method: 'PUT',
3199
3274
  headers: { 'Content-Type': 'application/json' },
3200
3275
  body: JSON.stringify({ [key]: val }),
@@ -3239,7 +3314,7 @@ window.__ModuleLoader__.load({
3239
3314
  httpSnapshot = { ...httpSnapshot, value: nextVal }
3240
3315
  notify()
3241
3316
  try {
3242
- const res = await fetch('/dsh-image-gen/config', {
3317
+ const res = await fetchJson('/dsh-image-gen/config', {
3243
3318
  method: 'PUT',
3244
3319
  headers: { 'Content-Type': 'application/json' },
3245
3320
  body: JSON.stringify({ resetFields: [key] }),
@@ -3512,7 +3587,7 @@ window.__ModuleLoader__.load({
3512
3587
  offset: String(newOffset),
3513
3588
  limit: '24',
3514
3589
  })
3515
- fetch('/dsh-image-gen/vault?' + params.toString())
3590
+ fetchJson('/dsh-image-gen/vault?' + params.toString())
3516
3591
  .then((r) => r.json())
3517
3592
  .then((data) => {
3518
3593
  setLoading(false)
@@ -3531,7 +3606,7 @@ window.__ModuleLoader__.load({
3531
3606
 
3532
3607
  const handleDelete = (id) => {
3533
3608
  if (!window.confirm(t('vault.confirmDelete') || 'Are you sure you want to delete this asset?')) return
3534
- fetch('/dsh-image-gen/vault?id=' + encodeURIComponent(id), { method: 'DELETE' })
3609
+ fetchJson('/dsh-image-gen/vault?id=' + encodeURIComponent(id), { method: 'DELETE' })
3535
3610
  .then((r) => r.json())
3536
3611
  .then((res) => {
3537
3612
  if (res.ok) {
@@ -3747,7 +3822,7 @@ window.__ModuleLoader__.load({
3747
3822
  ]
3748
3823
 
3749
3824
  const refreshRecent = () => {
3750
- fetch('/dsh-image-gen/vault?limit=12')
3825
+ fetchJson('/dsh-image-gen/vault?limit=12')
3751
3826
  .then((r) => r.json())
3752
3827
  .then((data) => {
3753
3828
  if (data && data.ok && Array.isArray(data.items)) {