From 13c3a3f5776859a3676dfc7bde916e06f410e271 Mon Sep 17 00:00:00 2001 From: Ayush8923 <80516839+Ayush8923@users.noreply.github.com> Date: Wed, 1 Jul 2026 14:01:53 +0530 Subject: [PATCH 1/4] feat(*): added the iterate on prompt --- .../configurations/prompt-editor/page.tsx | 30 +++++++- app/(main)/evaluations/[id]/page.tsx | 72 +++++++++++++++++++ .../evaluations/[id]/improve-prompt/route.ts | 39 ++++++++++ app/components/CommitMessage.tsx | 65 +++++++++++++++++ .../icons/prompt-editor/SpinnerIcon.tsx | 23 ++---- app/components/index.ts | 1 + .../prompt-editor/ConfigEditorPane.tsx | 1 - .../prompt-editor/HistorySidebar.tsx | 7 +- app/lib/types/commit.ts | 12 ++++ 9 files changed, 225 insertions(+), 25 deletions(-) create mode 100644 app/api/evaluations/[id]/improve-prompt/route.ts create mode 100644 app/components/CommitMessage.tsx create mode 100644 app/lib/types/commit.ts diff --git a/app/(main)/configurations/prompt-editor/page.tsx b/app/(main)/configurations/prompt-editor/page.tsx index f60ddb54..dca5291e 100644 --- a/app/(main)/configurations/prompt-editor/page.tsx +++ b/app/(main)/configurations/prompt-editor/page.tsx @@ -23,6 +23,7 @@ import { useConfigPersistence } from "@/app/hooks/useConfigPersistence"; import { SavedConfig, ConfigVersionItems } from "@/app/lib/types/configs"; import { configState } from "@/app/lib/store/configStore"; import { DEFAULT_CONFIG } from "@/app/lib/constants"; +import { apiFetch } from "@/app/lib/apiClient"; function PromptEditorContent() { const searchParams = useSearchParams(); @@ -126,6 +127,29 @@ function PromptEditorContent() { [], ); + const refreshVersionsForConfig = React.useCallback( + async (configId: string) => { + if (!configId) return; + try { + const apiKey = activeKey?.key ?? ""; + const res = await apiFetch<{ + success: boolean; + data: ConfigVersionItems[]; + }>(`/api/configs/${configId}/versions`, apiKey); + if (res.success && res.data) { + configState.versionItemsCache[configId] = res.data; + setStableVersionItemsMap((prev) => ({ + ...prev, + [configId]: res.data, + })); + } + } catch (err) { + console.error("Failed to refresh version list:", err); + } + }, + [activeKey], + ); + const resetEditor = React.useCallback(() => { setCurrentContent(""); setCurrentConfigBlob(DEFAULT_CONFIG); @@ -247,7 +271,11 @@ function PromptEditorContent() { if (ok) { setHasUnsavedChanges(false); setCommitMessage(""); - if (wasNewConfig) resetEditor(); + if (wasNewConfig) { + resetEditor(); + } else if (currentConfigParentId) { + await refreshVersionsForConfig(currentConfigParentId); + } } }; diff --git a/app/(main)/evaluations/[id]/page.tsx b/app/(main)/evaluations/[id]/page.tsx index 045eda53..66a6d0bd 100644 --- a/app/(main)/evaluations/[id]/page.tsx +++ b/app/(main)/evaluations/[id]/page.tsx @@ -8,6 +8,7 @@ import { useState, useEffect, useCallback, useRef } from "react"; import { useRouter, useParams } from "next/navigation"; import { apiFetch } from "@/app/lib/apiClient"; +import { invalidateConfigCache } from "@/app/lib/utils"; import { useAuth } from "@/app/lib/context/AuthContext"; import { useApp } from "@/app/lib/context/AppContext"; import type { @@ -48,6 +49,7 @@ import { DatabaseIcon, GroupIcon, DownloadIcon, + SpinnerIcon, } from "@/app/components/icons"; export default function EvaluationReport() { @@ -70,6 +72,7 @@ export default function EvaluationReport() { const [isConfigModalOpen, setIsConfigModalOpen] = useState(false); const [exportFormat, setExportFormat] = useState<"row" | "grouped">("row"); const [isResyncing, setIsResyncing] = useState(false); + const [isImprovingPrompt, setIsImprovingPrompt] = useState(false); const [showNoTracesModal, setShowNoTracesModal] = useState(false); const fetchJobDetails = useCallback(async () => { @@ -180,6 +183,51 @@ export default function EvaluationReport() { } }; + const handleIteratePrompt = async () => { + if (!isAuthenticated || !jobId) return; + setIsImprovingPrompt(true); + try { + const data = await apiFetch<{ + success: boolean; + error?: string; + data?: { + config_id?: string; + id?: string; + version?: number; + } | null; + }>(`/api/evaluations/${jobId}/improve-prompt`, apiKey, { + method: "POST", + body: JSON.stringify({}), + }); + + if (!data.success) { + toast.error(data.error || "Failed to iterate on prompt"); + return; + } + + invalidateConfigCache(); + toast.success("Prompt iteration created"); + + const newConfigId = data.data?.config_id ?? data.data?.id; + const newVersion = data.data?.version; + if (newConfigId) { + const versionParam = + typeof newVersion === "number" ? `&version=${newVersion}` : ""; + router.push( + `/configurations/prompt-editor?config=${encodeURIComponent( + newConfigId, + )}${versionParam}&from=evaluations`, + ); + } + } catch (err: unknown) { + toast.error( + `Failed to iterate on prompt: ${err instanceof Error ? err.message : "Unknown error"}`, + ); + } finally { + setIsImprovingPrompt(false); + } + }; + const handleResync = async () => { if (!isAuthenticated || !jobId) return; @@ -344,6 +392,30 @@ export default function EvaluationReport() { View Config Config +