Oletuspromptit agentille + klikattavat pipeline-vaiheet
- Jokaisella agentilla on nyt oletusprompt joka näkyy heti modalissa - Muokatut promptit tallentuvat localStorageen - Pipeline-vaiherivin (✓ Suunnittelu → ✓ models.py → ...) klikkaus avaa modalin jossa näkyy kyseisen vaiheen prompti + tulos - 📋 Näytä prompti -nappi näkyy aina kun agentti on valittu Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1255,8 +1255,9 @@
|
||||
const lastPromptText = document.getElementById('agent-last-prompt-text');
|
||||
if (selectedAgents.size === 1) {
|
||||
const agent = [...selectedAgents][0];
|
||||
const lastStep = [...pipelineSteps].reverse().find(s => s.agent === agent && s.status === 'done' && s.input);
|
||||
lastPromptDiv.style.display = lastStep ? 'block' : 'none';
|
||||
// Näytetään aina jos agentilla on oletusprompt tai pipeline-historia
|
||||
const hasPrompt = defaultPipelinePrompts[agent] || pipelineSteps.some(s => s.agent === agent);
|
||||
lastPromptDiv.style.display = hasPrompt ? 'block' : 'none';
|
||||
} else {
|
||||
lastPromptDiv.style.display = 'none';
|
||||
}
|
||||
@@ -1376,6 +1377,21 @@
|
||||
window.openPromptModal = openPromptModal;
|
||||
|
||||
function closePromptModal() {
|
||||
// Tallennetaan muokattu prompti localStorageen
|
||||
if (modalAgent) {
|
||||
const fields = document.getElementById('prompt-modal-fields');
|
||||
const textareas = fields.querySelectorAll('textarea');
|
||||
const parts = [];
|
||||
textareas.forEach((ta, i) => {
|
||||
const key = modalPromptParts[i]?.key || '';
|
||||
parts.push(`${key}: ${ta.value.trim()}`);
|
||||
});
|
||||
const assembled = parts.join('\n\n');
|
||||
if (defaultPipelinePrompts[modalAgent]) {
|
||||
defaultPipelinePrompts[modalAgent].prompt = assembled;
|
||||
localStorage.setItem('kpn-pipeline-prompt-' + modalAgent, assembled);
|
||||
}
|
||||
}
|
||||
document.getElementById('prompt-modal').style.display = 'none';
|
||||
}
|
||||
window.closePromptModal = closePromptModal;
|
||||
@@ -1399,11 +1415,93 @@
|
||||
window.rerunFromModal = rerunFromModal;
|
||||
|
||||
// "Näytä prompti" -nappi avaa modalin
|
||||
// Oletuspromptit jokaiselle agentille — näkyvät aina, muokattavissa
|
||||
const defaultPipelinePrompts = {
|
||||
manager: { label: 'Suunnittelu', prompt: `List the source files needed for this project. One file per line, format:
|
||||
filename.py: one-line description
|
||||
|
||||
CONSTRAINTS: the coder can only generate ~400 tokens per file
|
||||
- Max 3 files (keep it minimal)
|
||||
- Each file must be SHORT: one clear responsibility, no boilerplate
|
||||
- Only .py and pyproject.toml files
|
||||
|
||||
EXAMPLE: for "FastAPI todo app with SQLite"
|
||||
pyproject.toml: project metadata and dependencies
|
||||
models.py: SQLAlchemy models and database setup
|
||||
main.py: FastAPI app with CRUD endpoints
|
||||
|
||||
Project: (käyttäjän kuvaus)` },
|
||||
coder: { label: 'Koodaus', prompt: `Project: (managerin suunnitelma)
|
||||
Write ONLY the file "filename.py": description
|
||||
|
||||
EXAMPLE: output for a main.py
|
||||
from fastapi import FastAPI, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
from models import get_db, User
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@app.get("/users")
|
||||
def list_users(db: Session = Depends(get_db)):
|
||||
return db.query(User).all()
|
||||
|
||||
IMPORTANT: Keep the code SHORT. Max ~50 lines. No comments, no docstrings. Output ONLY code.` },
|
||||
qa: { label: 'Testit + Validointi', prompt: `Write test_app.py using pytest and FastAPI TestClient. Max 3 tests. Output ONLY code.
|
||||
|
||||
EXAMPLE:
|
||||
from fastapi.testclient import TestClient
|
||||
from main import app
|
||||
client = TestClient(app)
|
||||
|
||||
def test_create():
|
||||
r = client.post("/users", params={"name": "Test"})
|
||||
assert r.status_code == 200
|
||||
|
||||
IMPORTANT: Check consistency
|
||||
1. Dockerfile COPY: references files that exist
|
||||
2. Dockerfile deps vs imports: all imports covered
|
||||
3. docker-compose ports: match EXPOSE
|
||||
4. Test imports: match actual module names
|
||||
5. pyproject.toml deps: cover all imports` },
|
||||
tester: { label: 'DevOps', prompt: `docker-compose.yml: services, volumes, port mappings
|
||||
|
||||
EXAMPLE:
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "8000:8000"
|
||||
restart: unless-stopped
|
||||
|
||||
README.md: Quick start, development, API endpoints, testing
|
||||
IMPORTANT: Use uv for package management (uv sync, uv run)` },
|
||||
data: { label: 'Data', prompt: `SQLAlchemy models and database setup.
|
||||
|
||||
EXAMPLE:
|
||||
from sqlalchemy import create_engine, Column, Integer, String
|
||||
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||
|
||||
engine = create_engine("sqlite:///app.db")
|
||||
Base = declarative_base()
|
||||
|
||||
IMPORTANT: Include get_db() dependency for FastAPI` },
|
||||
};
|
||||
|
||||
// Ladataan muokatut promptit localStoragesta
|
||||
for (const [agent, def] of Object.entries(defaultPipelinePrompts)) {
|
||||
const saved = localStorage.getItem('kpn-pipeline-prompt-' + agent);
|
||||
if (saved) def.prompt = saved;
|
||||
}
|
||||
|
||||
document.getElementById('agent-open-modal-btn')?.addEventListener('click', () => {
|
||||
if (selectedAgents.size !== 1) return;
|
||||
const agent = [...selectedAgents][0];
|
||||
// Viimeisin pipeline-prompti tai oletusprompt
|
||||
const lastStep = [...pipelineSteps].reverse().find(s => s.agent === agent && s.status === 'done' && s.input);
|
||||
if (lastStep) openPromptModal(agent, lastStep.label, lastStep.input);
|
||||
const def = defaultPipelinePrompts[agent];
|
||||
const prompt = lastStep?.input || def?.prompt || agentPrompts[agent]?.prompt || '';
|
||||
const label = lastStep?.label || def?.label || 'Prompti';
|
||||
openPromptModal(agent, label, prompt);
|
||||
});
|
||||
|
||||
function checkAgentConfusion() {
|
||||
@@ -2034,11 +2132,18 @@
|
||||
const iconColor = s.status === 'done' ? '#3fb950' : s.status === 'active' ? '#d29922' : '#8b949e';
|
||||
const arrow = i < pipelineSteps.length - 1 ? ' <span style="color:#30363d">→</span> ' : '';
|
||||
// Tooltip: input/output esikatselu
|
||||
const tip = esc(`${s.label}\nInput: ${(s.input || '').substring(0, 150)}\nOutput: ${(s.output || '').substring(0, 150)}`).replace(/\n/g, ' ');
|
||||
return `<span title="${tip}" style="cursor:help"><span style="color:${iconColor}">${icon}</span> <span style="color:${color}">${esc(s.label)}</span></span>${arrow}`;
|
||||
return `<span onclick="openPipelineStepModal(${i})" style="cursor:pointer;padding:2px 4px;border-radius:3px;transition:background 0.2s" onmouseenter="this.style.background='#21262d'" onmouseleave="this.style.background='transparent'"><span style="color:${iconColor}">${icon}</span> <span style="color:${color}">${esc(s.label)}</span></span>${arrow}`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
window.openPipelineStepModal = function(idx) {
|
||||
const s = pipelineSteps[idx];
|
||||
if (!s) return;
|
||||
// Näytetään modal promptilla (input) ja tuloksella (output)
|
||||
const combined = (s.input ? s.input : '') + (s.output ? '\n\n--- Tulos ---\n' + s.output : '');
|
||||
openPromptModal(s.agent, s.label, combined);
|
||||
};
|
||||
|
||||
function pipelineClear() {
|
||||
pipelineSteps.length = 0;
|
||||
const container = document.getElementById('pipeline-steps');
|
||||
|
||||
Reference in New Issue
Block a user