Prompt-editori modal: avain-arvo-parit, editoitavat kentät
Klikkaa agenttia → 'Näytä viimeisin prompti' → modal-ikkuna jossa prompti on pilkottu rakenteellisiin kenttiin (Project, CONSTRAINTS, EXAMPLE jne.). Editoitavat kentät sinisellä ✏️, lukitut harmaalla 🔒. 'Aja uudelleen' kokoaa promptin kentistä ja ajaa sen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1076,12 +1076,8 @@
|
|||||||
<div id="shared-prompt-section" style="display:none;margin-top:8px;font-size:12px;color:#8b949e">
|
<div id="shared-prompt-section" style="display:none;margin-top:8px;font-size:12px;color:#8b949e">
|
||||||
Yhteinen konteksti liitetään jokaisen valitun agentin oman promptin alkuun.
|
Yhteinen konteksti liitetään jokaisen valitun agentin oman promptin alkuun.
|
||||||
</div>
|
</div>
|
||||||
<div id="agent-last-prompt" style="display:none;margin-top:12px;border-top:1px solid var(--border-color);padding-top:10px">
|
<div id="agent-last-prompt" style="display:none;margin-top:8px">
|
||||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
|
<button id="agent-open-modal-btn" style="background:#161b22;border:1px solid var(--accent-color);color:var(--accent-color);font-size:12px;padding:4px 12px;border-radius:4px;cursor:pointer;width:100%">📋 Näytä viimeisin prompti</button>
|
||||||
<span style="font-size:12px;color:#8b949e">Viimeisin pipeline-prompti:</span>
|
|
||||||
<button id="agent-rerun-btn" style="background:#161b22;border:1px solid var(--accent-color);color:var(--accent-color);font-size:11px;padding:2px 10px;border-radius:4px;cursor:pointer">▶ Aja uudelleen</button>
|
|
||||||
</div>
|
|
||||||
<textarea id="agent-last-prompt-text" style="width:100%;background:#010409;border:1px solid var(--border-color);border-radius:4px;color:#c9d1d9;font-size:12px;font-family:'Courier New',monospace;padding:8px;resize:vertical;min-height:80px;outline:none"></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1260,14 +1256,7 @@
|
|||||||
if (selectedAgents.size === 1) {
|
if (selectedAgents.size === 1) {
|
||||||
const agent = [...selectedAgents][0];
|
const agent = [...selectedAgents][0];
|
||||||
const lastStep = [...pipelineSteps].reverse().find(s => s.agent === agent && s.status === 'done' && s.input);
|
const lastStep = [...pipelineSteps].reverse().find(s => s.agent === agent && s.status === 'done' && s.input);
|
||||||
if (lastStep) {
|
lastPromptDiv.style.display = lastStep ? 'block' : 'none';
|
||||||
lastPromptDiv.style.display = 'block';
|
|
||||||
lastPromptText.value = lastStep.input;
|
|
||||||
lastPromptText.dataset.agent = agent;
|
|
||||||
lastPromptText.dataset.label = lastStep.label;
|
|
||||||
} else {
|
|
||||||
lastPromptDiv.style.display = 'none';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
lastPromptDiv.style.display = 'none';
|
lastPromptDiv.style.display = 'none';
|
||||||
}
|
}
|
||||||
@@ -1327,15 +1316,94 @@
|
|||||||
saved._t = setTimeout(() => saved.style.opacity = '0', 1500);
|
saved._t = setTimeout(() => saved.style.opacity = '0', 1500);
|
||||||
});
|
});
|
||||||
|
|
||||||
// "Aja uudelleen" -nappi: ajaa editoidun promptin samalla agentilla
|
// Prompt-editori modal
|
||||||
document.getElementById('agent-rerun-btn')?.addEventListener('click', () => {
|
let modalAgent = null;
|
||||||
const textEl = document.getElementById('agent-last-prompt-text');
|
let modalPromptParts = [];
|
||||||
const prompt = textEl?.value?.trim();
|
|
||||||
if (!prompt) return;
|
function parsePromptToFields(prompt) {
|
||||||
const agent = textEl.dataset.agent;
|
// Pilkotaan prompti avain-arvo-pareiksi
|
||||||
const model = agentPrompts[agent]?.model || 'qwen-coder';
|
const fields = [];
|
||||||
termLog(`<span class="terminal-prompt">$</span> <span style="color:#a371f7">↻ Aja uudelleen:</span> ${esc(agent)} — ${esc(prompt.substring(0, 60))}...`);
|
const lines = prompt.split('\n');
|
||||||
|
let currentKey = null;
|
||||||
|
let currentVal = [];
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
// Tunnistetaan avain: KEYWORD: tai KEYWORD — tai rivin alku isolla
|
||||||
|
const keyMatch = line.match(/^(Project|CONSTRAINTS|EXAMPLE|RULES|IMPORTANT|Check|Files in project|Main app|Already written files|PROJECT CODE|Current code|Review feedback|Feedback)[\s:—]*(.*)/i);
|
||||||
|
if (keyMatch) {
|
||||||
|
if (currentKey) fields.push({ key: currentKey, value: currentVal.join('\n').trim(), editable: isEditable(currentKey) });
|
||||||
|
currentKey = keyMatch[1];
|
||||||
|
currentVal = keyMatch[2] ? [keyMatch[2]] : [];
|
||||||
|
} else {
|
||||||
|
currentVal.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentKey) fields.push({ key: currentKey, value: currentVal.join('\n').trim(), editable: isEditable(currentKey) });
|
||||||
|
|
||||||
|
// Jos ei löytynyt rakenteellisia avaimia, näytetään koko prompti yhtenä
|
||||||
|
if (fields.length === 0) fields.push({ key: 'Prompti', value: prompt, editable: true });
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEditable(key) {
|
||||||
|
const editableKeys = ['Project', 'CONSTRAINTS', 'IMPORTANT', 'Feedback', 'Review feedback'];
|
||||||
|
return editableKeys.some(k => key.toLowerCase().includes(k.toLowerCase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPromptModal(agent, label, prompt) {
|
||||||
|
modalAgent = agent;
|
||||||
|
modalPromptParts = parsePromptToFields(prompt);
|
||||||
|
const modal = document.getElementById('prompt-modal');
|
||||||
|
const title = document.getElementById('prompt-modal-title');
|
||||||
|
const fields = document.getElementById('prompt-modal-fields');
|
||||||
|
|
||||||
|
const agentNames = { manager: 'Manageri', coder: 'Koodari', tester: 'DevOps', qa: 'QA', data: 'Data' };
|
||||||
|
title.textContent = `${agentNames[agent] || agent} — ${label}`;
|
||||||
|
|
||||||
|
fields.innerHTML = modalPromptParts.map((f, i) => `
|
||||||
|
<div style="border:1px solid #21262d;border-radius:6px;overflow:hidden">
|
||||||
|
<div style="background:#161b22;padding:6px 10px;font-size:12px;font-weight:600;color:${f.editable ? '#58a6ff' : '#8b949e'};display:flex;align-items:center;gap:6px">
|
||||||
|
${f.editable ? '✏️' : '🔒'} ${f.key}
|
||||||
|
</div>
|
||||||
|
<textarea data-field-idx="${i}" ${f.editable ? '' : 'readonly'} style="width:100%;background:${f.editable ? '#010409' : '#0d1117'};border:none;color:${f.editable ? '#c9d1d9' : '#6e7681'};font-size:12px;font-family:'Courier New',monospace;padding:8px;resize:vertical;min-height:${f.value.split('\n').length > 3 ? '100' : '40'}px;outline:none;box-sizing:border-box">${f.value.replace(/</g,'<')}</textarea>
|
||||||
|
</div>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
|
modal.style.display = 'block';
|
||||||
|
// Sulje klikatessa taustaa
|
||||||
|
modal.onclick = (e) => { if (e.target === modal) closePromptModal(); };
|
||||||
|
}
|
||||||
|
window.openPromptModal = openPromptModal;
|
||||||
|
|
||||||
|
function closePromptModal() {
|
||||||
|
document.getElementById('prompt-modal').style.display = 'none';
|
||||||
|
}
|
||||||
|
window.closePromptModal = closePromptModal;
|
||||||
|
|
||||||
|
function rerunFromModal() {
|
||||||
|
// Kootaan prompti takaisin kentistä
|
||||||
|
const fields = document.getElementById('prompt-modal-fields');
|
||||||
|
const textareas = fields.querySelectorAll('textarea');
|
||||||
|
const parts = [];
|
||||||
|
textareas.forEach((ta, i) => {
|
||||||
|
const key = modalPromptParts[i]?.key || '';
|
||||||
|
const val = ta.value.trim();
|
||||||
|
if (val) parts.push(`${key}: ${val}`);
|
||||||
|
});
|
||||||
|
const prompt = parts.join('\n\n');
|
||||||
|
const model = agentPrompts[modalAgent]?.model || 'qwen-coder';
|
||||||
|
closePromptModal();
|
||||||
|
termLog(`<span class="terminal-prompt">$</span> <span style="color:#a371f7">↻ Aja uudelleen:</span> ${esc(modalAgent)}`);
|
||||||
kpnRun(model, prompt);
|
kpnRun(model, prompt);
|
||||||
|
}
|
||||||
|
window.rerunFromModal = rerunFromModal;
|
||||||
|
|
||||||
|
// "Näytä prompti" -nappi avaa modalin
|
||||||
|
document.getElementById('agent-open-modal-btn')?.addEventListener('click', () => {
|
||||||
|
if (selectedAgents.size !== 1) return;
|
||||||
|
const agent = [...selectedAgents][0];
|
||||||
|
const lastStep = [...pipelineSteps].reverse().find(s => s.agent === agent && s.status === 'done' && s.input);
|
||||||
|
if (lastStep) openPromptModal(agent, lastStep.label, lastStep.input);
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkAgentConfusion() {
|
function checkAgentConfusion() {
|
||||||
@@ -4112,5 +4180,20 @@ ${generatedFiles['Dockerfile'] || '(puuttuu)'}`;
|
|||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Prompt-editori modal -->
|
||||||
|
<div id="prompt-modal" style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:1000;backdrop-filter:blur(4px)">
|
||||||
|
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:#0d1117;border:1px solid #30363d;border-radius:8px;width:700px;max-width:90vw;max-height:85vh;overflow-y:auto;padding:20px">
|
||||||
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
|
||||||
|
<span id="prompt-modal-title" style="font-weight:600;font-size:15px;color:#58a6ff"></span>
|
||||||
|
<button onclick="closePromptModal()" style="background:none;border:none;color:#8b949e;font-size:20px;cursor:pointer;padding:0 4px">×</button>
|
||||||
|
</div>
|
||||||
|
<div id="prompt-modal-fields" style="display:flex;flex-direction:column;gap:10px"></div>
|
||||||
|
<div style="display:flex;gap:8px;margin-top:16px;justify-content:flex-end">
|
||||||
|
<button onclick="closePromptModal()" style="background:#161b22;border:1px solid #30363d;color:#8b949e;padding:6px 16px;border-radius:4px;cursor:pointer">Sulje</button>
|
||||||
|
<button onclick="rerunFromModal()" style="background:#238636;border:1px solid #2ea043;color:white;padding:6px 16px;border-radius:4px;cursor:pointer;font-weight:600">▶ Aja uudelleen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user