pagina unica
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Forja — Project Progress</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #1c1c1c;
|
||||
--surface: #151515;
|
||||
--border: #333;
|
||||
--text: #e7e5e4;
|
||||
--muted: #78716c;
|
||||
--accent: #f97316;
|
||||
--ok: #34d399;
|
||||
--warn: #fbbf24;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 2rem 1.5rem 4rem;
|
||||
}
|
||||
.wrap { max-width: 820px; margin: 0 auto; }
|
||||
h1 { font-size: 2rem; font-weight: 600; margin: 0 0 0.25rem; letter-spacing: -0.02em; }
|
||||
.subtitle { color: var(--muted); font-size: 0.95rem; margin-bottom: 2rem; }
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: 0.7rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--accent);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.15rem;
|
||||
margin: 2rem 0 0.75rem;
|
||||
padding-bottom: 0.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
h3 { font-size: 0.95rem; color: var(--accent); margin: 1.25rem 0 0.5rem; }
|
||||
p, li { color: var(--muted); font-size: 0.9rem; }
|
||||
li { margin: 0.35rem 0; }
|
||||
ul { padding-left: 1.25rem; }
|
||||
.card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 1.25rem 1.5rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0.75rem; margin: 1rem 0; }
|
||||
.tile {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 1rem;
|
||||
}
|
||||
.tile strong { display: block; color: var(--text); font-size: 0.9rem; margin-bottom: 0.25rem; }
|
||||
.tile span { font-size: 0.8rem; color: var(--muted); }
|
||||
code, pre {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.8rem;
|
||||
background: #0a0a0a;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
}
|
||||
code { padding: 0.15rem 0.4rem; color: #fcd34d; }
|
||||
pre {
|
||||
padding: 1rem;
|
||||
overflow-x: auto;
|
||||
color: var(--text);
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
a { color: var(--accent); }
|
||||
.done { color: var(--ok); }
|
||||
.todo { color: var(--warn); }
|
||||
table { width: 100%; border-collapse: collapse; font-size: 0.85rem; margin: 0.75rem 0; }
|
||||
th, td { text-align: left; padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--border); }
|
||||
th { color: var(--muted); font-weight: 500; }
|
||||
td { color: var(--text); }
|
||||
footer { margin-top: 3rem; font-size: 0.75rem; color: var(--muted); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
|
||||
<p class="badge">Status snapshot · 2 June 2026</p>
|
||||
<h1>Forja</h1>
|
||||
<p class="subtitle">Governed control plane for LLM agents and models — registry, guardrails, HITL, training orchestration, and promotion gates.</p>
|
||||
|
||||
<h2>Product direction</h2>
|
||||
<p>
|
||||
Forja is evolving from an <strong>agent governance runtime</strong> into a full <strong>model lifecycle forge</strong>:
|
||||
define agents and policies (Studio), validate with guardrails and human review (Runs, Approvals),
|
||||
orchestrate external fine-tuning (Azure ML), evaluate on canonical scenarios, and promote draft versions to production (Promotions).
|
||||
</p>
|
||||
<div class="grid">
|
||||
<div class="tile"><strong>Studio</strong><span>Agents, policies, datasets, base models (YAML)</span></div>
|
||||
<div class="tile"><strong>Validation</strong><span>Runs, guardrails, runtime HITL</span></div>
|
||||
<div class="tile"><strong>Training</strong><span>Azure ML SDK or mock/stub backends</span></div>
|
||||
<div class="tile"><strong>Governance</strong><span>Post-train eval gate + promotion HITL</span></div>
|
||||
</div>
|
||||
|
||||
<h2>Completed in this iteration</h2>
|
||||
|
||||
<h3 class="done">Phase 0 — Professional UI (English)</h3>
|
||||
<ul>
|
||||
<li>Removed gamified copy (Hearth, Anvil, blades, levels, etc.)</li>
|
||||
<li>Navigation: Agents, Runs, Approvals, Promotions, Run history, Deployments</li>
|
||||
<li><code>docs/product-voice.md</code> and <code>karpathy.md</code> referenced from README</li>
|
||||
<li>Terminal runs from the UI persist to <code>data/executions.jsonl</code></li>
|
||||
</ul>
|
||||
|
||||
<h3 class="done">Phase A — MLOps orchestration (foundation)</h3>
|
||||
<ul>
|
||||
<li>Versioned <code>datasets/</code> and <code>models/</code> registries</li>
|
||||
<li><code>TrainingBackend</code> strategy: <code>mock</code> and <code>azure_ml</code></li>
|
||||
<li>REST: <code>/api/datasets</code>, <code>/api/models</code>, <code>/api/training/runs</code></li>
|
||||
<li>Training runs stored under <code>data/training_runs/</code></li>
|
||||
</ul>
|
||||
|
||||
<h3 class="done">Phase B — Eval gate and governance promotion</h3>
|
||||
<ul>
|
||||
<li>Post-train evaluation over <code>agents/<name>/examples/*.txt</code></li>
|
||||
<li><code>POST /api/training/runs/{id}/evaluate</code> — blocks promotion if guardrails fail</li>
|
||||
<li><code>/api/promotions</code> — request, approve, reject; activates agent version in registry</li>
|
||||
<li>HTMX page <a href="http://localhost:8000/promotions">/promotions</a> for the governance queue</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="done">Azure ML SDK integration</h3>
|
||||
<ul>
|
||||
<li><code>azure-ai-ml</code> + <code>azure-identity</code> (<code>DefaultAzureCredential</code>)</li>
|
||||
<li>Submits command jobs when <code>AZURE_ML_*</code> workspace settings are set</li>
|
||||
<li>Falls back to <strong>stub mode</strong> locally when workspace is not configured</li>
|
||||
<li>Placeholder script: <code>core/src/forja_core/training/_azure_job_bundle/train.py</code></li>
|
||||
</ul>
|
||||
|
||||
<h2>Already in place (MVP core)</h2>
|
||||
<ul>
|
||||
<li>LangGraph runtime with SQLite checkpoints (HITL survives restarts)</li>
|
||||
<li>Guardrails AI engine + policy YAML</li>
|
||||
<li>Agent registry with Git-like versioning</li>
|
||||
<li>REST API under <code>/api</code> and HTMX UI on port 8000</li>
|
||||
</ul>
|
||||
|
||||
<h2>How to run the project</h2>
|
||||
|
||||
<h3>Option 1 — Docker (recommended)</h3>
|
||||
<pre>cp .env.example .env
|
||||
docker compose up</pre>
|
||||
<p>Open <a href="http://localhost:8000">http://localhost:8000</a>. Default <code>LLM_PROVIDER=mock</code> works without API keys.</p>
|
||||
|
||||
<h3>Option 2 — Local Python</h3>
|
||||
<pre>cp .env.example .env
|
||||
python -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r core/requirements.txt
|
||||
pip install pytest pytest-asyncio ruff mypy freezegun
|
||||
|
||||
cd core/src
|
||||
uvicorn forja_core.main:app --reload --host 0.0.0.0 --port 8000</pre>
|
||||
<p>Run from repo root with <code>PYTHONPATH=core/src</code> if needed:</p>
|
||||
<pre>PYTHONPATH=core/src uvicorn forja_core.main:app --reload --port 8000</pre>
|
||||
|
||||
<h3>Tests</h3>
|
||||
<pre>source venv/bin/activate
|
||||
./venv/bin/pytest tests/unit -q # unit
|
||||
./venv/bin/pytest tests/integration -q # integration (slower)
|
||||
make lint # ruff + mypy (if tools on PATH)</pre>
|
||||
|
||||
<h3>Quick demo (3 steps)</h3>
|
||||
<ol>
|
||||
<li><strong>Agents</strong> — <a href="http://localhost:8000/agents">/agents</a> → inspect <code>incident_analyzer</code></li>
|
||||
<li><strong>Runs</strong> — <a href="http://localhost:8000/run">/run</a> → scenario <code>01_sip_registration_drop</code> (may trigger Approvals)</li>
|
||||
<li><strong>Approvals / Promotions</strong> — <a href="http://localhost:8000/approvals">/approvals</a> and <a href="http://localhost:8000/promotions">/promotions</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>Key API endpoints</h2>
|
||||
<table>
|
||||
<thead><tr><th>Area</th><th>Endpoint</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Health</td><td><code>GET /health</code></td></tr>
|
||||
<tr><td>Invoke agent</td><td><code>POST /api/agents/{name}/invoke</code></td></tr>
|
||||
<tr><td>Training run</td><td><code>POST /api/training/runs</code></td></tr>
|
||||
<tr><td>Post-train eval</td><td><code>POST /api/training/runs/{id}/evaluate</code></td></tr>
|
||||
<tr><td>Promotion</td><td><code>POST /api/promotions</code> → <code>.../approve</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Next steps (when you resume)</h2>
|
||||
<ul>
|
||||
<li class="todo">Wire Forja datasets to Azure ML data assets (not only env vars)</li>
|
||||
<li class="todo">Replace placeholder <code>train.py</code> with real fine-tuning script</li>
|
||||
<li class="todo">Multi-tenant, OIDC, Postgres (enterprise roadmap)</li>
|
||||
<li class="todo">LLM-as-judge regression suite in CI</li>
|
||||
</ul>
|
||||
|
||||
<h2>Documentation</h2>
|
||||
<ul>
|
||||
<li><a href="../README.md">README.md</a> — quickstart</li>
|
||||
<li><a href="../ARCHITECTURE.md">ARCHITECTURE.md</a> — technical decisions</li>
|
||||
<li><a href="product-voice.md">docs/product-voice.md</a> — UI language rules</li>
|
||||
<li><a href="../karpathy.md">karpathy.md</a> — development guidelines</li>
|
||||
<li><a href="futuro.md">docs/futuro.md</a> — roadmap</li>
|
||||
</ul>
|
||||
|
||||
<footer>
|
||||
Generated for end-of-session handoff. Open this file in a browser: <code>docs/project-progress.html</code>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user