diff --git a/Endpoints/SkillEndpoint.cs b/Endpoints/SkillEndpoint.cs
index 00c76fb..242d3a9 100644
--- a/Endpoints/SkillEndpoint.cs
+++ b/Endpoints/SkillEndpoint.cs
@@ -193,8 +193,8 @@ public static class SkillEndpoint
{
using var image = await Image.LoadAsync(originalPath);
- // Max 300px auf der längsten Seite
- var maxSize = 300;
+ // Max 320px auf der längsten Seite
+ var maxSize = 320;
image.Mutate(x => x.Resize(new ResizeOptions
{
Size = new Size(maxSize, maxSize),
diff --git a/Services/SkillService.cs b/Services/SkillService.cs
index eb466c1..c6b73b4 100644
--- a/Services/SkillService.cs
+++ b/Services/SkillService.cs
@@ -46,13 +46,14 @@ public class SkillService
}
///
- /// Liest die SKILL.md eines Skills. Gibt null zurück wenn nicht vorhanden.
+ /// Liest die PROMPT.md eines Skills. Gibt null zurück wenn nicht vorhanden.
+ /// Nur Skills mit PROMPT.md können im System-Prompt verwendet werden.
///
public string GetSkillPrompt(string slug)
{
- var skillMd = Path.Combine(_skillsDir, slug, "SKILL.md");
- if (!File.Exists(skillMd)) return null;
- return File.ReadAllText(skillMd);
+ var promptMd = Path.Combine(_skillsDir, slug, "PROMPT.md");
+ if (!File.Exists(promptMd)) return null;
+ return File.ReadAllText(promptMd);
}
private SkillInfo LoadSkill(string dir)
@@ -61,11 +62,14 @@ public class SkillService
var metaFile = Path.Combine(dir, "_meta.json");
var skillMd = Path.Combine(dir, "SKILL.md");
+ var promptMd = Path.Combine(dir, "PROMPT.md");
+
var info = new SkillInfo
{
Slug = slug,
Path = Path.GetFullPath(dir),
- HasSkillMd = File.Exists(skillMd)
+ HasSkillMd = File.Exists(skillMd),
+ HasPromptMd = File.Exists(promptMd)
};
// Name/Description aus SKILL.md Frontmatter lesen
@@ -135,4 +139,5 @@ public class SkillInfo
public string Version { get; set; }
public string Path { get; set; }
public bool HasSkillMd { get; set; }
+ public bool HasPromptMd { get; set; }
}
diff --git a/wwwroot/css/chat.css b/wwwroot/css/chat.css
index 3d93227..f2b76a6 100644
--- a/wwwroot/css/chat.css
+++ b/wwwroot/css/chat.css
@@ -627,17 +627,13 @@
.krea-thumb {
display: block;
- max-width: 300px;
- max-height: 200px;
+ max-width: 320px !important;
+ max-height: 240px;
object-fit: contain;
}
/* Krea Image Modal */
-.krea-overlay {
- backdrop-filter: blur(4px);
-}
-
.krea-modal {
max-width: 90vw;
max-height: 90vh;
diff --git a/wwwroot/css/form.css b/wwwroot/css/form.css
index b736b1b..e757785 100644
--- a/wwwroot/css/form.css
+++ b/wwwroot/css/form.css
@@ -180,6 +180,21 @@
border-radius: var(--border-radius);
}
+.skill-unavailable {
+ opacity: 0.45;
+ cursor: not-allowed;
+}
+
+.skill-unavailable:hover {
+ border-color: var(--f2-border);
+}
+
+.skill-warning {
+ color: var(--dangerous);
+ font-size: var(--font-size-sm, 0.8em);
+ margin-left: auto;
+}
+
.danger-btn {
color: var(--dangerous);
border-color: var(--dangerous);
diff --git a/wwwroot/js/pages/agent-page.js b/wwwroot/js/pages/agent-page.js
index ba9b26a..2a6a74e 100644
--- a/wwwroot/js/pages/agent-page.js
+++ b/wwwroot/js/pages/agent-page.js
@@ -185,14 +185,17 @@ function renderSkillCheckboxes(container, allSkills, assignedSlugs) {
}
for (const skill of allSkills) {
const checked = assignedSlugs.includes(skill.slug) ? 'checked' : '';
+ const disabled = !skill.hasPromptMd ? 'disabled' : '';
const version = skill.version ? ` v${skill.version}` : '';
const desc = skill.description ? `${skill.description}` : '';
+ const warning = !skill.hasPromptMd ? '⚠ PROMPT.md fehlt – Skill nicht verwendbar' : '';
const row = document.createElement('label');
- row.className = 'skill-item';
+ row.className = 'skill-item' + (!skill.hasPromptMd ? ' skill-unavailable' : '');
row.innerHTML = `
-
+
${skill.name}${version}
${desc}
+ ${warning}
`;
container.appendChild(row);
}
diff --git a/wwwroot/js/ui.js b/wwwroot/js/ui.js
index 5399b07..186669d 100644
--- a/wwwroot/js/ui.js
+++ b/wwwroot/js/ui.js
@@ -79,6 +79,16 @@ function scrollDown() {
});
}
+function _scrollOnImages(container) {
+ var imgs = container.querySelectorAll('img');
+ for (var i = 0; i < imgs.length; i++) {
+ if (!imgs[i].complete) {
+ imgs[i].addEventListener('load', scrollDown);
+ imgs[i].addEventListener('error', scrollDown);
+ }
+ }
+}
+
function esc(s) {
const d = document.createElement('div');
d.textContent = s;
@@ -234,6 +244,7 @@ function addAssistantBubble(text, timestamp = '', messageId = null, isMarked = f
if (messageId) div.dataset.messageId = messageId;
div.innerHTML = renderMarkdown(text);
wrapKreaGalleries(div);
+ _scrollOnImages(div);
_addReplyButton(div);
_addMarkButton(div, messageId, isMarked);
chatEl().appendChild(div);
@@ -299,6 +310,7 @@ function endStreamBubble() {
else {
_streamDiv.innerHTML = renderMarkdown(_streamText);
wrapKreaGalleries(_streamDiv);
+ _scrollOnImages(_streamDiv);
}
}
_streamDiv = null;