abstractflow 0.3.0__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
abstractflow/__init__.py CHANGED
@@ -39,9 +39,9 @@ For agent-based flows:
39
39
  >>> result = runner.run({"context": {"task": "Build a REST API"}})
40
40
  """
41
41
 
42
- __version__ = "0.3.0"
42
+ __version__ = "0.3.1"
43
43
  __author__ = "Laurent-Philippe Albou"
44
- __email__ = "contact@abstractcore.ai"
44
+ __email__ = "contact@abstractflow.ai"
45
45
  __license__ = "MIT"
46
46
 
47
47
  # Core classes
@@ -1,124 +1,5 @@
1
- """Adapter for using AbstractAgent agents as flow nodes."""
1
+ """Re-export: AbstractRuntime VisualFlow compiler adapter."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable, Optional, TYPE_CHECKING
6
-
7
- if TYPE_CHECKING:
8
- from abstractruntime.core.models import RunState, StepPlan
9
- from abstractagent.agents.base import BaseAgent
10
-
11
-
12
- def create_agent_node_handler(
13
- node_id: str,
14
- agent: "BaseAgent",
15
- next_node: Optional[str],
16
- input_key: Optional[str] = None,
17
- output_key: Optional[str] = None,
18
- ) -> Callable:
19
- """Create a node handler that runs an agent as a subworkflow.
20
-
21
- Agent nodes execute the full agent workflow (ReAct loop, CodeAct, etc.)
22
- as a subworkflow. The agent runs to completion before transitioning.
23
-
24
- Args:
25
- node_id: Unique identifier for this node
26
- agent: The agent instance to run
27
- next_node: ID of the next node to transition to (None for terminal)
28
- input_key: Key in run.vars to read task/input from
29
- output_key: Key in run.vars to write agent output to
30
-
31
- Returns:
32
- A node handler function compatible with AbstractRuntime
33
-
34
- Example:
35
- >>> from abstractagent import create_react_agent
36
- >>> planner = create_react_agent(provider="ollama", model="qwen3:4b")
37
- >>> handler = create_agent_node_handler("plan", planner, "search")
38
- """
39
- from abstractruntime.core.models import Effect, EffectType, StepPlan
40
-
41
- def handler(run: "RunState", ctx: Any) -> "StepPlan":
42
- """Start the agent as a subworkflow."""
43
- # Determine task for the agent
44
- task = ""
45
-
46
- if input_key:
47
- input_data = run.vars.get(input_key, {})
48
- if isinstance(input_data, dict):
49
- task = input_data.get("task", "") or input_data.get("query", "")
50
- if not task:
51
- # Use the whole input as context
52
- task = str(input_data)
53
- else:
54
- task = str(input_data)
55
-
56
- # Fallback to flow's main task
57
- if not task:
58
- context = run.vars.get("context", {})
59
- if isinstance(context, dict):
60
- task = context.get("task", "")
61
-
62
- if not task:
63
- task = f"Execute {node_id} step"
64
-
65
- # Build initial vars for the agent subworkflow
66
- max_iterations = getattr(agent, "_max_iterations", 25)
67
- max_history_messages = getattr(agent, "_max_history_messages", -1)
68
- max_tokens = getattr(agent, "_max_tokens", None)
69
- if not isinstance(max_tokens, int) or max_tokens <= 0:
70
- try:
71
- runtime = getattr(agent, "runtime", None)
72
- config = getattr(runtime, "config", None)
73
- base = config.to_limits_dict() if config is not None else {}
74
- max_tokens = int(base.get("max_tokens", 32768) or 32768)
75
- except Exception:
76
- max_tokens = 32768
77
-
78
- agent_vars = {
79
- "context": {
80
- "task": task,
81
- "messages": [],
82
- },
83
- "scratchpad": {
84
- "iteration": 0,
85
- "max_iterations": max_iterations,
86
- "max_history_messages": max_history_messages,
87
- },
88
- "_runtime": {"inbox": []},
89
- "_temp": {},
90
- # Canonical _limits namespace for runtime awareness
91
- "_limits": {
92
- "max_iterations": max_iterations,
93
- "current_iteration": 0,
94
- "max_tokens": max_tokens,
95
- "max_history_messages": max_history_messages,
96
- "estimated_tokens_used": 0,
97
- "warn_iterations_pct": 80,
98
- "warn_tokens_pct": 80,
99
- },
100
- }
101
-
102
- # Inject any additional context from the flow
103
- if input_key and isinstance(run.vars.get(input_key), dict):
104
- # Merge additional context
105
- for k, v in run.vars.get(input_key, {}).items():
106
- if k not in ("task", "query"):
107
- agent_vars["context"][k] = v
108
-
109
- # Use START_SUBWORKFLOW effect to run agent durably
110
- return StepPlan(
111
- node_id=node_id,
112
- effect=Effect(
113
- type=EffectType.START_SUBWORKFLOW,
114
- payload={
115
- "workflow_id": agent.workflow.workflow_id,
116
- "vars": agent_vars,
117
- "async": False, # Sync: wait for completion
118
- },
119
- result_key=output_key or f"_flow.{node_id}.result",
120
- ),
121
- next_node=next_node,
122
- )
123
-
124
- return handler
5
+ from abstractruntime.visualflow_compiler.adapters.agent_adapter import * # noqa: F401,F403