feat: add web UI prompt library from canonical workflows (#428)

Surface short copy/paste operator prompts derived from canonical workflow
files with workflow path and SHA-256 citations. Adds /prompts, /prompts/{id},
and /api/prompts with one-click copy.

Closes #428
This commit is contained in:
2026-07-07 14:53:16 -04:00
parent 6670c72e65
commit f845864889
4 changed files with 127 additions and 87 deletions
+21 -2
View File
@@ -12,8 +12,8 @@ from starlette.routing import Route
from webui.layout import render_page
from webui.project_registry import find_project, load_registry, registry_to_dict
from webui.project_views import render_project_detail, render_projects_list
from webui.prompt_library import library_to_dict
from webui.prompt_views import render_prompts_page
from webui.prompt_library import find_prompt, library_to_dict
from webui.prompt_views import render_prompt_detail, render_prompts_page
_READ_ONLY_METHODS = frozenset({"GET", "HEAD", "OPTIONS"})
@@ -85,6 +85,24 @@ async def prompts(_request: Request) -> HTMLResponse:
return HTMLResponse(render_prompts_page())
async def prompt_detail(request: Request) -> HTMLResponse:
prompt_id = request.path_params["prompt_id"]
prompt = find_prompt(prompt_id)
if prompt is None:
return HTMLResponse(
render_page(
title="Prompt not found",
body_html=(
"<h2>Prompt not found</h2>"
f"<p>No library entry for <code>{prompt_id}</code>.</p>"
'<p><a href="/prompts">← All prompts</a></p>'
),
),
status_code=404,
)
return HTMLResponse(render_prompt_detail(prompt))
async def api_prompts(_request: Request) -> JSONResponse:
return JSONResponse(library_to_dict())
@@ -137,6 +155,7 @@ def create_app() -> Starlette:
Route("/projects/{project_id}", project_detail, methods=["GET"]),
Route("/api/projects", api_projects, methods=["GET"]),
Route("/prompts", prompts, methods=["GET"]),
Route("/prompts/{prompt_id}", prompt_detail, methods=["GET"]),
Route("/api/prompts", api_prompts, methods=["GET"]),
Route("/runtime", runtime, methods=["GET"]),
Route("/audit", audit, methods=["GET"]),