feat: Enhance prompt execution for workflows and analysis offers
All checks were successful
Deploy Development / deploy (push) Successful in 48s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s

- Added support for handling aggregated results in workflow prompts, allowing for various data formats (string, object).
- Introduced a utility function to filter active prompts for both pipeline and workflow types in the analysis page.
- Updated content handling in the analysis component to accommodate new workflow data structures.

This improves the flexibility and usability of the prompt execution process in both backend and frontend components.
This commit is contained in:
Lars 2026-04-11 11:42:54 +02:00
parent 28b6fb28d5
commit 300d96a9d8
2 changed files with 32 additions and 5 deletions

View File

@ -1253,6 +1253,18 @@ async def execute_unified_prompt(
content = list(final_output.values())[0]
else:
content = json.dumps(final_output, ensure_ascii=False)
elif result['type'] == 'workflow':
# Graph-Workflows: kein "output", sondern aggregated_result
agg = result.get('aggregated_result')
if isinstance(agg, dict) and len(agg) == 1:
v = list(agg.values())[0]
content = v if isinstance(v, str) else json.dumps(v, ensure_ascii=False)
elif agg is None:
content = ''
elif isinstance(agg, str):
content = agg
else:
content = json.dumps(agg, ensure_ascii=False)
else:
# For base prompts, use output directly
content = result.get('output', '')

View File

@ -45,6 +45,11 @@ function analysisCategoryLabel(key) {
return ANALYSIS_CATEGORY_LABELS[k] || String(key)
}
/** Analyse-Angebote: klassische Pipelines + graphbasierte KI-Workflows (`type === 'workflow'`) */
function isAnalysisOfferPrompt(p) {
return p.active && (p.type === 'pipeline' || p.type === 'workflow')
}
/** Pipeline-Prompts nach `category` gruppieren (Backend-Feld), innerhalb Gruppe nach sort_order */
function buildPipelineGroups(pipelinePrompts) {
const m = new Map()
@ -360,7 +365,7 @@ export default function Analysis() {
},[])
useEffect(() => {
const list = prompts.filter(p => p.active && p.type === 'pipeline')
const list = prompts.filter(isAnalysisOfferPrompt)
setActiveCategoryKey(prev => {
if (!list.length) return null
const groups = buildPipelineGroups(list)
@ -372,7 +377,7 @@ export default function Analysis() {
useEffect(() => {
if (!newResult?.scope) return
const list = prompts.filter(p => p.active && p.type === 'pipeline')
const list = prompts.filter(isAnalysisOfferPrompt)
const groups = buildPipelineGroups(list)
const g = groups.find(gg => gg.prompts.some(p => p.slug === newResult.scope))
if (g) setActiveCategoryKey(g.categoryKey)
@ -394,6 +399,16 @@ export default function Analysis() {
} else {
content = JSON.stringify(finalOutput, null, 2)
}
} else if (result.type === 'workflow') {
const agg = result.aggregated_result
if (agg != null && typeof agg === 'object' && !Array.isArray(agg) && Object.keys(agg).length === 1) {
const v = Object.values(agg)[0]
content = typeof v === 'string' ? v : JSON.stringify(v, null, 2)
} else if (typeof agg === 'string') {
content = agg
} else {
content = JSON.stringify(agg ?? {}, null, 2)
}
} else {
// For base prompts, use output directly
content = typeof result.output === 'string' ? result.output : JSON.stringify(result.output, null, 2)
@ -405,7 +420,7 @@ export default function Analysis() {
const placeholders = {}
const resolved = result.debug.resolved_placeholders
// For pipeline, collect from all stages
// For pipeline, collect from all stages (Workflow: kein gleiches debug-Schema)
if (result.type === 'pipeline' && result.debug.stages) {
for (const stage of result.debug.stages) {
for (const promptDebug of (stage.prompts || [])) {
@ -456,9 +471,9 @@ export default function Analysis() {
grouped[key].push(ins)
})
// Show only active pipeline-type prompts (und nach DB-Kategorie gruppiert)
// Aktive Pipeline- + Workflow-Prompts (nach DB-Kategorie gruppiert)
const { pipelinePrompts, pipelineGroups } = useMemo(() => {
const list = prompts.filter(p => p.active && p.type === 'pipeline')
const list = prompts.filter(isAnalysisOfferPrompt)
return { pipelinePrompts: list, pipelineGroups: buildPipelineGroups(list) }
}, [prompts])