This commit is contained in:
elpresidank 2026-05-11 19:44:40 -05:00
parent 54a6e49bd3
commit a20dd1999c
39 changed files with 3627 additions and 46 deletions

View file

@ -1183,44 +1183,42 @@ export class FlowsApi {
// Prompt management - specialized config operations for AI prompts
/**
* Retrieves list of available prompt templates
* Retrieves list of available prompt templates from config.prompt.
* Each template is stored at `config.prompt.<name>` as an object
* `{system, prompt}`. The reserved key `system` holds an optional
* global system prompt and is excluded from the template list.
*/
getPrompts() {
return this.getConfigAll().then((r) => {
const config = r as Record<
string,
Record<string, Record<string, string>>
>;
const raw = config.config?.prompt?.["template-index"];
return raw ? JSON.parse(raw) : [];
const config = r as { config?: { prompt?: Record<string, unknown> } };
const promptNs = config.config?.prompt ?? {};
return Object.keys(promptNs)
.filter((k) => k !== "system")
.sort()
.map((id) => ({ id, name: id }));
});
}
/**
* Retrieves a specific prompt template
* Retrieves a specific prompt template object: `{system, prompt}`.
*/
getPrompt(id: string) {
return this.getConfigAll().then((r) => {
const config = r as Record<
string,
Record<string, Record<string, string>>
>;
const raw = config.config?.prompt?.[`template.${id}`];
return raw ? JSON.parse(raw) : null;
const config = r as { config?: { prompt?: Record<string, unknown> } };
return config.config?.prompt?.[id] ?? null;
});
}
/**
* Retrieves the system prompt configuration
* Retrieves the optional global system prompt at `config.prompt.system`.
* Returns "" if not configured.
*/
getSystemPrompt() {
return this.getConfigAll().then((r) => {
const config = r as Record<
string,
Record<string, Record<string, string>>
>;
const config = r as { config?: { prompt?: { system?: unknown } } };
const raw = config.config?.prompt?.system;
return raw ? JSON.parse(raw) : "";
if (raw == null) return "";
return typeof raw === "string" ? raw : raw;
});
}
@ -2091,44 +2089,42 @@ export class ConfigApi {
// Specialized prompt management methods
/**
* Retrieves available prompt templates
* Retrieves list of available prompt templates from config.prompt.
* Each template is stored at `config.prompt.<name>` as an object
* `{system, prompt}`. The reserved key `system` holds an optional
* global system prompt and is excluded from the template list.
*/
getPrompts() {
return this.getConfigAll().then((r) => {
const config = r as Record<
string,
Record<string, Record<string, string>>
>;
const raw = config.config?.prompt?.["template-index"];
return raw ? JSON.parse(raw) : [];
const config = r as { config?: { prompt?: Record<string, unknown> } };
const promptNs = config.config?.prompt ?? {};
return Object.keys(promptNs)
.filter((k) => k !== "system")
.sort()
.map((id) => ({ id, name: id }));
});
}
/**
* Retrieves a specific prompt template
* Retrieves a specific prompt template object: `{system, prompt}`.
*/
getPrompt(id: string) {
return this.getConfigAll().then((r) => {
const config = r as Record<
string,
Record<string, Record<string, string>>
>;
const raw = config.config?.prompt?.[`template.${id}`];
return raw ? JSON.parse(raw) : null;
const config = r as { config?: { prompt?: Record<string, unknown> } };
return config.config?.prompt?.[id] ?? null;
});
}
/**
* Retrieves system prompt configuration
* Retrieves the optional global system prompt at `config.prompt.system`.
* Returns "" if not configured.
*/
getSystemPrompt() {
return this.getConfigAll().then((r) => {
const config = r as Record<
string,
Record<string, Record<string, string>>
>;
const config = r as { config?: { prompt?: { system?: unknown } } };
const raw = config.config?.prompt?.system;
return raw ? JSON.parse(raw) : "";
if (raw == null) return "";
return typeof raw === "string" ? raw : raw;
});
}

View file

@ -22,7 +22,7 @@ export default function PromptsPage() {
const [activeTab, setActiveTab] = useState<Tab>("templates");
const [selectedPromptId, setSelectedPromptId] = useState<string | null>(null);
const [promptDetail, setPromptDetail] = useState<string>("");
const [promptDetail, setPromptDetail] = useState<{ system?: string; prompt?: string } | string | null>(null);
const [loadingDetail, setLoadingDetail] = useState(false);
const handleSelectPrompt = useCallback(
@ -31,9 +31,7 @@ export default function PromptsPage() {
setLoadingDetail(true);
try {
const detail = await getPrompt(id);
setPromptDetail(
typeof detail === "string" ? detail : JSON.stringify(detail, null, 2),
);
setPromptDetail(detail as typeof promptDetail);
} catch (err) {
console.error("Failed to load prompt detail:", err);
setPromptDetail("Error loading prompt.");
@ -181,9 +179,32 @@ export default function PromptsPage() {
<Loader2 className="h-4 w-4 animate-spin" />
Loading...
</div>
) : promptDetail && typeof promptDetail === "object" ? (
<div className="space-y-4">
{promptDetail.system && (
<section>
<h3 className="mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-fg-subtle">
System
</h3>
<pre className="whitespace-pre-wrap rounded-md border border-border bg-surface-100 p-3 font-mono text-xs text-fg-muted">
{promptDetail.system}
</pre>
</section>
)}
{promptDetail.prompt && (
<section>
<h3 className="mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-fg-subtle">
Prompt
</h3>
<pre className="whitespace-pre-wrap rounded-md border border-border bg-surface-100 p-3 font-mono text-xs text-fg-muted">
{promptDetail.prompt}
</pre>
</section>
)}
</div>
) : (
<pre className="whitespace-pre-wrap font-mono text-xs text-fg-muted">
{promptDetail}
{typeof promptDetail === "string" ? promptDetail : ""}
</pre>
)}
</div>