diff --git a/api/core/app/apps/workflow/app_generator.py b/api/core/app/apps/workflow/app_generator.py index 0165c74295..f21f40bbc5 100644 --- a/api/core/app/apps/workflow/app_generator.py +++ b/api/core/app/apps/workflow/app_generator.py @@ -141,9 +141,12 @@ class WorkflowAppGenerator(BaseAppGenerator): inputs: Mapping[str, Any] = args["inputs"] - extras = { + extras: dict[str, Any] = { **extract_external_trace_id_from_args(args), } + parent_trace_context = args.get("_parent_trace_context") + if parent_trace_context: + extras["parent_trace_context"] = parent_trace_context workflow_run_id = str(uuid.uuid4()) # FIXME (Yeuoly): we need to remove the SKIP_PREPARE_USER_INPUTS_KEY from the args # trigger shouldn't prepare user inputs diff --git a/api/core/tools/workflow_as_tool/tool.py b/api/core/tools/workflow_as_tool/tool.py index 33b15b3438..2a8cf0c280 100644 --- a/api/core/tools/workflow_as_tool/tool.py +++ b/api/core/tools/workflow_as_tool/tool.py @@ -51,6 +51,7 @@ class WorkflowTool(Tool): self.workflow_call_depth = workflow_call_depth self.label = label self._latest_usage = LLMUsage.empty_usage() + self.parent_trace_context: dict[str, str] | None = None super().__init__(entity=entity, runtime=runtime) @@ -91,11 +92,15 @@ class WorkflowTool(Tool): self._latest_usage = LLMUsage.empty_usage() + args: dict[str, Any] = {"inputs": tool_parameters, "files": files} + if self.parent_trace_context: + args["_parent_trace_context"] = self.parent_trace_context + result = generator.generate( app_model=app, workflow=workflow, user=user, - args={"inputs": tool_parameters, "files": files}, + args=args, invoke_from=self.runtime.invoke_from, streaming=False, call_depth=self.workflow_call_depth + 1, diff --git a/api/core/workflow/nodes/tool/tool_node.py b/api/core/workflow/nodes/tool/tool_node.py index 2e7ec757b4..2a6b59437c 100644 --- a/api/core/workflow/nodes/tool/tool_node.py +++ b/api/core/workflow/nodes/tool/tool_node.py @@ -105,6 +105,17 @@ class ToolNode(Node[ToolNodeData]): # get conversation id conversation_id = self.graph_runtime_state.variable_pool.get(["sys", SystemVariableKey.CONVERSATION_ID]) + from core.tools.workflow_as_tool.tool import WorkflowTool + + if isinstance(tool_runtime, WorkflowTool): + workflow_run_id_var = self.graph_runtime_state.variable_pool.get(["sys", SystemVariableKey.WORKFLOW_RUN_ID]) + tool_runtime.parent_trace_context = { + "trace_id": str(workflow_run_id_var.text) if workflow_run_id_var else "", + "parent_node_execution_id": self.execution_id, + "parent_workflow_run_id": str(workflow_run_id_var.text) if workflow_run_id_var else "", + "parent_app_id": self.app_id, + } + try: message_stream = ToolEngine.generic_invoke( tool=tool_runtime,