Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
26.2.0.dev0
26.2.0.dev2
5 changes: 5 additions & 0 deletions docs/wayflowcore/source/core/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ New features
Improvements
^^^^^^^^^^^^

* **Support for native Agent Spec CatchExceptionNode:**

WayFlow flows using the CatchExceptionStep now convert to the native Agent Spec
CatchExceptionNode when compatible (i.e., when catching all exceptions).

* **Added ``sensitive_headers`` in components that perform remote calls:**

``ApiCallStep``, ``RemoteTool``, and MCP ``RemoteBaseTransport`` now have a new attribute ``sensitive_headers``.
Expand Down
2 changes: 1 addition & 1 deletion wayflowcore/constraints/constraints_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ PyYAML==6.0.3
pydantic==2.12.4
httpx==0.28.1
mcp==1.24.0
pyagentspec==26.2.0.dev0 # Main branch of pyagentspec
pyagentspec==26.2.0.dev1 # Main branch of pyagentspec
opentelemetry-api==1.36.0
opentelemetry-sdk==1.36.0
2 changes: 1 addition & 1 deletion wayflowcore/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def read(file_name):
packages=find_packages("src"),
python_requires=">=3.10,<3.15",
install_requires=[
"pyagentspec>=26.1.0",
"pyagentspec>=26.2.0.dev0",
"httpx>0.28.0,<1.0.0", # warning but no vulnerabilities
"numpy>=1.24.3,<3.0.0",
"pandas>=2.0.3,<3.0.0",
Expand Down
16 changes: 12 additions & 4 deletions wayflowcore/src/wayflowcore/datastore/inmemory.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@

import warnings
from logging import getLogger
from typing import Any, Dict, List, Optional, Union, cast, overload

import numpy as np
import pandas as pd
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, cast, overload

from wayflowcore._metadata import MetadataType
from wayflowcore._utils.lazy_loader import LazyLoader
from wayflowcore.datastore._datatable import Datatable
from wayflowcore.datastore._utils import (
check_collection_name,
Expand All @@ -35,6 +33,16 @@
from wayflowcore.serialization.context import DeserializationContext, SerializationContext
from wayflowcore.serialization.serializer import serialize_to_dict

if TYPE_CHECKING:
# Important: do not move these imports out of the TYPE_CHECKING
# Otherwise, importing the module when they are not installed would lead to an import error.
import numpy as np
import pandas as pd
else:
np = LazyLoader("numpy")
pd = LazyLoader("pandas")


logger = getLogger(__name__)

_INMEMORY_USER_WARNING = "InMemoryDatastore is for DEVELOPMENT and PROOF-OF-CONCEPT ONLY!"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
from pyagentspec.flows.nodes.agentnode import AgentNode as AgentSpecAgentNode
from pyagentspec.flows.nodes.apinode import ApiNode as AgentSpecApiNode
from pyagentspec.flows.nodes.branchingnode import BranchingNode as AgentSpecBranchingNode
from pyagentspec.flows.nodes.catchexceptionnode import (
CatchExceptionNode as AgentSpecCatchExceptionNode,
)
from pyagentspec.flows.nodes.endnode import EndNode as AgentSpecEndNode
from pyagentspec.flows.nodes.flownode import FlowNode as AgentSpecFlowNode
from pyagentspec.flows.nodes.llmnode import LlmNode as AgentSpecLlmNode
Expand Down Expand Up @@ -379,6 +382,7 @@
from wayflowcore.outputparser import PythonToolOutputParser as RuntimePythonToolOutputParser
from wayflowcore.outputparser import RegexOutputParser as RuntimeRegexOutputParser
from wayflowcore.outputparser import RegexPattern as RuntimeRegexPattern
from wayflowcore.property import AnyProperty as RuntimeAnyProperty
from wayflowcore.property import JsonSchemaParam
from wayflowcore.property import ListProperty as RuntimeListProperty
from wayflowcore.property import Property as RuntimeProperty
Expand Down Expand Up @@ -1105,10 +1109,18 @@ def _find_property(properties: List[AgentSpecProperty], name: str) -> AgentSpecP
conversion_context.convert(edge, tool_registry, converted_components)
for edge in data_flow_connections or []
]
control_flow_edges: List[RuntimeControlFlowEdge] = [
conversion_context.convert(edge, tool_registry, converted_components)
for edge in agentspec_component.control_flow_connections
]
control_flow_edges: List[RuntimeControlFlowEdge] = []
for edge in agentspec_component.control_flow_connections:
if (
isinstance(edge.from_node, AgentSpecCatchExceptionNode)
and edge.from_branch == AgentSpecCatchExceptionNode.CAUGHT_EXCEPTION_BRANCH
):
# we need to rename the branch used in the CatchExceptionNode
edge.from_branch = RuntimeCatchExceptionStep.DEFAULT_EXCEPTION_BRANCH
control_flow_edges.append(
conversion_context.convert(edge, tool_registry, converted_components)
)

for step in steps.values():
for branch in step.get_branches():
edge_exists = any(
Expand Down Expand Up @@ -1482,6 +1494,55 @@ def _find_property(properties: List[AgentSpecProperty], name: str) -> AgentSpecP
except_on=agentspec_component.except_on,
**self._get_rt_nodes_arguments(agentspec_component, metadata_info),
)
elif isinstance(agentspec_component, AgentSpecCatchExceptionNode):
# Standard CatchExceptionNode from Agent Spec does not expose catch_all_exceptions
# and except_on fields
# Also, the output of the catch exception node might be renamed,
# so we have to use output mapping when needed
rt_nodes_arguments = self._get_node_arguments(agentspec_component, metadata_info)
if agentspec_component.outputs:
subflow_outputs_titles = {
p.title for p in agentspec_component.subflow.outputs or []
}
caught_exception_property = next(
(
p
for p in agentspec_component.outputs
if p.title not in subflow_outputs_titles
),
None,
)
if caught_exception_property is None:
raise ValueError(
f"Internal error: Agent Spec CatchExceptionNode '{agentspec_component.name}' "
"is missing a output for the exception info. Make sure the pyagentspec "
"component is successfully validated."
)
if (
caught_exception_property.title
!= RuntimeCatchExceptionStep.EXCEPTION_PAYLOAD_OUTPUT_NAME
):
# there is no output mapping by default. We add one to handle renaming
rt_nodes_arguments["output_mapping"] = {
RuntimeCatchExceptionStep.EXCEPTION_PAYLOAD_OUTPUT_NAME: caught_exception_property.title
}

# we need to add a default output property for the exception name
rt_nodes_arguments["output_descriptors"].append(
RuntimeAnyProperty(
name=RuntimeCatchExceptionStep.EXCEPTION_NAME_OUTPUT_NAME,
default_value="",
)
)

return RuntimeCatchExceptionStep(
flow=conversion_context.convert(
agentspec_component.subflow, tool_registry, converted_components
),
catch_all_exceptions=True,
except_on=None,
**rt_nodes_arguments,
)
elif isinstance(agentspec_component, AgentSpecPluginRegexNode):
regex_pattern = self._regex_pattern_to_runtime(agentspec_component.regex_pattern)
if not (
Expand Down
Loading