Universal CSV Importer #70

Merged
Lars merged 54 commits from develop into main 2026-04-11 07:06:47 +02:00
2 changed files with 51 additions and 17 deletions
Showing only changes of commit 3b4902dc11 - Show all commits

View File

@ -603,22 +603,56 @@ def execute_end_node(
"status": node_state.status.value if node_state.status else "unknown",
}
# Add normalized signals as {{node_id.signal_X}}
if node_state.normalized_signals:
for signal in node_state.normalized_signals:
# Convert NormalizedSignal object to dict if needed
signal_dict = signal.model_dump() if hasattr(signal, 'model_dump') else signal
signal_key = f"signal_{signal_dict['question_type']}"
node_context[signal_key] = signal_dict['normalized_value'] or signal_dict['raw_value']
# Add question texts as {{node_id.question_X}}
# Build question_type → question_id mapping from workflow graph
question_id_map = {}
if graph:
workflow_node = next((n for n in graph.nodes if n.id == node_id), None)
if workflow_node and workflow_node.question_augmentations:
for q in workflow_node.question_augmentations:
q_dict = q.model_dump() if hasattr(q, 'model_dump') else q
question_key = f"question_{q_dict['type']}"
node_context[question_key] = q_dict.get('question', '')
q_type = q_dict.get('type')
q_id = q_dict.get('id')
if q_type and q_id:
# Multiple questions with same type → use ID
if q_type not in question_id_map:
question_id_map[q_type] = []
question_id_map[q_type].append(q_id)
# Add normalized signals as {{node_id.signal_ID}} (not type!)
if node_state.normalized_signals:
# Track which types we've seen (for duplicate detection)
type_counts = {}
for signal in node_state.normalized_signals:
# Convert NormalizedSignal object to dict if needed
signal_dict = signal.model_dump() if hasattr(signal, 'model_dump') else signal
q_type = signal_dict['question_type']
# Determine which ID to use for this signal
if q_type in question_id_map:
# Get the Nth ID for this type (handles duplicates)
type_idx = type_counts.get(q_type, 0)
type_counts[q_type] = type_idx + 1
if type_idx < len(question_id_map[q_type]):
q_id = question_id_map[q_type][type_idx]
signal_key = f"signal_{q_id}"
node_context[signal_key] = signal_dict['normalized_value'] or signal_dict['raw_value']
else:
logger.warning(f"No question_id found for signal type={q_type} index={type_idx}")
else:
logger.warning(f"No question_id mapping for type={q_type}")
# Add question texts as {{node_id.question_ID}}
if graph:
workflow_node = next((n for n in graph.nodes if n.id == node_id), None)
if workflow_node and workflow_node.question_augmentations:
for q in workflow_node.question_augmentations:
q_dict = q.model_dump() if hasattr(q, 'model_dump') else q
q_id = q_dict.get('id')
if q_id:
question_key = f"question_{q_id}"
node_context[question_key] = q_dict.get('question', '')
template_context[node_id] = node_context

View File

@ -376,21 +376,21 @@ function extractWorkflowPlaceholders(nodes) {
if (node.type === 'analysis' && node.data.questions && node.data.questions.length > 0) {
node.data.questions.forEach((q, qIdx) => {
const questionId = q.id || `q${qIdx + 1}`
const questionType = q.type || `q${qIdx + 1}`
const questionType = q.type || 'unknown'
const questionText = q.question || `Frage ${qIdx + 1}`
// Signal-Platzhalter (Antwort)
// Signal-Platzhalter (Antwort) - VERWENDET ID für Eindeutigkeit!
placeholders.push({
placeholder: `{{ ${nodeId}.signal_${questionType} }}`,
description: `${nodeLabel} (${questionId}) - Signal ${questionType}: ${questionText.substring(0, 40)}${questionText.length > 40 ? '...' : ''}`,
placeholder: `{{ ${nodeId}.signal_${questionId} }}`,
description: `${nodeLabel} - ${questionId} (${questionType}): ${questionText.substring(0, 45)}${questionText.length > 45 ? '...' : ''}`,
icon: '📊',
category: 'Workflow - Signals'
})
// Frage-Text-Platzhalter
placeholders.push({
placeholder: `{{ ${nodeId}.question_${questionType} }}`,
description: `${nodeLabel} (${questionId}) - Frage ${questionType}: ${questionText.substring(0, 40)}${questionText.length > 40 ? '...' : ''}`,
placeholder: `{{ ${nodeId}.question_${questionId} }}`,
description: `${nodeLabel} - ${questionId} (${questionType}): ${questionText.substring(0, 45)}${questionText.length > 45 ? '...' : ''}`,
icon: '❓',
category: 'Workflow - Questions'
})