fixed doc handover

This commit is contained in:
ValueOn AG 2026-04-14 16:22:55 +02:00
parent 4852059c7d
commit 005b794a2a
2 changed files with 20 additions and 1 deletions

View file

@ -158,19 +158,23 @@ def _applyEmailSearchQuery(params: Dict) -> None:
def _wireHandover(nodeDef: Dict, inputSources: Dict, nodeOutputs: Dict, params: Dict) -> None: def _wireHandover(nodeDef: Dict, inputSources: Dict, nodeOutputs: Dict, params: Dict) -> None:
"""Apply wire-handover: extract fields from upstream using INPUT_EXTRACTORS.""" """Apply wire-handover: extract fields from upstream using INPUT_EXTRACTORS."""
if 0 not in inputSources: if 0 not in inputSources:
logger.debug("_wireHandover: no port 0 in inputSources=%s", inputSources)
return return
srcId, _ = inputSources[0] srcId, _ = inputSources[0]
upstream = nodeOutputs.get(srcId) upstream = nodeOutputs.get(srcId)
if not upstream or not isinstance(upstream, dict): if not upstream or not isinstance(upstream, dict):
logger.debug("_wireHandover: upstream for %s is missing or not dict: %s", srcId, type(upstream))
return return
data = _unwrapTransit(upstream) data = _unwrapTransit(upstream)
if not isinstance(data, dict): if not isinstance(data, dict):
logger.debug("_wireHandover: unwrapped data is not dict: %s", type(data))
return return
inputPorts = nodeDef.get("inputPorts", {}) inputPorts = nodeDef.get("inputPorts", {})
port0 = inputPorts.get(0, {}) port0 = inputPorts.get(0, {})
accepts = port0.get("accepts", []) accepts = port0.get("accepts", [])
logger.debug("_wireHandover: srcId=%s accepts=%s upstream_keys=%s params_keys_before=%s", srcId, accepts, list(data.keys()), list(params.keys()))
for schemaName in accepts: for schemaName in accepts:
if schemaName == "Transit": if schemaName == "Transit":
@ -178,9 +182,15 @@ def _wireHandover(nodeDef: Dict, inputSources: Dict, nodeOutputs: Dict, params:
extractor = INPUT_EXTRACTORS.get(schemaName) extractor = INPUT_EXTRACTORS.get(schemaName)
if extractor: if extractor:
extracted = extractor(data) extracted = extractor(data)
logger.debug("_wireHandover: extractor %s returned keys=%s", schemaName, list(extracted.keys()) if extracted else None)
if extracted: if extracted:
for k, v in extracted.items(): for k, v in extracted.items():
params.setdefault(k, v) existing = params.get(k)
if not existing:
params[k] = v
logger.debug("_wireHandover: set %s (was empty/missing) type=%s len=%s", k, type(v).__name__, len(v) if isinstance(v, (list, str, dict)) else "n/a")
else:
logger.debug("_wireHandover: skip %s (already has value, type=%s)", k, type(existing).__name__)
return return
@ -222,11 +232,14 @@ class ActionNodeExecutor:
# 1. Resolve parameters (DataRef, SystemVar, Static) # 1. Resolve parameters (DataRef, SystemVar, Static)
params = dict(node.get("parameters") or {}) params = dict(node.get("parameters") or {})
logger.debug("ActionNodeExecutor node %s raw params keys=%s", nodeId, list(params.keys()))
resolvedParams = resolveParameterReferences(params, context.get("nodeOutputs", {})) resolvedParams = resolveParameterReferences(params, context.get("nodeOutputs", {}))
logger.debug("ActionNodeExecutor node %s resolved params keys=%s documentList_present=%s documentList_type=%s", nodeId, list(resolvedParams.keys()), "documentList" in resolvedParams, type(resolvedParams.get("documentList")).__name__)
# 2. Wire-handover via extractors (fills missing params from upstream) # 2. Wire-handover via extractors (fills missing params from upstream)
inputSources = context.get("inputSources", {}).get(nodeId, {}) inputSources = context.get("inputSources", {}).get(nodeId, {})
_wireHandover(nodeDef, inputSources, context.get("nodeOutputs", {}), resolvedParams) _wireHandover(nodeDef, inputSources, context.get("nodeOutputs", {}), resolvedParams)
logger.debug("ActionNodeExecutor node %s after wireHandover: params keys=%s documentList_present=%s documentList_type=%s", nodeId, list(resolvedParams.keys()), "documentList" in resolvedParams, type(resolvedParams.get("documentList")).__name__)
# 3. Apply defaults from parameter definitions # 3. Apply defaults from parameter definitions
for pDef in nodeDef.get("parameters", []): for pDef in nodeDef.get("parameters", []):

View file

@ -213,9 +213,11 @@ def _resolveDocumentList(documentListParam, services) -> List[tuple]:
if isinstance(documentListParam, list) and documentListParam: if isinstance(documentListParam, list) and documentListParam:
first = documentListParam[0] first = documentListParam[0]
logger.debug("_resolveDocumentList: %d items, first type=%s, first keys=%s", len(documentListParam), type(first).__name__, list(first.keys()) if isinstance(first, dict) else "n/a")
if isinstance(first, dict) and ("documentData" in first or "documentName" in first): if isinstance(first, dict) and ("documentData" in first or "documentName" in first):
for doc in documentListParam: for doc in documentListParam:
rawData = doc.get("documentData") rawData = doc.get("documentData")
logger.debug("_resolveDocumentList: doc keys=%s documentData type=%s documentData truthy=%s", list(doc.keys()), type(rawData).__name__, bool(rawData))
if not rawData: if not rawData:
continue continue
try: try:
@ -228,6 +230,8 @@ def _resolveDocumentList(documentListParam, services) -> List[tuple]:
results.append((data, fileId, fileName, mimeType)) results.append((data, fileId, fileName, mimeType))
if results: if results:
return results return results
else:
logger.debug("_resolveDocumentList: first item has no documentData/documentName key, falling through to chat fallback")
chatService = getattr(services, "chat", None) chatService = getattr(services, "chat", None)
if not chatService: if not chatService:
@ -268,7 +272,9 @@ async def processDocuments(self, parameters: Dict[str, Any]) -> ActionResult:
return ActionResult.isFailure(error="featureInstanceId is required") return ActionResult.isFailure(error="featureInstanceId is required")
try: try:
logger.debug("processDocuments: documentListParam type=%s len=%s", type(documentListParam).__name__, len(documentListParam) if isinstance(documentListParam, (list, str)) else "n/a")
extractionDocs = _resolveDocumentList(documentListParam, self.services) extractionDocs = _resolveDocumentList(documentListParam, self.services)
logger.debug("processDocuments: extractionDocs count=%d", len(extractionDocs))
if not extractionDocs: if not extractionDocs:
return ActionResult.isFailure(error="No documents found for documentList") return ActionResult.isFailure(error="No documents found for documentList")