abstractflow 0.1.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 +74 -94
- abstractflow/__main__.py +2 -0
- abstractflow/adapters/__init__.py +11 -0
- abstractflow/adapters/agent_adapter.py +5 -0
- abstractflow/adapters/control_adapter.py +5 -0
- abstractflow/adapters/effect_adapter.py +5 -0
- abstractflow/adapters/event_adapter.py +5 -0
- abstractflow/adapters/function_adapter.py +5 -0
- abstractflow/adapters/subflow_adapter.py +5 -0
- abstractflow/adapters/variable_adapter.py +5 -0
- abstractflow/cli.py +75 -28
- abstractflow/compiler.py +23 -0
- abstractflow/core/__init__.py +5 -0
- abstractflow/core/flow.py +11 -0
- abstractflow/py.typed +2 -0
- abstractflow/runner.py +402 -0
- abstractflow/visual/__init__.py +43 -0
- abstractflow/visual/agent_ids.py +5 -0
- abstractflow/visual/builtins.py +5 -0
- abstractflow/visual/code_executor.py +5 -0
- abstractflow/visual/event_ids.py +33 -0
- abstractflow/visual/executor.py +968 -0
- abstractflow/visual/interfaces.py +440 -0
- abstractflow/visual/models.py +277 -0
- abstractflow/visual/session_runner.py +182 -0
- abstractflow/visual/workspace_scoped_tools.py +29 -0
- abstractflow/workflow_bundle.py +290 -0
- abstractflow-0.3.1.dist-info/METADATA +186 -0
- abstractflow-0.3.1.dist-info/RECORD +33 -0
- {abstractflow-0.1.0.dist-info → abstractflow-0.3.1.dist-info}/WHEEL +1 -1
- {abstractflow-0.1.0.dist-info → abstractflow-0.3.1.dist-info}/licenses/LICENSE +2 -0
- abstractflow-0.1.0.dist-info/METADATA +0 -238
- abstractflow-0.1.0.dist-info/RECORD +0 -10
- {abstractflow-0.1.0.dist-info → abstractflow-0.3.1.dist-info}/entry_points.txt +0 -0
- {abstractflow-0.1.0.dist-info → abstractflow-0.3.1.dist-info}/top_level.txt +0 -0
abstractflow/__init__.py
CHANGED
|
@@ -1,104 +1,84 @@
|
|
|
1
|
+
"""AbstractFlow - Multi-agent orchestration layer for the Abstract Framework.
|
|
2
|
+
|
|
3
|
+
AbstractFlow enables composition of agents into pipelines and coordinates
|
|
4
|
+
their execution via AbstractRuntime. It provides:
|
|
5
|
+
|
|
6
|
+
- Flow: Declarative flow definition with nodes and edges
|
|
7
|
+
- FlowRunner: High-level interface for running flows
|
|
8
|
+
- compile_flow: Convert Flow to WorkflowSpec for direct runtime usage
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> from abstractflow import Flow, FlowRunner
|
|
12
|
+
>>>
|
|
13
|
+
>>> # Define a simple flow
|
|
14
|
+
>>> flow = Flow("my_pipeline")
|
|
15
|
+
>>> flow.add_node("step1", lambda x: x * 2, input_key="value", output_key="doubled")
|
|
16
|
+
>>> flow.add_node("step2", lambda x: x + 10, input_key="doubled", output_key="result")
|
|
17
|
+
>>> flow.add_edge("step1", "step2")
|
|
18
|
+
>>> flow.set_entry("step1")
|
|
19
|
+
>>>
|
|
20
|
+
>>> # Run the flow
|
|
21
|
+
>>> runner = FlowRunner(flow)
|
|
22
|
+
>>> result = runner.run({"value": 5})
|
|
23
|
+
>>> print(result) # {'result': 20, 'success': True}
|
|
24
|
+
|
|
25
|
+
For agent-based flows:
|
|
26
|
+
>>> from abstractflow import Flow, FlowRunner
|
|
27
|
+
>>> from abstractagent import create_react_agent
|
|
28
|
+
>>>
|
|
29
|
+
>>> planner = create_react_agent(provider="ollama", model="qwen3:4b")
|
|
30
|
+
>>> executor = create_react_agent(provider="ollama", model="qwen3:4b")
|
|
31
|
+
>>>
|
|
32
|
+
>>> flow = Flow("plan_and_execute")
|
|
33
|
+
>>> flow.add_node("plan", planner, output_key="plan")
|
|
34
|
+
>>> flow.add_node("execute", executor, input_key="plan")
|
|
35
|
+
>>> flow.add_edge("plan", "execute")
|
|
36
|
+
>>> flow.set_entry("plan")
|
|
37
|
+
>>>
|
|
38
|
+
>>> runner = FlowRunner(flow)
|
|
39
|
+
>>> result = runner.run({"context": {"task": "Build a REST API"}})
|
|
1
40
|
"""
|
|
2
|
-
AbstractFlow - Diagram-based AI workflow generation.
|
|
3
41
|
|
|
4
|
-
|
|
5
|
-
""
|
|
6
|
-
|
|
7
|
-
__version__ = "0.1.0"
|
|
8
|
-
__author__ = "AbstractFlow Team"
|
|
42
|
+
__version__ = "0.3.1"
|
|
43
|
+
__author__ = "Laurent-Philippe Albou"
|
|
9
44
|
__email__ = "contact@abstractflow.ai"
|
|
10
45
|
__license__ = "MIT"
|
|
11
46
|
|
|
12
|
-
# Core
|
|
13
|
-
|
|
14
|
-
"__version__",
|
|
15
|
-
"WorkflowBuilder",
|
|
16
|
-
"Node",
|
|
17
|
-
"LLMNode",
|
|
18
|
-
"TextNode",
|
|
19
|
-
"ConditionalNode",
|
|
20
|
-
"TransformNode",
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
# Placeholder implementations - these will be replaced with actual implementations
|
|
24
|
-
class WorkflowBuilder:
|
|
25
|
-
"""
|
|
26
|
-
Visual workflow builder for creating AI-powered diagrams.
|
|
27
|
-
|
|
28
|
-
This is a placeholder implementation. The full version will provide:
|
|
29
|
-
- Drag-and-drop workflow creation
|
|
30
|
-
- Real-time execution monitoring
|
|
31
|
-
- Multi-provider LLM support via AbstractCore
|
|
32
|
-
- Export to various formats
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def __init__(self):
|
|
36
|
-
"""Initialize a new workflow builder."""
|
|
37
|
-
raise NotImplementedError(
|
|
38
|
-
"AbstractFlow is currently in development. "
|
|
39
|
-
"This placeholder package reserves the PyPI name. "
|
|
40
|
-
"Follow https://github.com/lpalbou/AbstractFlow for updates."
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class Node:
|
|
45
|
-
"""Base class for all workflow nodes."""
|
|
46
|
-
|
|
47
|
-
def __init__(self, node_id: str):
|
|
48
|
-
"""Initialize a workflow node."""
|
|
49
|
-
raise NotImplementedError(
|
|
50
|
-
"AbstractFlow is currently in development. "
|
|
51
|
-
"This placeholder package reserves the PyPI name. "
|
|
52
|
-
"Follow https://github.com/lpalbou/AbstractFlow for updates."
|
|
53
|
-
)
|
|
47
|
+
# Core classes
|
|
48
|
+
from .core.flow import Flow, FlowNode, FlowEdge
|
|
54
49
|
|
|
50
|
+
# Compiler
|
|
51
|
+
from .compiler import compile_flow
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def __init__(self, provider: str, model: str, **kwargs):
|
|
60
|
-
"""Initialize an LLM node with AbstractCore provider."""
|
|
61
|
-
raise NotImplementedError(
|
|
62
|
-
"AbstractFlow is currently in development. "
|
|
63
|
-
"This placeholder package reserves the PyPI name. "
|
|
64
|
-
"Follow https://github.com/lpalbou/AbstractFlow for updates."
|
|
65
|
-
)
|
|
53
|
+
# Runner
|
|
54
|
+
from .runner import FlowRunner
|
|
66
55
|
|
|
56
|
+
# Adapters (for advanced usage)
|
|
57
|
+
from .adapters import (
|
|
58
|
+
create_function_node_handler,
|
|
59
|
+
create_agent_node_handler,
|
|
60
|
+
create_subflow_node_handler,
|
|
61
|
+
)
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
""
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"This placeholder package reserves the PyPI name. "
|
|
88
|
-
"Follow https://github.com/lpalbou/AbstractFlow for updates."
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
class TransformNode(Node):
|
|
93
|
-
"""Node for data transformation operations."""
|
|
94
|
-
|
|
95
|
-
def __init__(self, transform_func: str):
|
|
96
|
-
"""Initialize a transform node."""
|
|
97
|
-
raise NotImplementedError(
|
|
98
|
-
"AbstractFlow is currently in development. "
|
|
99
|
-
"This placeholder package reserves the PyPI name. "
|
|
100
|
-
"Follow https://github.com/lpalbou/AbstractFlow for updates."
|
|
101
|
-
)
|
|
63
|
+
__all__ = [
|
|
64
|
+
# Version info
|
|
65
|
+
"__version__",
|
|
66
|
+
"__author__",
|
|
67
|
+
"__email__",
|
|
68
|
+
"__license__",
|
|
69
|
+
# Core classes
|
|
70
|
+
"Flow",
|
|
71
|
+
"FlowNode",
|
|
72
|
+
"FlowEdge",
|
|
73
|
+
# Compiler
|
|
74
|
+
"compile_flow",
|
|
75
|
+
# Runner
|
|
76
|
+
"FlowRunner",
|
|
77
|
+
# Adapters
|
|
78
|
+
"create_function_node_handler",
|
|
79
|
+
"create_agent_node_handler",
|
|
80
|
+
"create_subflow_node_handler",
|
|
81
|
+
]
|
|
102
82
|
|
|
103
83
|
|
|
104
84
|
def get_version() -> str:
|
|
@@ -107,5 +87,5 @@ def get_version() -> str:
|
|
|
107
87
|
|
|
108
88
|
|
|
109
89
|
def is_development_version() -> bool:
|
|
110
|
-
"""Check if this is a development
|
|
111
|
-
return
|
|
90
|
+
"""Check if this is a development version."""
|
|
91
|
+
return False # Now implemented!
|
abstractflow/__main__.py
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""AbstractFlow adapters for converting handlers to workflow nodes."""
|
|
2
|
+
|
|
3
|
+
from .function_adapter import create_function_node_handler
|
|
4
|
+
from .agent_adapter import create_agent_node_handler
|
|
5
|
+
from .subflow_adapter import create_subflow_node_handler
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"create_function_node_handler",
|
|
9
|
+
"create_agent_node_handler",
|
|
10
|
+
"create_subflow_node_handler",
|
|
11
|
+
]
|
abstractflow/cli.py
CHANGED
|
@@ -1,42 +1,89 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""Command-line interface for AbstractFlow.
|
|
2
|
+
|
|
3
|
+
Current implemented features:
|
|
4
|
+
- WorkflowBundle (.flow) pack/inspect/unpack (backlog 314)
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
Other commands are intentionally kept minimal for now.
|
|
5
7
|
"""
|
|
6
8
|
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
7
13
|
import sys
|
|
8
14
|
from typing import List, Optional
|
|
9
15
|
|
|
16
|
+
from .workflow_bundle import inspect_workflow_bundle, pack_workflow_bundle, unpack_workflow_bundle
|
|
17
|
+
from abstractruntime.workflow_bundle import workflow_bundle_manifest_to_dict
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
21
|
+
p = argparse.ArgumentParser(prog="abstractflow", add_help=True)
|
|
22
|
+
sub = p.add_subparsers(dest="command")
|
|
23
|
+
|
|
24
|
+
bundle = sub.add_parser("bundle", help="WorkflowBundle (.flow) tools")
|
|
25
|
+
bundle_sub = bundle.add_subparsers(dest="bundle_cmd")
|
|
26
|
+
|
|
27
|
+
pack = bundle_sub.add_parser("pack", help="Pack a .flow bundle from a root VisualFlow JSON file")
|
|
28
|
+
pack.add_argument("root", help="Path to root VisualFlow JSON (e.g., ./flows/<id>.json)")
|
|
29
|
+
pack.add_argument("--out", required=True, help="Output .flow path")
|
|
30
|
+
pack.add_argument("--bundle-id", default=None, help="Bundle id (default: root flow id)")
|
|
31
|
+
pack.add_argument("--bundle-version", default="0.0.0", help="Bundle version (default: 0.0.0)")
|
|
32
|
+
pack.add_argument("--flows-dir", default=None, help="Directory containing flow JSON files (default: root's directory)")
|
|
33
|
+
pack.add_argument(
|
|
34
|
+
"--entrypoint",
|
|
35
|
+
action="append",
|
|
36
|
+
default=None,
|
|
37
|
+
help="Entrypoint flow id (repeatable). Default: root flow id",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
insp = bundle_sub.add_parser("inspect", help="Print bundle manifest (JSON)")
|
|
41
|
+
insp.add_argument("bundle", help="Path to .flow (zip) or extracted directory")
|
|
42
|
+
|
|
43
|
+
unpack = bundle_sub.add_parser("unpack", help="Extract a .flow bundle to a directory")
|
|
44
|
+
unpack.add_argument("bundle", help="Path to .flow (zip) or extracted directory")
|
|
45
|
+
unpack.add_argument("--dir", required=True, help="Output directory")
|
|
46
|
+
|
|
47
|
+
return p
|
|
48
|
+
|
|
10
49
|
|
|
11
50
|
def main(args: Optional[List[str]] = None) -> int:
|
|
12
|
-
"""
|
|
13
|
-
Main entry point for the AbstractFlow CLI.
|
|
14
|
-
|
|
15
|
-
Args:
|
|
16
|
-
args: Command-line arguments (defaults to sys.argv[1:])
|
|
17
|
-
|
|
18
|
-
Returns:
|
|
19
|
-
Exit code (0 for success, non-zero for error)
|
|
20
|
-
"""
|
|
21
51
|
if args is None:
|
|
22
52
|
args = sys.argv[1:]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
53
|
+
|
|
54
|
+
parser = _build_parser()
|
|
55
|
+
ns = parser.parse_args(args)
|
|
56
|
+
|
|
57
|
+
if ns.command == "bundle":
|
|
58
|
+
if ns.bundle_cmd == "pack":
|
|
59
|
+
packed = pack_workflow_bundle(
|
|
60
|
+
root_flow_json=ns.root,
|
|
61
|
+
out_path=ns.out,
|
|
62
|
+
bundle_id=ns.bundle_id,
|
|
63
|
+
bundle_version=ns.bundle_version,
|
|
64
|
+
flows_dir=ns.flows_dir,
|
|
65
|
+
entrypoints=list(ns.entrypoint) if isinstance(ns.entrypoint, list) and ns.entrypoint else None,
|
|
66
|
+
)
|
|
67
|
+
sys.stdout.write(str(packed.path) + "\n")
|
|
68
|
+
return 0
|
|
69
|
+
|
|
70
|
+
if ns.bundle_cmd == "inspect":
|
|
71
|
+
man = inspect_workflow_bundle(bundle_path=ns.bundle)
|
|
72
|
+
sys.stdout.write(json.dumps(workflow_bundle_manifest_to_dict(man), indent=2, ensure_ascii=False) + "\n")
|
|
73
|
+
return 0
|
|
74
|
+
|
|
75
|
+
if ns.bundle_cmd == "unpack":
|
|
76
|
+
out = unpack_workflow_bundle(bundle_path=ns.bundle, out_dir=ns.dir)
|
|
77
|
+
sys.stdout.write(str(out) + "\n")
|
|
78
|
+
return 0
|
|
79
|
+
|
|
80
|
+
parser.error("Missing bundle subcommand (pack|inspect|unpack)")
|
|
81
|
+
|
|
82
|
+
parser.print_help()
|
|
38
83
|
return 0
|
|
39
84
|
|
|
40
85
|
|
|
41
86
|
if __name__ == "__main__":
|
|
42
|
-
|
|
87
|
+
raise SystemExit(main())
|
|
88
|
+
|
|
89
|
+
|
abstractflow/compiler.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""AbstractFlow compiler shim.
|
|
2
|
+
|
|
3
|
+
AbstractFlow no longer owns workflow compilation semantics. The single source of
|
|
4
|
+
truth for VisualFlow/Flow compilation lives in `abstractruntime.visualflow_compiler`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from abstractruntime.visualflow_compiler.compiler import (
|
|
10
|
+
_create_visual_agent_effect_handler,
|
|
11
|
+
_sync_effect_results_to_node_outputs,
|
|
12
|
+
compile_flow,
|
|
13
|
+
compile_visualflow,
|
|
14
|
+
compile_visualflow_tree,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"compile_flow",
|
|
19
|
+
"compile_visualflow",
|
|
20
|
+
"compile_visualflow_tree",
|
|
21
|
+
"_create_visual_agent_effect_handler",
|
|
22
|
+
"_sync_effect_results_to_node_outputs",
|
|
23
|
+
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Flow definition classes for AbstractFlow.
|
|
2
|
+
|
|
3
|
+
This module is a thin re-export of AbstractRuntime's Flow IR so there is a
|
|
4
|
+
single semantics + IR surface shared across hosts.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from abstractruntime.visualflow_compiler.flow import Flow, FlowEdge, FlowNode
|
|
10
|
+
|
|
11
|
+
__all__ = ["Flow", "FlowNode", "FlowEdge"]
|
abstractflow/py.typed
CHANGED