Files
AI/참고/ontocast-main/ontocast/stategraph/util.py
2026-05-12 19:40:31 +09:00

76 lines
2.5 KiB
Python

import asyncio
import logging
from functools import wraps
from typing import Callable
from ontocast.onto.enum import Status, WorkflowNode
from ontocast.onto.state import AgentState
logger = logging.getLogger(__name__)
def count_visits_conditional_success(
state: AgentState, current_node: WorkflowNode
) -> AgentState:
"""Track node visits and handle success/failure conditions.
This function increments the visit counter for a node and manages the state
based on success/failure conditions and maximum visit limits.
Args:
state: The current agent state.
current_node: The node being visited.
Returns:
AgentState: Updated agent state after processing visit conditions.
"""
state.node_visits[current_node] += 1
if state.status == Status.SUCCESS:
logger.info(f"For {current_node}: status is SUCCESS, proceeding to next node")
state.clear_failure()
elif state.node_visits[current_node] >= state.max_visits:
logger.info(f"For {current_node}: maximum visits exceeded")
# Don't set failure stage since we're continuing with SUCCESS status
# Just log the reason and continue
state.failure_reason = f"Maximum visits exceeded for {current_node}"
state.status = Status.SUCCESS
return state
def wrap_with(func, node_name, post_func) -> tuple[WorkflowNode, Callable]:
"""Add a visit counter to a function.
This function wraps a given function with logging and post-processing
functionality, typically used for workflow node execution.
Args:
func: The function to wrap (can be sync or async).
node_name: The name of the node.
post_func: Function to execute after the main function.
Returns:
tuple[WorkflowNode, Callable]: A tuple containing the node name and
the wrapped function.
"""
# Check if the function is async
if asyncio.iscoroutinefunction(func):
@wraps(func)
async def async_wrapper(state: AgentState):
logger.info(f"Starting to execute {node_name}")
state = await func(state)
state = post_func(state, node_name)
return state
return node_name, async_wrapper
else:
@wraps(func)
def sync_wrapper(state: AgentState):
logger.info(f"Starting to execute {node_name}")
state = func(state)
state = post_func(state, node_name)
return state
return node_name, sync_wrapper