diff --git a/Assets/assistent.js b/Assets/assistent.js index d8574ae..8612e43 100644 --- a/Assets/assistent.js +++ b/Assets/assistent.js @@ -1,6 +1,6 @@ /** * Swarm Assistent — Krea 2 collaborative chat (Ollama via Swarm API). - * v0.7.1: Exact KV memory; block SwarmUI ViewSpecial/model-card previews from Generate+vision. + * v0.7.2: Slim Exact in prompt; no Exact blob in live ctx; tighter preview filter; critique requires vision+JSON. */ (function () { const LS_BASE = 'swarm_assistent_base_url'; @@ -1681,10 +1681,10 @@ }; } - ctx.exact = state.exact || state.config?.exact || null; ctx.session_exact = state.sessionExact && Object.keys(state.sessionExact).length ? { ...state.sessionExact } : {}; + // Exact KV is already in the system prompt — do not duplicate the full blob into live context. return ctx; } @@ -2088,6 +2088,9 @@ if (!t.trim()) { return null; } + if (/\b(поправь|исправь|перепиши|улучши|fix\s+it|make\s+it\s+better|rewrite)\b/i.test(t)) { + return 'write_prompt'; + } if (/\b(опиши\s+реф|опиши\s+изображ|prompt\s+from\s+image|describe\s+(this|the|ref|image)|reverse\s*prompt)\b/i.test(t) || /опиши\s+(этот|эту|картинк|референс)/i.test(t)) { return 'describe_ref'; @@ -2846,17 +2849,14 @@ if (!s) { return false; } - // SwarmUI checkpoint/LoRA cards: ViewSpecial/*, View/Models/*, *.preview.*, PLACEHOLDER. - if (s.includes('.preview.') + // Only SwarmUI checkpoint/LoRA card routes — not bare "/models/" (matches Civitai page URLs). + return s.includes('.preview.') || s.includes('placeholder') || s.includes('/viewspecial/') || s.includes('viewspecial/') - || s.includes('/models/') - || s.includes('view/models/') - || /[?&](?:path|file)=[^&]*\.preview\./i.test(s)) { - return true; - } - return false; + || s.includes('/view/models/') + || /\/view\/models\//.test(s) + || /[?&](?:path|file)=[^&]*\.preview\./i.test(s); } function findCurrentGenerateSrc({ allowPreview = false } = {}) { diff --git a/AssistentConfig.cs b/AssistentConfig.cs index 138e903..b2a71f9 100644 --- a/AssistentConfig.cs +++ b/AssistentConfig.cs @@ -315,6 +315,46 @@ public sealed class AssistentConfig return def; } + /// Exact KV for the system prompt: params tables only (facts stay short / in RAG). + public JObject LoadExactForPrompt(string personaId) + { + JObject full = LoadExact(personaId); + if (full is null || full.Count == 0) + { + return full ?? new JObject(); + } + JObject slim = new(); + foreach (string key in new[] { "generation", "profiles", "aspect_table" }) + { + if (full[key] is not null) + { + slim[key] = full[key].DeepClone(); + } + } + if (full["facts"] is JObject facts) + { + // Keep short pointers only — long prose bloats 7B context and kills JSON discipline. + JObject shortFacts = new(); + foreach (JProperty prop in facts.Properties()) + { + string text = prop.Value?.ToString() ?? ""; + if (text.Length <= 160) + { + shortFacts[prop.Name] = text; + } + else + { + shortFacts[prop.Name] = text.Substring(0, 157) + "…"; + } + } + if (shortFacts.Count > 0) + { + slim["facts"] = shortFacts; + } + } + return slim; + } + public JObject LoadAssistant(string personaId) => MergeJsonLayers("assistant.json", LayerRoots(personaId)); public JObject LoadUi(string personaId) => MergeJsonLayers("ui.json", LayerRoots(personaId)); diff --git a/Config/_base/core/core.md b/Config/_base/core/core.md index 22ab538..47decca 100644 --- a/Config/_base/core/core.md +++ b/Config/_base/core/core.md @@ -16,14 +16,17 @@ When instructions conflict, apply this order (highest wins): Exact = encyclopedia of defaults. RAG = soft notes. Do **not** re-emit `steps` / `cfg` / `sigma_shift` / `aspect` when they already match exact (or session_exact) and the user did not ask to change them. +Never write a “JSON Patch” section in prose without an actual fenced ```json``` object. If you propose UI changes, the fence is mandatory. Keep the prose short (a few lines) — do not paste long critique templates. + ## Live context A JSON block named "Live SwarmUI context" is attached. Treat it as ground truth — refreshed every chat turn: - Use only LoRAs listed in `available_loras` / `enabled_loras` (exact `name`), or Civitai search candidates. - Prefer listed `trigger_phrase` / `triggers` — **never invent** trigger words. -- `exact` / `session_exact` / `recommended_params` — generation defaults; see Priority. -- `memory_hits` are retrieved notes (LoRA tips, pitfalls). Trust them over guesses, but **not** over exact or the user. +- `session_exact` / `recommended_params` — session overrides and defaults (Exact KV is in the system block above). +- `memory_hits` are retrieved notes (LoRA tips, pitfalls). Trust them over guesses, but **not** over Exact or the user. +- `has_vision_image` — if false, do not invent what the image looks like; emit `look_at` first when you need to see it. - `model_cards` for **enabled** models beat generic blurbs — follow `when` / `avoid` / `prompt_hint` / `triggers`. - `taste_profile` is the user's remembered preferences — bias toward it unless they override. - Prefer `krea_likely` / Krea architecture entries; ignore FLUX/SDXL LoRAs. diff --git a/Config/_base/packs/critique_image.md b/Config/_base/packs/critique_image.md index a1ba719..48d9ccd 100644 --- a/Config/_base/packs/critique_image.md +++ b/Config/_base/packs/critique_image.md @@ -1,28 +1,20 @@ # Mode: critique_image -Goal: look at the attached / requested board image(s) and improve the next generation for **Krea 2**. +Goal: look at the attached board image(s) and improve the next **Krea 2** generation. -If vision is missing but `image_slots` shows `generate` or a ref with `has_image: true`, emit `look_at: ["generate"]` (or the ref id) and **omit** `actions: ["generate"]` this turn so the UI can hop vision first. +## Vision gate (mandatory) -## Critique checklist +- If `has_vision_image` is false: emit **only** a one-line note + JSON with `look_at: ["generate"]` (or the ref id). Do **not** write a critique checklist. Do **not** invent defects. +- If vision is present: short critique, then a real fenced JSON patch. -- Subject, composition, lighting — what works / what fails. -- **Anatomy** (hands, limbs, face). -- **Dead eyes / flat expression** — stronger facial prose; enable bypass/expressiveness LoRA from inventory if available. -- **3D / concept-art bias** when the user wanted a photo — add photograph / real skin / film language. -- **Qwen VAE grid** on sand, hair, fine fabric — prefer **inpaint** that region, not a full rewrite. -- **Prompt Images dominate** (`prompt_image_count` > 0) — weaken reliance or clear via `clear_prompt_images`. -- Aspect too tight/wide — set `aspect` or width/height. -- Missing / wrong LoRA triggers or weights. +## Critique (keep short) -## Fix strategy - -- **Local defect** (hands, face, object): inpaint (`use_init_image` + mask). No mask → ask to paint / pack `inpaint_edit`. -- **Global restyle:** img2img with `init_creativity` ≈ 0.4–0.6. -- **From-scratch rewrite:** only when composition is wrong. +Bullet the real issues you see (anatomy, eyes, lighting, aspect, LoRA triggers). Do not paste a generic template of pitfalls you did not observe. ## Deliverable -- Short critique in the user's language. -- JSON patch with improved `prompt` and any `loras` / size / init tweaks. -- `actions: ["generate"]` when proposing a revised generation (default for this mode). +1. 2–6 short lines in the user's language. +2. One fenced ```json``` patch with improved `prompt` and any `loras` / `aspect` / init tweaks. +3. `actions: ["generate"]` when proposing a revised generation. + +Never describe a patch in prose without the fenced JSON object. diff --git a/README.md b/README.md index cccb8be..9e4decb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ SwarmUI extension for **collaborative Krea 2** prompting via **Ollama**: chat + board (Generate | Refs tabs), LoRA chips, **persona presets** (`Config/personas/`), **vector memory**, model cards with Civitai fetch, img2img/inpaint, slash commands, auto Generate. -**Version 0.7.1** — Exact KV memory + persona overlays; block SwarmUI `ViewSpecial`/model-card previews from Generate + vision. +**Version 0.7.2** — Exact KV (slim in prompt); block `ViewSpecial` model-card previews; critique requires vision + real JSON fence. ## Layout diff --git a/SwarmAssistentExtension.cs b/SwarmAssistentExtension.cs index c7ebaa2..e38c177 100644 --- a/SwarmAssistentExtension.cs +++ b/SwarmAssistentExtension.cs @@ -49,7 +49,7 @@ public class SwarmAssistentExtension : Extension ExtensionAuthor = "mrleo1nid"; Description = "Collaborative Krea 2 assistant: Ollama chat, persona presets, vector memory, model cards, Generate loop."; License = "MIT"; - Version = "0.7.1"; + Version = "0.7.2"; Tags = ["tabs", "ui", "llm", "ollama", "krea", "inpaint", "memory"]; } @@ -1347,11 +1347,11 @@ public class SwarmAssistentExtension : Extension } } - JObject exact = Config.LoadExact(pid); + JObject exact = Config.LoadExactForPrompt(pid); if (exact is not null && exact.Count > 0) { system.AppendLine(); - system.AppendLine("## Exact memory (canonical KV — always trust over RAG guesses)"); + system.AppendLine("## Exact memory (canonical KV defaults — prefer over RAG for numbers)"); system.AppendLine("```json"); system.AppendLine(exact.ToString(Newtonsoft.Json.Formatting.None)); system.AppendLine("```"); @@ -1574,7 +1574,7 @@ public class SwarmAssistentExtension : Extension Logs.Debug($"Assistent memory retrieve: {ex.Message}"); } - string enrichedContext = InjectMemoryHits(contextJson, hits, Config.LoadExact(pid)); + string enrichedContext = InjectMemoryHits(contextJson, hits); List messages = BuildOllamaMessages(packName, includeBase, enrichedContext, userMessages, personaId: pid, skillIds: skills); JArray civitaiResults = []; string reply = ""; @@ -1681,29 +1681,12 @@ public class SwarmAssistentExtension : Extension ctx = new JObject { ["_raw_context"] = contextJson }; } ctx["memory_hits"] = hits ?? new JArray(); - if (exact is not null && exact.Count > 0 && ctx["exact"] is null) - { - ctx["exact"] = exact; - } + // Never re-inject full Exact into live context (already in system prompt). + ctx.Remove("exact"); if (ctx["session_exact"] is null) { ctx["session_exact"] = new JObject(); } - if (ctx["recommended_params"] is null && exact?["generation"] is JObject gen) - { - JObject rec = new(); - foreach (string key in new[] { "steps", "cfg", "sigma_shift", "aspect", "images" }) - { - if (gen[key] is not null) - { - rec[key] = gen[key].DeepClone(); - } - } - if (rec.Count > 0) - { - ctx["recommended_params"] = rec; - } - } // Slim inventory for LLM: keep enabled + current, drop full dump if present if (ctx["available_loras"] is JArray allLoras && allLoras.Count > 24) {