feat: Anweisungen-Feld für Agents mit EasyMDE-Editor
- AgentRecord: TaskInstruction (string, nullable) - DB-Migration: task_instruction TEXT Spalte - AgentEndpoint: Create/Update lesen taskInstruction - SystemPromptBuilder: '## Anweisungen' Block nach Soul, nur wenn nicht leer - HTML: Textarea #agentTaskInstruction nach Rückfragen-Checkbox - agent-page.js: EasyMDE-Editor mit Init, Laden, Speichern, Destroy
This commit is contained in:
1 parent
14e721f95b
commit
4f027360fd
6 files changed
+39
-5
No files matched your search
@@ -66,6 +66,7 @@ public static class AgentEndpoint
|
|||||||
UseWebSearch = body.TryGetProperty("webSearchVersion", out var wsv) && !string.IsNullOrEmpty(wsv.GetString()),
|
UseWebSearch = body.TryGetProperty("webSearchVersion", out var wsv) && !string.IsNullOrEmpty(wsv.GetString()),
|
||||||
WebSearchVersion = body.TryGetProperty("webSearchVersion", out var wsv2) ? wsv2.GetString() ?? "" : "",
|
WebSearchVersion = body.TryGetProperty("webSearchVersion", out var wsv2) ? wsv2.GetString() ?? "" : "",
|
||||||
AllowUserChoice = !body.TryGetProperty("allowUserChoice", out var auc) || auc.GetBoolean(),
|
AllowUserChoice = !body.TryGetProperty("allowUserChoice", out var auc) || auc.GetBoolean(),
|
||||||
|
TaskInstruction = body.TryGetProperty("taskInstruction", out var ti) ? ti.GetString() : null,
|
||||||
AvatarScale = body.TryGetProperty("avatarScale", out var asc) ? asc.GetDouble() : 1.0,
|
AvatarScale = body.TryGetProperty("avatarScale", out var asc) ? asc.GetDouble() : 1.0,
|
||||||
AvatarOffsetX = body.TryGetProperty("avatarOffsetX", out var aox) ? aox.GetDouble() : 0,
|
AvatarOffsetX = body.TryGetProperty("avatarOffsetX", out var aox) ? aox.GetDouble() : 0,
|
||||||
AvatarOffsetY = body.TryGetProperty("avatarOffsetY", out var aoy) ? aoy.GetDouble() : 0
|
AvatarOffsetY = body.TryGetProperty("avatarOffsetY", out var aoy) ? aoy.GetDouble() : 0
|
||||||
@@ -105,6 +106,7 @@ public static class AgentEndpoint
|
|||||||
agent.UseWebSearch = !string.IsNullOrEmpty(agent.WebSearchVersion);
|
agent.UseWebSearch = !string.IsNullOrEmpty(agent.WebSearchVersion);
|
||||||
}
|
}
|
||||||
if (body.TryGetProperty("allowUserChoice", out var auc)) agent.AllowUserChoice = auc.GetBoolean();
|
if (body.TryGetProperty("allowUserChoice", out var auc)) agent.AllowUserChoice = auc.GetBoolean();
|
||||||
|
if (body.TryGetProperty("taskInstruction", out var ti)) agent.TaskInstruction = ti.GetString();
|
||||||
if (body.TryGetProperty("avatarScale", out var asc)) agent.AvatarScale = asc.GetDouble();
|
if (body.TryGetProperty("avatarScale", out var asc)) agent.AvatarScale = asc.GetDouble();
|
||||||
if (body.TryGetProperty("avatarOffsetX", out var aox)) agent.AvatarOffsetX = aox.GetDouble();
|
if (body.TryGetProperty("avatarOffsetX", out var aox)) agent.AvatarOffsetX = aox.GetDouble();
|
||||||
if (body.TryGetProperty("avatarOffsetY", out var aoy)) agent.AvatarOffsetY = aoy.GetDouble();
|
if (body.TryGetProperty("avatarOffsetY", out var aoy)) agent.AvatarOffsetY = aoy.GetDouble();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class AgentRecord
|
|||||||
public bool UseWebSearch { get; set; }
|
public bool UseWebSearch { get; set; }
|
||||||
public string WebSearchVersion { get; set; } = "";
|
public string WebSearchVersion { get; set; } = "";
|
||||||
public bool AllowUserChoice { get; set; } = true;
|
public bool AllowUserChoice { get; set; } = true;
|
||||||
|
public string TaskInstruction { get; set; }
|
||||||
public double AvatarScale { get; set; } = 1.0;
|
public double AvatarScale { get; set; } = 1.0;
|
||||||
public double AvatarOffsetX { get; set; }
|
public double AvatarOffsetX { get; set; }
|
||||||
public double AvatarOffsetY { get; set; }
|
public double AvatarOffsetY { get; set; }
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public class DatabaseService
|
|||||||
TryAddColumn(conn, "agents", "avatar_offset_y", "REAL NOT NULL DEFAULT 0");
|
TryAddColumn(conn, "agents", "avatar_offset_y", "REAL NOT NULL DEFAULT 0");
|
||||||
TryAddColumn(conn, "sessions", "finalizer_agent_id", "TEXT");
|
TryAddColumn(conn, "sessions", "finalizer_agent_id", "TEXT");
|
||||||
TryAddColumn(conn, "agents", "allow_user_choice", "INTEGER NOT NULL DEFAULT 1");
|
TryAddColumn(conn, "agents", "allow_user_choice", "INTEGER NOT NULL DEFAULT 1");
|
||||||
|
TryAddColumn(conn, "agents", "task_instruction", "TEXT");
|
||||||
TryAddColumn(conn, "chains", "plan_mode", "INTEGER NOT NULL DEFAULT 0");
|
TryAddColumn(conn, "chains", "plan_mode", "INTEGER NOT NULL DEFAULT 0");
|
||||||
TryAddColumn(conn, "sessions", "preparer_agent_id", "TEXT");
|
TryAddColumn(conn, "sessions", "preparer_agent_id", "TEXT");
|
||||||
TryAddColumn(conn, "messages", "tag", "TEXT");
|
TryAddColumn(conn, "messages", "tag", "TEXT");
|
||||||
@@ -334,8 +335,8 @@ public class DatabaseService
|
|||||||
agent.CreatedAt = now;
|
agent.CreatedAt = now;
|
||||||
agent.UpdatedAt = now;
|
agent.UpdatedAt = now;
|
||||||
await conn.ExecuteAsync(@"
|
await conn.ExecuteAsync(@"
|
||||||
INSERT INTO agents (agent_id, user_id, name, avatar, description, model, tool_choice, custom_commands, auto_commit, use_soul, use_identity, use_user_info, use_memory, use_web_search, web_search_version, allow_user_choice, avatar_scale, avatar_offset_x, avatar_offset_y, is_deleted, created_at, updated_at)
|
INSERT INTO agents (agent_id, user_id, name, avatar, description, model, tool_choice, custom_commands, auto_commit, use_soul, use_identity, use_user_info, use_memory, use_web_search, web_search_version, allow_user_choice, task_instruction, avatar_scale, avatar_offset_x, avatar_offset_y, is_deleted, created_at, updated_at)
|
||||||
VALUES (@AgentId, @UserId, @Name, @Avatar, @Description, @Model, @ToolChoice, @CustomCommands, @AutoCommit, @UseSoul, @UseIdentity, @UseUserInfo, @UseMemory, @UseWebSearch, @WebSearchVersion, @AllowUserChoice, @AvatarScale, @AvatarOffsetX, @AvatarOffsetY, 0, @CreatedAt, @UpdatedAt)
|
VALUES (@AgentId, @UserId, @Name, @Avatar, @Description, @Model, @ToolChoice, @CustomCommands, @AutoCommit, @UseSoul, @UseIdentity, @UseUserInfo, @UseMemory, @UseWebSearch, @WebSearchVersion, @AllowUserChoice, @TaskInstruction, @AvatarScale, @AvatarOffsetX, @AvatarOffsetY, 0, @CreatedAt, @UpdatedAt)
|
||||||
", agent);
|
", agent);
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
@@ -363,7 +364,7 @@ public class DatabaseService
|
|||||||
model = @Model, tool_choice = @ToolChoice,
|
model = @Model, tool_choice = @ToolChoice,
|
||||||
custom_commands = @CustomCommands, auto_commit = @AutoCommit,
|
custom_commands = @CustomCommands, auto_commit = @AutoCommit,
|
||||||
use_soul = @UseSoul, use_identity = @UseIdentity, use_user_info = @UseUserInfo, use_memory = @UseMemory, use_web_search = @UseWebSearch, web_search_version = @WebSearchVersion,
|
use_soul = @UseSoul, use_identity = @UseIdentity, use_user_info = @UseUserInfo, use_memory = @UseMemory, use_web_search = @UseWebSearch, web_search_version = @WebSearchVersion,
|
||||||
allow_user_choice = @AllowUserChoice,
|
allow_user_choice = @AllowUserChoice, task_instruction = @TaskInstruction,
|
||||||
avatar_scale = @AvatarScale, avatar_offset_x = @AvatarOffsetX, avatar_offset_y = @AvatarOffsetY, updated_at = @UpdatedAt
|
avatar_scale = @AvatarScale, avatar_offset_x = @AvatarOffsetX, avatar_offset_y = @AvatarOffsetY, updated_at = @UpdatedAt
|
||||||
WHERE agent_id = @AgentId AND user_id = @UserId
|
WHERE agent_id = @AgentId AND user_id = @UserId
|
||||||
", agent);
|
", agent);
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ public static class SystemPromptBuilder
|
|||||||
blocks.Add(new PromptBlock { Icon = "fa-heart", Label = "Agent · SOUL.md (UseSoul)", Content = soul });
|
blocks.Add(new PromptBlock { Icon = "fa-heart", Label = "Agent · SOUL.md (UseSoul)", Content = soul });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Anweisungen
|
||||||
|
if (!string.IsNullOrWhiteSpace(agent.TaskInstruction))
|
||||||
|
{
|
||||||
|
blocks.Add(new PromptBlock { Icon = "fa-clipboard", Label = "Agent · Anweisungen", Content = $"## Anweisungen\n{agent.TaskInstruction.Trim()}" });
|
||||||
|
}
|
||||||
|
|
||||||
// User-Info: Persona aus dem Profil des Users der gerade schreibt
|
// User-Info: Persona aus dem Profil des Users der gerade schreibt
|
||||||
if (agent.UseUserInfo && !string.IsNullOrWhiteSpace(userPersona))
|
if (agent.UseUserInfo && !string.IsNullOrWhiteSpace(userPersona))
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-1
@@ -199,9 +199,11 @@
|
|||||||
Tool-Nutzung erzwingen <span class="checkbox-hint">(tool_choice: any)</span>
|
Tool-Nutzung erzwingen <span class="checkbox-hint">(tool_choice: any)</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="checkbox-label">
|
<label class="checkbox-label">
|
||||||
<input type="checkbox" id="agentAllowUserChoice">
|
<input type="checkbox" id="agentAllowUserChoice" checked>
|
||||||
Rückfragen erlauben <span class="checkbox-hint">(ask_user_choice Tool)</span>
|
Rückfragen erlauben <span class="checkbox-hint">(ask_user_choice Tool)</span>
|
||||||
</label>
|
</label>
|
||||||
|
<label>Anweisungen <small>(optional)</small></label>
|
||||||
|
<textarea id="agentTaskInstruction" rows="4" placeholder="Spezifische Anweisungen für diesen Agent (Markdown, optional)"></textarea>
|
||||||
<label>Git-Commit-Verhalten</label>
|
<label>Git-Commit-Verhalten</label>
|
||||||
<select id="agentAutoCommit">
|
<select id="agentAutoCommit">
|
||||||
<option value="">Nicht erwähnen</option>
|
<option value="">Nicht erwähnen</option>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// ── Agent Page ──
|
// ── Agent Page ──
|
||||||
|
|
||||||
let _agentAvatarEditor = null;
|
let _agentAvatarEditor = null;
|
||||||
|
let _agentTaskMde = null;
|
||||||
|
|
||||||
registerPage('agent', {
|
registerPage('agent', {
|
||||||
async init(params) {
|
async init(params) {
|
||||||
@@ -44,6 +45,21 @@ registerPage('agent', {
|
|||||||
initialOffsetY: (agent && agent.avatarOffsetY) || 0
|
initialOffsetY: (agent && agent.avatarOffsetY) || 0
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// EasyMDE für Task-Instruction
|
||||||
|
const taskEl = document.getElementById('agentTaskInstruction');
|
||||||
|
_agentTaskMde = new EasyMDE({
|
||||||
|
element: taskEl,
|
||||||
|
toolbar: ['bold', 'italic', 'heading', '|', 'quote', 'unordered-list', 'ordered-list', '|', 'link', 'code', '|', 'preview', 'guide'],
|
||||||
|
status: false,
|
||||||
|
autofocus: false,
|
||||||
|
spellChecker: false,
|
||||||
|
autoDownloadFontAwesome: false,
|
||||||
|
placeholder: 'Spezifische Anweisungen für diesen Agent (Markdown, optional)',
|
||||||
|
minHeight: '120px'
|
||||||
|
});
|
||||||
|
_agentTaskMde.codemirror.setOption('theme', 'default');
|
||||||
|
_agentTaskMde.codemirror.getWrapperElement().closest('.EasyMDEContainer').classList.add('fe-mde-wrap');
|
||||||
|
|
||||||
if (agent) {
|
if (agent) {
|
||||||
title.textContent = agent.name;
|
title.textContent = agent.name;
|
||||||
nameEl.value = agent.name || '';
|
nameEl.value = agent.name || '';
|
||||||
@@ -51,6 +67,7 @@ registerPage('agent', {
|
|||||||
modelEl.value = agent.model || 'sonnet';
|
modelEl.value = agent.model || 'sonnet';
|
||||||
toolChoiceEl.checked = (agent.toolChoice || 'any') === 'any';
|
toolChoiceEl.checked = (agent.toolChoice || 'any') === 'any';
|
||||||
allowUserChoiceEl.checked = agent.allowUserChoice !== false;
|
allowUserChoiceEl.checked = agent.allowUserChoice !== false;
|
||||||
|
_agentTaskMde.value(agent.taskInstruction || '');
|
||||||
autoCommitEl.value = agent.autoCommit || '';
|
autoCommitEl.value = agent.autoCommit || '';
|
||||||
useSoulEl.checked = agent.useSoul !== false;
|
useSoulEl.checked = agent.useSoul !== false;
|
||||||
useIdentityEl.checked = agent.useIdentity !== false;
|
useIdentityEl.checked = agent.useIdentity !== false;
|
||||||
@@ -107,7 +124,8 @@ registerPage('agent', {
|
|||||||
avatarScale: _agentAvatarEditor.getScale(),
|
avatarScale: _agentAvatarEditor.getScale(),
|
||||||
avatarOffsetX: _agentAvatarEditor.getOffsetX(),
|
avatarOffsetX: _agentAvatarEditor.getOffsetX(),
|
||||||
avatarOffsetY: _agentAvatarEditor.getOffsetY(),
|
avatarOffsetY: _agentAvatarEditor.getOffsetY(),
|
||||||
customCommands: getCommandsFromUI(commandsList)
|
customCommands: getCommandsFromUI(commandsList),
|
||||||
|
taskInstruction: _agentTaskMde ? _agentTaskMde.value().trim() || null : null
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isNew) {
|
if (isNew) {
|
||||||
@@ -137,6 +155,10 @@ registerPage('agent', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
|
if (_agentTaskMde) {
|
||||||
|
try { _agentTaskMde.toTextArea(); } catch (_) {}
|
||||||
|
_agentTaskMde = null;
|
||||||
|
}
|
||||||
if (_agentAvatarEditor) {
|
if (_agentAvatarEditor) {
|
||||||
_agentAvatarEditor.destroy();
|
_agentAvatarEditor.destroy();
|
||||||
_agentAvatarEditor = null;
|
_agentAvatarEditor = null;
|
||||||
|
|||||||
Reference in new issue
Block a user