feat(dashboard): show system prompt per role in workflow detail

- Add systemPrompt to WorkflowRoleDescriptor (protocol)
- Propagate systemPrompt through buildDescriptor and validateWorkflowDescriptor
- Display system prompt as collapsible <details> in RoleCard
This commit is contained in:
2026-05-15 09:27:03 +08:00
parent 15edc99c72
commit b65a006d45
5 changed files with 28 additions and 1 deletions
+1
View File
@@ -122,6 +122,7 @@ export type WorkflowGraph = {
export type WorkflowRoleDescriptor = { export type WorkflowRoleDescriptor = {
description: string; description: string;
systemPrompt: string;
schema: Record<string, unknown>; schema: Record<string, unknown>;
}; };
@@ -179,6 +179,28 @@ function RoleCard({ roleName, role }: { roleName: string; role: WorkflowRoleDesc
{role.description} {role.description}
</p> </p>
)} )}
{role.systemPrompt !== "" && (
<details className="mb-3">
<summary
className="text-[10px] uppercase tracking-wider font-medium cursor-pointer select-none"
style={{ color: "var(--color-text-muted)" }}
>
System Prompt
</summary>
<pre
className="mt-1 text-xs p-2 rounded overflow-x-auto whitespace-pre-wrap break-words"
style={{
color: "var(--color-text)",
background: "var(--color-bg)",
border: "1px solid var(--color-border)",
maxHeight: "300px",
overflowY: "auto",
}}
>
{role.systemPrompt}
</pre>
</details>
)}
{rows.length > 0 && ( {rows.length > 0 && (
<div> <div>
<p <p
+1
View File
@@ -24,6 +24,7 @@ export type WorkflowRoleSchema = Record<string, unknown>;
export type WorkflowRoleDescriptor = { export type WorkflowRoleDescriptor = {
description: string; description: string;
systemPrompt: string;
schema: WorkflowRoleSchema; schema: WorkflowRoleSchema;
}; };
@@ -35,11 +35,12 @@ export function buildDescriptor<M extends RoleMeta>(
): WorkflowDescriptor { ): WorkflowDescriptor {
const roles: WorkflowDescriptor["roles"] = {}; const roles: WorkflowDescriptor["roles"] = {};
for (const [key, roleDef] of Object.entries(def.roles) as Array< for (const [key, roleDef] of Object.entries(def.roles) as Array<
[string, { description: string; schema: z.ZodType }] [string, { description: string; systemPrompt: string; schema: z.ZodType }]
>) { >) {
const rawJsonSchema = z.toJSONSchema(roleDef.schema) as Record<string, unknown>; const rawJsonSchema = z.toJSONSchema(roleDef.schema) as Record<string, unknown>;
roles[key] = { roles[key] = {
description: roleDef.description, description: roleDef.description,
systemPrompt: roleDef.systemPrompt,
schema: stripJsonSchemaMeta(rawJsonSchema), schema: stripJsonSchemaMeta(rawJsonSchema),
}; };
} }
@@ -88,8 +88,10 @@ export function validateWorkflowDescriptor(value: unknown): Result<WorkflowDescr
if (schema === null || typeof schema !== "object" || Array.isArray(schema)) { if (schema === null || typeof schema !== "object" || Array.isArray(schema)) {
return err(`descriptor.roles.${roleName}.schema must be a non-array object`); return err(`descriptor.roles.${roleName}.schema must be a non-array object`);
} }
const systemPrompt = typeof spec.systemPrompt === "string" ? spec.systemPrompt : "";
roles[roleName] = { roles[roleName] = {
description: roleDesc, description: roleDesc,
systemPrompt,
schema: schema as WorkflowRoleSchema, schema: schema as WorkflowRoleSchema,
}; };
} }