Files
sfera/services/api-server/src/api_server/html5_ai_structure.py
T
m cbcfcc1741
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled
Optimize AI structure output for Codex
2026-05-21 20:51:34 +03:00

95 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
from html import escape
from typing import Iterable
from urllib.parse import quote
from api_server.html5 import _page, _project_link, _topbar
def render_html5_ai_structure_page(*, project_id: str, projects: Iterable[object], result: dict | None = None) -> str:
project_nav = "\n".join(_project_link(project, project_id) for project in projects)
return _page(
f"SFERA AI Structure - {project_id}",
f"""
<main class="workspace ai-structure-workspace" data-html5-page="ai-structure" data-project-id="{escape(project_id)}">
{_topbar(project_id, project_nav)}
<section class="setup-layout">
<aside class="panel">
<div class="setup-card">
<p class="eyebrow">AI-ready export</p>
<h1>Структура для ИИ</h1>
<p class="muted">Сервер подготовит полный пакет SFERA: normalized model, SIR graph, объекты, модули, связи и контекст для генерации кода.</p>
</div>
</aside>
<section class="panel setup-main">
<div class="panel-title">Подготовка структуры</div>
{render_html5_ai_structure_form(project_id)}
<div data-html5-ai-structure-result>{render_html5_ai_structure_result(result)}</div>
</section>
</section>
</main>
""",
)
def render_html5_ai_structure_form(project_id: str) -> str:
return f"""
<form
class="ai-structure-form"
hx-post="/html5/projects/{quote(project_id)}/ai-structure/run"
hx-target="[data-html5-ai-structure-result]"
hx-swap="innerHTML"
>
<label>
<span>Папка с cf/cfe или выгрузкой</span>
<input name="input_path" placeholder="D:\\1c\\source" />
</label>
<label>
<span>Папка результата</span>
<input name="output_path" placeholder="D:\\sfera-ai\\result" />
</label>
<label>
<span>Project id</span>
<input name="project_id" value="{escape(project_id)}" />
</label>
<button class="primary" type="submit">Подготовить для ИИ</button>
</form>
"""
def render_html5_ai_structure_result(result: dict | None) -> str:
if result is None:
return '<p class="muted padded">Укажите входную и выходную папку. Файлы будут созданы сервером в указанном каталоге.</p>'
diagnostics = list(result.get("diagnostics") or [])
artifacts = list(result.get("artifacts") or [])
snapshot = result.get("snapshot") or {}
normalized = result.get("normalized") or {}
return f"""
<section class="ai-structure-result" data-html5-ai-structure-status="{escape(str(result.get('status', '')))}">
<div class="access-plan-head">
<span class="status-pill">{escape(str(result.get("status", "")))}</span>
<strong>{escape(str(result.get("codex_package_folder") or result.get("output_path", "")))}</strong>
</div>
<p class="object-summary">Папка для переноса в Codex: {escape(str(result.get("codex_package_path", "")))}</p>
<dl class="setup-metrics">
<div><dt>Файлы</dt><dd>{escape(str(result.get("files_count", 0)))}</dd></div>
<div><dt>Nodes</dt><dd>{escape(str(snapshot.get("nodes", 0)))}</dd></div>
<div><dt>Edges</dt><dd>{escape(str(snapshot.get("edges", 0)))}</dd></div>
<div><dt>Objects</dt><dd>{escape(str(normalized.get("objects", 0)))}</dd></div>
</dl>
<div class="panel-title">Артефакты</div>
<div class="access-operations">{''.join(f'<article class="access-card"><strong>{escape(str(item))}</strong><small>AI structure package</small></article>' for item in artifacts)}</div>
{_diagnostics(diagnostics)}
</section>
"""
def _diagnostics(items: list[object]) -> str:
if not items:
return ""
return f"""
<div class="panel-title">Диагностика</div>
<ul class="access-warnings">{''.join(f'<li>{escape(str(item))}</li>' for item in items)}</ul>
"""