model-compose 0.2.0__tar.gz → 0.2.2__tar.gz
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.
- {model_compose-0.2.0 → model_compose-0.2.2}/PKG-INFO +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/pyproject.toml +1 -1
- {model_compose-0.2.0/src/mindor/core/component/engine → model_compose-0.2.2/src/mindor/core/component}/base.py +25 -3
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/component.py +5 -3
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/engine/__init__.py +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/engine/http_client.py +8 -9
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/engine/http_server.py +6 -6
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/engine/mcp_client.py +5 -6
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/engine/mcp_server.py +6 -6
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/engine/shell.py +5 -6
- model_compose-0.2.2/src/mindor/core/component/engine/workflow.py +40 -0
- {model_compose-0.2.0/src/mindor/core/controller/engine → model_compose-0.2.2/src/mindor/core/controller}/base.py +28 -12
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/controller.py +4 -2
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/engine/__init__.py +0 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/engine/http_server.py +5 -8
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/engine/mcp_server.py +20 -26
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/runner/mcp_client.py +10 -11
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/runner/runner.py +3 -4
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/webui/gradio.py +31 -34
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/webui/webui.py +1 -3
- model_compose-0.2.2/src/mindor/core/gateway/__init__.py +2 -0
- {model_compose-0.2.0/src/mindor/core/gateway/engine → model_compose-0.2.2/src/mindor/core/gateway}/base.py +7 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/gateway/engine/__init__.py +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/gateway/engine/http_tunnel.py +5 -6
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/gateway/engine/ssh_tunnel.py +2 -3
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/gateway/gateway.py +4 -2
- {model_compose-0.2.0/src/mindor/core/listener/engine → model_compose-0.2.2/src/mindor/core/listener}/base.py +7 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/listener/engine/__init__.py +0 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/listener/engine/http_callback.py +2 -3
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/listener/listener.py +4 -2
- {model_compose-0.2.0/src/mindor/core/workflow/job/impl → model_compose-0.2.2/src/mindor/core/workflow/job}/base.py +10 -3
- model_compose-0.2.2/src/mindor/core/workflow/job/impl/__init__.py +2 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/workflow/job/impl/action.py +7 -8
- model_compose-0.2.0/src/mindor/core/workflow/job/impl/wait.py → model_compose-0.2.2/src/mindor/core/workflow/job/impl/delay.py +11 -12
- model_compose-0.2.2/src/mindor/core/workflow/job/job.py +10 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/workflow/workflow.py +9 -9
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/action.py +3 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/__init__.py +1 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/common.py +2 -2
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/http_client.py +26 -21
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/http_server.py +2 -2
- model_compose-0.2.2/src/mindor/dsl/schema/action/impl/workflow.py +8 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/component.py +1 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/__init__.py +1 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/common.py +4 -2
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/http_client.py +2 -2
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/types.py +1 -0
- model_compose-0.2.2/src/mindor/dsl/schema/component/impl/workflow.py +17 -0
- model_compose-0.2.2/src/mindor/dsl/schema/controller/impl/common.py +13 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/controller/impl/http_server.py +4 -4
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/controller/impl/mcp_server.py +3 -3
- model_compose-0.2.2/src/mindor/dsl/schema/controller/impl/webui.py +11 -0
- model_compose-0.2.2/src/mindor/dsl/schema/gateway/impl/common.py +9 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/gateway/impl/http_tunnel.py +5 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/job/impl/__init__.py +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/job/impl/common.py +1 -1
- model_compose-0.2.0/src/mindor/dsl/schema/job/impl/wait.py → model_compose-0.2.2/src/mindor/dsl/schema/job/impl/delay.py +11 -11
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/job/impl/types.py +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/job/job.py +1 -1
- model_compose-0.2.2/src/mindor/dsl/schema/listener/impl/common.py +9 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/listener/impl/http_callback.py +8 -8
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/runtime/impl/common.py +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/runtime/runtime.py +5 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/model_compose.egg-info/PKG-INFO +1 -1
- {model_compose-0.2.0 → model_compose-0.2.2}/src/model_compose.egg-info/SOURCES.txt +11 -8
- model_compose-0.2.0/src/mindor/core/gateway/__init__.py +0 -2
- model_compose-0.2.0/src/mindor/core/workflow/job/impl/__init__.py +0 -3
- model_compose-0.2.0/src/mindor/core/workflow/job/job.py +0 -7
- model_compose-0.2.0/src/mindor/dsl/schema/controller/impl/common.py +0 -12
- model_compose-0.2.0/src/mindor/dsl/schema/controller/impl/webui.py +0 -7
- model_compose-0.2.0/src/mindor/dsl/schema/gateway/impl/common.py +0 -8
- model_compose-0.2.0/src/mindor/dsl/schema/listener/impl/common.py +0 -8
- {model_compose-0.2.0 → model_compose-0.2.2}/LICENSE +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/README.md +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/setup.cfg +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/cli/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/cli/compose.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/component/__init__.py +0 -0
- {model_compose-0.2.0/src/mindor/core/component/engine → model_compose-0.2.2/src/mindor/core/component}/context.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/compose/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/compose/compose.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/compose/manager.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/runner/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/runner/client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/runner/http_client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/webui/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/listener/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/runtime/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/runtime/env.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/services/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/services/async_service.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/expiring.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/http_client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/http_request.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/http_status.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/image.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/mcp_client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/renderer.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/ssh_client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/streaming.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/time.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/utils/workqueue.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/workflow/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/workflow/context.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/workflow/job/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/workflow/schema.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/loader.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/compose.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/controller/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/controller/controller.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/job/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/job/impl/action.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/listener/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/listener/listener.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/runtime/impl/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/runtime/impl/docker.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/runtime/impl/types.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/utils/__init__.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/utils/annotation.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/dsl/schema/workflow.py +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/model_compose.egg-info/dependency_links.txt +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/model_compose.egg-info/entry_points.txt +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/model_compose.egg-info/requires.txt +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/src/model_compose.egg-info/top_level.txt +0 -0
- {model_compose-0.2.0 → model_compose-0.2.2}/tests/test_cli.py +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Callable, Any
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
|
-
|
|
4
3
|
from mindor.dsl.schema.component import ComponentConfig, ComponentType
|
|
5
4
|
from mindor.dsl.schema.action import ActionConfig
|
|
5
|
+
from mindor.dsl.schema.listener import ListenerConfig
|
|
6
|
+
from mindor.dsl.schema.gateway import GatewayConfig
|
|
7
|
+
from mindor.dsl.schema.workflow import WorkflowConfig
|
|
6
8
|
from mindor.core.services import AsyncService
|
|
7
9
|
from mindor.core.utils.workqueue import WorkQueue
|
|
8
10
|
from .context import ComponentActionContext
|
|
@@ -30,12 +32,26 @@ class ActionResolver:
|
|
|
30
32
|
|
|
31
33
|
return default_ids[0] if default_ids else "__default__"
|
|
32
34
|
|
|
35
|
+
class ComponentGlobalConfigs:
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
components: Dict[str, ComponentConfig],
|
|
39
|
+
listeners: List[ListenerConfig],
|
|
40
|
+
gateways: List[GatewayConfig],
|
|
41
|
+
workflows: Dict[str, WorkflowConfig]
|
|
42
|
+
):
|
|
43
|
+
self.components: Dict[str, ComponentConfig] = components
|
|
44
|
+
self.listeners: List[ListenerConfig] = listeners
|
|
45
|
+
self.gateways: List[GatewayConfig] = gateways
|
|
46
|
+
self.workflows: Dict[str, WorkflowConfig] = workflows
|
|
47
|
+
|
|
33
48
|
class ComponentEngine(AsyncService):
|
|
34
|
-
def __init__(self, id: str, config: ComponentConfig, daemon: bool):
|
|
49
|
+
def __init__(self, id: str, config: ComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
35
50
|
super().__init__(daemon)
|
|
36
51
|
|
|
37
52
|
self.id: str = id
|
|
38
53
|
self.config: ComponentConfig = config
|
|
54
|
+
self.global_configs: ComponentGlobalConfigs = global_configs
|
|
39
55
|
self.queue: Optional[WorkQueue] = None
|
|
40
56
|
|
|
41
57
|
if self.config.max_concurrent_count > 0:
|
|
@@ -66,4 +82,10 @@ class ComponentEngine(AsyncService):
|
|
|
66
82
|
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
67
83
|
pass
|
|
68
84
|
|
|
69
|
-
|
|
85
|
+
def register_component(type: ComponentType):
|
|
86
|
+
def decorator(cls: Type[ComponentEngine]) -> Type[ComponentEngine]:
|
|
87
|
+
ComponentRegistry[type] = cls
|
|
88
|
+
return cls
|
|
89
|
+
return decorator
|
|
90
|
+
|
|
91
|
+
ComponentRegistry: Dict[ComponentType, Type[ComponentEngine]] = {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from mindor.dsl.schema.component import ComponentConfig
|
|
3
|
-
from .
|
|
3
|
+
from .base import ComponentEngine, ComponentGlobalConfigs, ComponentRegistry
|
|
4
4
|
|
|
5
5
|
ComponentInstances: Dict[str, ComponentEngine] = {}
|
|
6
6
|
|
|
@@ -27,12 +27,14 @@ class ComponentResolver:
|
|
|
27
27
|
|
|
28
28
|
return default_ids[0] if default_ids else "__default__"
|
|
29
29
|
|
|
30
|
-
def create_component(id: str, config: ComponentConfig, daemon: bool) -> ComponentEngine:
|
|
30
|
+
def create_component(id: str, config: ComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool) -> ComponentEngine:
|
|
31
31
|
try:
|
|
32
32
|
component = ComponentInstances[id] if id in ComponentInstances else None
|
|
33
33
|
|
|
34
34
|
if not component:
|
|
35
|
-
|
|
35
|
+
if not ComponentRegistry:
|
|
36
|
+
from . import engine
|
|
37
|
+
component = ComponentRegistry[config.type](id, config, global_configs, daemon)
|
|
36
38
|
ComponentInstances[id] = component
|
|
37
39
|
|
|
38
40
|
return component
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, AsyncIterator, Any
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
from mindor.dsl.schema.component import HttpClientComponentConfig
|
|
4
|
-
from mindor.dsl.schema.action import ActionConfig, HttpClientActionConfig, HttpClientCompletionConfig
|
|
4
|
+
from mindor.dsl.schema.action import ActionConfig, HttpClientActionConfig, HttpClientCompletionType, HttpClientCompletionConfig
|
|
5
5
|
from mindor.core.listener import HttpCallbackListener
|
|
6
6
|
from mindor.core.utils.http_client import HttpClient
|
|
7
7
|
from mindor.core.utils.http_status import is_status_code_matched
|
|
8
8
|
from mindor.core.utils.time import parse_duration
|
|
9
|
-
from
|
|
10
|
-
from
|
|
9
|
+
from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
|
|
10
|
+
from ..context import ComponentActionContext
|
|
11
11
|
from datetime import datetime, timezone
|
|
12
12
|
import asyncio
|
|
13
13
|
|
|
@@ -79,11 +79,11 @@ class HttpClientAction:
|
|
|
79
79
|
self._configure_completion()
|
|
80
80
|
|
|
81
81
|
def _configure_completion(self) -> None:
|
|
82
|
-
if self.config.completion.type ==
|
|
82
|
+
if self.config.completion.type == HttpClientCompletionType.POLLING:
|
|
83
83
|
self.completion = HttpClientPollingCompletion(self.config.completion)
|
|
84
84
|
return
|
|
85
85
|
|
|
86
|
-
if self.config.completion.type ==
|
|
86
|
+
if self.config.completion.type == HttpClientCompletionType.CALLBACK:
|
|
87
87
|
self.completion = HttpClientCallbackCompletion(self.config.completion)
|
|
88
88
|
return
|
|
89
89
|
|
|
@@ -111,9 +111,10 @@ class HttpClientAction:
|
|
|
111
111
|
|
|
112
112
|
return await context.render_variable(self.config.endpoint)
|
|
113
113
|
|
|
114
|
+
@register_component(ComponentType.HTTP_CLIENT)
|
|
114
115
|
class HttpClientComponent(ComponentEngine):
|
|
115
|
-
def __init__(self, id: str, config: HttpClientComponentConfig, daemon: bool):
|
|
116
|
-
super().__init__(id, config, daemon)
|
|
116
|
+
def __init__(self, id: str, config: HttpClientComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
117
|
+
super().__init__(id, config, global_configs, daemon)
|
|
117
118
|
|
|
118
119
|
self.client: HttpClient = None
|
|
119
120
|
|
|
@@ -126,5 +127,3 @@ class HttpClientComponent(ComponentEngine):
|
|
|
126
127
|
|
|
127
128
|
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
128
129
|
return await HttpClientAction(action).run(context, self.client)
|
|
129
|
-
|
|
130
|
-
ComponentEngineMap[ComponentType.HTTP_CLIENT] = HttpClientComponent
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from mindor.dsl.schema.component import HttpServerComponentConfig
|
|
3
|
-
from .
|
|
4
|
-
from
|
|
3
|
+
from mindor.dsl.schema.action import ActionConfig, HttpServerActionConfig
|
|
4
|
+
from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
|
|
5
|
+
from ..context import ComponentActionContext
|
|
5
6
|
|
|
7
|
+
@register_component(ComponentType.HTTP_SERVER)
|
|
6
8
|
class HttpServerComponent(ComponentEngine):
|
|
7
|
-
def __init__(self, id: str, config: HttpServerComponentConfig, daemon: bool):
|
|
8
|
-
super().__init__(id, config, daemon)
|
|
9
|
+
def __init__(self, id: str, config: HttpServerComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
10
|
+
super().__init__(id, config, global_configs, daemon)
|
|
9
11
|
|
|
10
12
|
async def _serve(self) -> None:
|
|
11
13
|
pass
|
|
@@ -15,5 +17,3 @@ class HttpServerComponent(ComponentEngine):
|
|
|
15
17
|
|
|
16
18
|
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
17
19
|
return {}
|
|
18
|
-
|
|
19
|
-
ComponentEngineMap[ComponentType.HTTP_SERVER] = HttpServerComponent
|
|
@@ -2,8 +2,8 @@ from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annot
|
|
|
2
2
|
from mindor.dsl.schema.component import McpClientComponentConfig
|
|
3
3
|
from mindor.dsl.schema.action import ActionConfig, McpClientActionConfig
|
|
4
4
|
from mindor.core.utils.mcp_client import McpClient, ContentBlock, TextContent, ImageContent, AudioContent
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
|
|
6
|
+
from ..context import ComponentActionContext
|
|
7
7
|
|
|
8
8
|
class McpClientAction():
|
|
9
9
|
def __init__(self, config: McpClientActionConfig):
|
|
@@ -27,9 +27,10 @@ class McpClientAction():
|
|
|
27
27
|
|
|
28
28
|
return None
|
|
29
29
|
|
|
30
|
+
@register_component(ComponentType.MCP_CLIENT)
|
|
30
31
|
class McpClientComponent(ComponentEngine):
|
|
31
|
-
def __init__(self, id: str, config: McpClientComponentConfig, daemon: bool):
|
|
32
|
-
super().__init__(id, config, daemon)
|
|
32
|
+
def __init__(self, id: str, config: McpClientComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
33
|
+
super().__init__(id, config, global_configs, daemon)
|
|
33
34
|
|
|
34
35
|
async def _serve(self) -> None:
|
|
35
36
|
self.client = McpClient(self.config.url, self.config.headers)
|
|
@@ -40,5 +41,3 @@ class McpClientComponent(ComponentEngine):
|
|
|
40
41
|
|
|
41
42
|
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
42
43
|
return await McpClientAction(action).run(context, self.client)
|
|
43
|
-
|
|
44
|
-
ComponentEngineMap[ComponentType.MCP_CLIENT] = McpClientComponent
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from mindor.dsl.schema.component import McpServerComponentConfig
|
|
3
|
-
from .
|
|
4
|
-
from
|
|
3
|
+
from mindor.dsl.schema.action import ActionConfig, McpServerActionConfig
|
|
4
|
+
from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
|
|
5
|
+
from ..context import ComponentActionContext
|
|
5
6
|
|
|
7
|
+
@register_component(ComponentType.MCP_SERVER)
|
|
6
8
|
class McpServerComponent(ComponentEngine):
|
|
7
|
-
def __init__(self, id: str, config: McpServerComponentConfig, daemon: bool):
|
|
8
|
-
super().__init__(id, config, daemon)
|
|
9
|
+
def __init__(self, id: str, config: McpServerComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
10
|
+
super().__init__(id, config, global_configs, daemon)
|
|
9
11
|
|
|
10
12
|
async def _serve(self) -> None:
|
|
11
13
|
pass
|
|
@@ -15,5 +17,3 @@ class McpServerComponent(ComponentEngine):
|
|
|
15
17
|
|
|
16
18
|
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
17
19
|
return {}
|
|
18
|
-
|
|
19
|
-
ComponentEngineMap[ComponentType.MCP_SERVER] = McpServerComponent
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from mindor.dsl.schema.component import ShellComponentConfig
|
|
3
3
|
from mindor.dsl.schema.action import ActionConfig, ShellActionConfig
|
|
4
|
-
from
|
|
5
|
-
from
|
|
4
|
+
from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
|
|
5
|
+
from ..context import ComponentActionContext
|
|
6
6
|
from asyncio.subprocess import Process
|
|
7
7
|
import asyncio, os
|
|
8
8
|
|
|
@@ -64,9 +64,10 @@ class ShellAction:
|
|
|
64
64
|
working_dir = self.base_dir or os.getcwd()
|
|
65
65
|
return working_dir
|
|
66
66
|
|
|
67
|
+
@register_component(ComponentType.SHELL)
|
|
67
68
|
class ShellComponent(ComponentEngine):
|
|
68
|
-
def __init__(self, id: str, config: ShellComponentConfig, daemon: bool):
|
|
69
|
-
super().__init__(id, config, daemon)
|
|
69
|
+
def __init__(self, id: str, config: ShellComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
70
|
+
super().__init__(id, config, global_configs, daemon)
|
|
70
71
|
|
|
71
72
|
async def _serve(self) -> None:
|
|
72
73
|
pass
|
|
@@ -76,5 +77,3 @@ class ShellComponent(ComponentEngine):
|
|
|
76
77
|
|
|
77
78
|
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
78
79
|
return await ShellAction(action, self.config.base_dir, self.config.env).run(context)
|
|
79
|
-
|
|
80
|
-
ComponentEngineMap[ComponentType.SHELL] = ShellComponent
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
|
+
from mindor.dsl.schema.component import ComponentConfig, WorkflowComponentConfig
|
|
3
|
+
from mindor.dsl.schema.action import ActionConfig, WorkflowActionConfig
|
|
4
|
+
from mindor.dsl.schema.workflow import WorkflowConfig
|
|
5
|
+
from mindor.core.workflow import Workflow, WorkflowResolver, create_workflow
|
|
6
|
+
from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
|
|
7
|
+
from ..context import ComponentActionContext
|
|
8
|
+
import asyncio, os
|
|
9
|
+
|
|
10
|
+
class WorkflowAction:
|
|
11
|
+
def __init__(self, config: WorkflowActionConfig, global_configs: ComponentGlobalConfigs):
|
|
12
|
+
self.config: WorkflowActionConfig = config
|
|
13
|
+
self.global_configs: ComponentGlobalConfigs = global_configs
|
|
14
|
+
|
|
15
|
+
async def run(self, context: ComponentActionContext) -> Any:
|
|
16
|
+
workflow_id = await context.render_variable(self.config.workflow)
|
|
17
|
+
input = await context.render_variable(self.config.input)
|
|
18
|
+
|
|
19
|
+
workflow = self._create_workflow(workflow_id)
|
|
20
|
+
output = await workflow.run(context.call_id, input)
|
|
21
|
+
context.register_source("output", output)
|
|
22
|
+
|
|
23
|
+
return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else output
|
|
24
|
+
|
|
25
|
+
def _create_workflow(self, workflow_id: Optional[str]) -> Workflow:
|
|
26
|
+
return create_workflow(*WorkflowResolver(self.global_configs.workflows).resolve(workflow_id), self.global_configs)
|
|
27
|
+
|
|
28
|
+
@register_component(ComponentType.WORKFLOW)
|
|
29
|
+
class WorkflowComponent(ComponentEngine):
|
|
30
|
+
def __init__(self, id: str, config: WorkflowComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
|
|
31
|
+
super().__init__(id, config, global_configs, daemon)
|
|
32
|
+
|
|
33
|
+
async def _serve(self) -> None:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
async def _shutdown(self) -> None:
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
|
|
40
|
+
return await WorkflowAction(action, self.global_configs).run(context)
|
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
|
+
from enum import Enum
|
|
2
3
|
from dataclasses import dataclass
|
|
3
|
-
|
|
4
4
|
from mindor.dsl.schema.controller import ControllerConfig, ControllerType
|
|
5
5
|
from mindor.dsl.schema.component import ComponentConfig
|
|
6
6
|
from mindor.dsl.schema.listener import ListenerConfig
|
|
7
7
|
from mindor.dsl.schema.gateway import GatewayConfig
|
|
8
8
|
from mindor.dsl.schema.workflow import WorkflowConfig
|
|
9
9
|
from mindor.core.services import AsyncService
|
|
10
|
-
from mindor.core.component import ComponentEngine, create_component
|
|
10
|
+
from mindor.core.component import ComponentEngine, ComponentGlobalConfigs, create_component
|
|
11
11
|
from mindor.core.listener import ListenerEngine, create_listener
|
|
12
12
|
from mindor.core.gateway import GatewayEngine, create_gateway
|
|
13
13
|
from mindor.core.workflow import Workflow, WorkflowResolver, create_workflow
|
|
14
14
|
from mindor.core.controller.webui import ControllerWebUI
|
|
15
15
|
from mindor.core.utils.workqueue import WorkQueue
|
|
16
16
|
from mindor.core.utils.expiring import ExpiringDict
|
|
17
|
-
|
|
18
17
|
from threading import Lock
|
|
19
18
|
import asyncio, ulid
|
|
20
19
|
|
|
20
|
+
class TaskStatus(str, Enum):
|
|
21
|
+
PENDING = "pending"
|
|
22
|
+
PROCESSING = "processing"
|
|
23
|
+
COMPLETED = "completed"
|
|
24
|
+
FAILED = "failed"
|
|
25
|
+
|
|
21
26
|
@dataclass
|
|
22
27
|
class TaskState:
|
|
23
28
|
task_id: str
|
|
24
|
-
status:
|
|
29
|
+
status: TaskStatus
|
|
25
30
|
output: Optional[Any] = None
|
|
26
31
|
error: Optional[Any] = None
|
|
27
32
|
|
|
@@ -51,7 +56,7 @@ class ControllerEngine(AsyncService):
|
|
|
51
56
|
|
|
52
57
|
async def run_workflow(self, workflow_id: Optional[str], input: Dict[str, Any], wait_for_completion: bool = True) -> TaskState:
|
|
53
58
|
task_id = ulid.ulid()
|
|
54
|
-
state = TaskState(task_id=task_id, status=
|
|
59
|
+
state = TaskState(task_id=task_id, status=TaskStatus.PENDING)
|
|
55
60
|
with self.task_states_lock:
|
|
56
61
|
self.task_states.set(task_id, state)
|
|
57
62
|
|
|
@@ -122,16 +127,16 @@ class ControllerEngine(AsyncService):
|
|
|
122
127
|
await asyncio.gather(*[ self._create_webui().stop() ])
|
|
123
128
|
|
|
124
129
|
async def _run_workflow(self, task_id: str, workflow_id: Optional[str], input: Dict[str, Any]) -> TaskState:
|
|
125
|
-
state = TaskState(task_id=task_id, status=
|
|
130
|
+
state = TaskState(task_id=task_id, status=TaskStatus.PROCESSING)
|
|
126
131
|
with self.task_states_lock:
|
|
127
132
|
self.task_states.set(task_id, state)
|
|
128
133
|
|
|
129
134
|
try:
|
|
130
|
-
workflow =
|
|
135
|
+
workflow = self._create_workflow(workflow_id)
|
|
131
136
|
output = await workflow.run(task_id, input)
|
|
132
|
-
state = TaskState(task_id=task_id, status=
|
|
137
|
+
state = TaskState(task_id=task_id, status=TaskStatus.COMPLETED, output=output)
|
|
133
138
|
except Exception as e:
|
|
134
|
-
state = TaskState(task_id=task_id, status=
|
|
139
|
+
state = TaskState(task_id=task_id, status=TaskStatus.FAILED, error=str(e))
|
|
135
140
|
|
|
136
141
|
with self.task_states_lock:
|
|
137
142
|
self.task_states.set(task_id, state, 1 * 3600)
|
|
@@ -139,7 +144,8 @@ class ControllerEngine(AsyncService):
|
|
|
139
144
|
return state
|
|
140
145
|
|
|
141
146
|
def _create_components(self) -> List[ComponentEngine]:
|
|
142
|
-
|
|
147
|
+
global_configs = self._get_component_global_configs()
|
|
148
|
+
return [ create_component(component_id, config, global_configs, self.daemon) for component_id, config in self.components.items() ]
|
|
143
149
|
|
|
144
150
|
def _create_listeners(self) -> List[ListenerEngine]:
|
|
145
151
|
return [ create_listener(f"listener-{index}", config, self.daemon) for index, config in enumerate(self.listeners) ]
|
|
@@ -151,6 +157,16 @@ class ControllerEngine(AsyncService):
|
|
|
151
157
|
return ControllerWebUI(self.config.webui, self.config, self.components, self.workflows, self.daemon)
|
|
152
158
|
|
|
153
159
|
def _create_workflow(self, workflow_id: Optional[str]) -> Workflow:
|
|
154
|
-
|
|
160
|
+
global_configs = self._get_component_global_configs()
|
|
161
|
+
return create_workflow(*WorkflowResolver(self.workflows).resolve(workflow_id), global_configs)
|
|
162
|
+
|
|
163
|
+
def _get_component_global_configs(self) -> ComponentGlobalConfigs:
|
|
164
|
+
return ComponentGlobalConfigs(self.components, self.listeners, self.gateways, self.workflows)
|
|
165
|
+
|
|
166
|
+
def register_controller(type: ControllerType):
|
|
167
|
+
def decorator(cls: Type[ControllerEngine]) -> Type[ControllerEngine]:
|
|
168
|
+
ControllerRegistry[type] = cls
|
|
169
|
+
return cls
|
|
170
|
+
return decorator
|
|
155
171
|
|
|
156
|
-
|
|
172
|
+
ControllerRegistry: Dict[ControllerType, Type[ControllerEngine]] = {}
|
|
@@ -4,7 +4,7 @@ from mindor.dsl.schema.component import ComponentConfig
|
|
|
4
4
|
from mindor.dsl.schema.listener import ListenerConfig
|
|
5
5
|
from mindor.dsl.schema.gateway import GatewayConfig
|
|
6
6
|
from mindor.dsl.schema.workflow import WorkflowConfig
|
|
7
|
-
from .
|
|
7
|
+
from .base import ControllerEngine, ControllerRegistry
|
|
8
8
|
|
|
9
9
|
def create_controller(
|
|
10
10
|
config: ControllerConfig,
|
|
@@ -15,6 +15,8 @@ def create_controller(
|
|
|
15
15
|
daemon: bool
|
|
16
16
|
) -> ControllerEngine:
|
|
17
17
|
try:
|
|
18
|
-
|
|
18
|
+
if not ControllerRegistry:
|
|
19
|
+
from . import engine
|
|
20
|
+
return ControllerRegistry[config.type](config, components, listeners, gateways, workflows, daemon)
|
|
19
21
|
except KeyError:
|
|
20
22
|
raise ValueError(f"Unsupported controller type: {config.type}")
|
{model_compose-0.2.0 → model_compose-0.2.2}/src/mindor/core/controller/engine/http_server.py
RENAMED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from typing_extensions import Self
|
|
3
3
|
from pydantic import BaseModel
|
|
4
|
-
|
|
5
4
|
from mindor.dsl.schema.controller import HttpServerControllerConfig
|
|
6
5
|
from mindor.dsl.schema.component import ComponentConfig
|
|
7
6
|
from mindor.dsl.schema.listener import ListenerConfig
|
|
@@ -9,8 +8,7 @@ from mindor.dsl.schema.gateway import GatewayConfig
|
|
|
9
8
|
from mindor.dsl.schema.workflow import WorkflowConfig
|
|
10
9
|
from mindor.core.utils.http_request import parse_request_body, parse_options_header
|
|
11
10
|
from mindor.core.utils.streaming import StreamResource
|
|
12
|
-
from
|
|
13
|
-
|
|
11
|
+
from ..base import ControllerEngine, ControllerType, TaskState, TaskStatus, register_controller
|
|
14
12
|
from fastapi import FastAPI, APIRouter, Request, Body, HTTPException
|
|
15
13
|
from fastapi.middleware.cors import CORSMiddleware
|
|
16
14
|
from fastapi.responses import Response, JSONResponse, StreamingResponse
|
|
@@ -38,6 +36,7 @@ class TaskResult(BaseModel):
|
|
|
38
36
|
error=instance.error
|
|
39
37
|
)
|
|
40
38
|
|
|
39
|
+
@register_controller(ControllerType.HTTP_SERVER)
|
|
41
40
|
class HttpServerController(ControllerEngine):
|
|
42
41
|
def __init__(
|
|
43
42
|
self,
|
|
@@ -76,7 +75,7 @@ class HttpServerController(ControllerEngine):
|
|
|
76
75
|
state = await self.run_workflow(body.workflow_id, body.input, body.wait_for_completion)
|
|
77
76
|
|
|
78
77
|
if body.output_only and not body.wait_for_completion:
|
|
79
|
-
raise HTTPException(status_code=400, detail="output_only requires wait_for_completion=
|
|
78
|
+
raise HTTPException(status_code=400, detail="output_only requires wait_for_completion=true.")
|
|
80
79
|
|
|
81
80
|
if body.output_only:
|
|
82
81
|
return self._render_task_output(state)
|
|
@@ -130,10 +129,10 @@ class HttpServerController(ControllerEngine):
|
|
|
130
129
|
return JSONResponse(content=TaskResult.from_instance(state).model_dump(exclude_none=True))
|
|
131
130
|
|
|
132
131
|
def _render_task_output(self, state: TaskState) -> Response:
|
|
133
|
-
if state.status in [
|
|
132
|
+
if state.status in [ TaskStatus.PENDING, TaskStatus.PROCESSING ]:
|
|
134
133
|
raise HTTPException(status_code=202, detail="Task is still in progress.")
|
|
135
134
|
|
|
136
|
-
if state.status ==
|
|
135
|
+
if state.status == TaskStatus.FAILED:
|
|
137
136
|
raise HTTPException(status_code=500, detail=str(state.error))
|
|
138
137
|
|
|
139
138
|
if isinstance(state.output, StreamResource):
|
|
@@ -160,5 +159,3 @@ class HttpServerController(ControllerEngine):
|
|
|
160
159
|
headers["Content-Disposition"] = f'attachment; filename="{filename}"'
|
|
161
160
|
|
|
162
161
|
return headers
|
|
163
|
-
|
|
164
|
-
ControllerEngineMap[ControllerType.HTTP_SERVER] = HttpServerController
|
|
@@ -3,12 +3,12 @@ from mindor.dsl.schema.controller import McpServerControllerConfig
|
|
|
3
3
|
from mindor.dsl.schema.component import ComponentConfig
|
|
4
4
|
from mindor.dsl.schema.listener import ListenerConfig
|
|
5
5
|
from mindor.dsl.schema.gateway import GatewayConfig
|
|
6
|
-
from mindor.dsl.schema.workflow import WorkflowConfig, WorkflowVariableConfig
|
|
6
|
+
from mindor.dsl.schema.workflow import WorkflowConfig, WorkflowVariableConfig, WorkflowVariableType, WorkflowVariableFormat
|
|
7
7
|
from mindor.core.workflow.schema import WorkflowSchema, create_workflow_schema
|
|
8
8
|
from mindor.core.utils.streaming import StreamResource, Base64StreamResource
|
|
9
9
|
from mindor.core.utils.streaming import save_stream_to_temporary_file
|
|
10
10
|
from mindor.core.utils.http_client import create_stream_with_url
|
|
11
|
-
from
|
|
11
|
+
from ..base import ControllerEngine, ControllerType, TaskState, register_controller
|
|
12
12
|
from mcp.server.fastmcp.server import FastMCP
|
|
13
13
|
from mcp.types import TextContent, ImageContent, AudioContent
|
|
14
14
|
import uvicorn, re, json
|
|
@@ -35,13 +35,12 @@ class WorkflowToolGenerator():
|
|
|
35
35
|
input: Dict[str, Any] = {}
|
|
36
36
|
|
|
37
37
|
for value, variable in zip(arguments, workflow.input):
|
|
38
|
-
|
|
39
|
-
input[variable.name or "input"] = await self._convert_input_value(value, type, subtype, format, variable.default)
|
|
38
|
+
input[variable.name or "input"] = await self._convert_input_value(value, variable.type, variable.subtype, variable.format, variable.default)
|
|
40
39
|
|
|
41
40
|
return input
|
|
42
41
|
|
|
43
|
-
async def _convert_input_value(self, value: Any, type:
|
|
44
|
-
if type in [
|
|
42
|
+
async def _convert_input_value(self, value: Any, type: WorkflowVariableType, subtype: Optional[str], format: Optional[WorkflowVariableFormat], default: Optional[Any]) -> Any:
|
|
43
|
+
if type in [ WorkflowVariableType.IMAGE, WorkflowVariableType.AUDIO, WorkflowVariableType.VIDEO, WorkflowVariableType.FILE ]:
|
|
45
44
|
if format and format != "path":
|
|
46
45
|
pass
|
|
47
46
|
|
|
@@ -53,23 +52,21 @@ class WorkflowToolGenerator():
|
|
|
53
52
|
if state.output:
|
|
54
53
|
if len(workflow.output) == 1 and not workflow.output[0].name:
|
|
55
54
|
variable = workflow.output[0]
|
|
56
|
-
|
|
57
|
-
output.append(await self._convert_output_value(state.output, type, subtype, format))
|
|
55
|
+
output.append(await self._convert_output_value(state.output, variable.type, variable.subtype, variable.format))
|
|
58
56
|
else:
|
|
59
57
|
for variable in workflow.output:
|
|
60
|
-
|
|
61
|
-
output.append(await self._convert_output_value(state.output[variable.name], type, subtype, format))
|
|
58
|
+
output.append(await self._convert_output_value(state.output[variable.name], variable.type, variable.subtype, variable.format))
|
|
62
59
|
|
|
63
60
|
return output
|
|
64
61
|
|
|
65
|
-
async def _convert_output_value(self, value: Any, type:
|
|
66
|
-
if type in [
|
|
67
|
-
if format ==
|
|
68
|
-
if type ==
|
|
62
|
+
async def _convert_output_value(self, value: Any, type: WorkflowVariableType, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Union[TextContent, ImageContent, AudioContent]:
|
|
63
|
+
if type in [ WorkflowVariableType.IMAGE, WorkflowVariableType.AUDIO, WorkflowVariableType.VIDEO, WorkflowVariableType.FILE ]:
|
|
64
|
+
if format == WorkflowVariableFormat.BASE64 and len(value) < 1024 * 1024: # at most 1MB
|
|
65
|
+
if type == WorkflowVariableType.IMAGE:
|
|
69
66
|
return ImageContent(type="image", data=value, mimeType=f"{type}/{subtype}")
|
|
70
|
-
if type ==
|
|
67
|
+
if type == WorkflowVariableType.AUDIO:
|
|
71
68
|
return AudioContent(type="audio", data=value, mimeType=f"{type}/{subtype}")
|
|
72
|
-
if not format or format not in [
|
|
69
|
+
if not format or format not in [ WorkflowVariableFormat.PATH, WorkflowVariableFormat.URL ]:
|
|
73
70
|
value = await self._save_value_to_temporary_file(value, subtype, format)
|
|
74
71
|
return TextContent(type="text", text=value)
|
|
75
72
|
|
|
@@ -78,11 +75,11 @@ class WorkflowToolGenerator():
|
|
|
78
75
|
|
|
79
76
|
return TextContent(type="text", text=str(value))
|
|
80
77
|
|
|
81
|
-
async def _save_value_to_temporary_file(self, value: Any, subtype: Optional[str], format: Optional[
|
|
82
|
-
if format ==
|
|
78
|
+
async def _save_value_to_temporary_file(self, value: Any, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Optional[str]:
|
|
79
|
+
if format == WorkflowVariableFormat.BASE64 and isinstance(value, str):
|
|
83
80
|
return await save_stream_to_temporary_file(Base64StreamResource(value), subtype)
|
|
84
81
|
|
|
85
|
-
if format ==
|
|
82
|
+
if format == WorkflowVariableFormat.URL and isinstance(value, str):
|
|
86
83
|
return await save_stream_to_temporary_file(await create_stream_with_url(value), subtype)
|
|
87
84
|
|
|
88
85
|
if isinstance(value, StreamResource):
|
|
@@ -119,19 +116,18 @@ class WorkflowToolGenerator():
|
|
|
119
116
|
return "\n".join(lines)
|
|
120
117
|
|
|
121
118
|
def _get_docstring_type(self, variable: WorkflowVariableConfig) -> str:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if type == "object[]":
|
|
119
|
+
if variable.type == WorkflowVariableType.OBJECTS:
|
|
125
120
|
return "list[dict]"
|
|
126
121
|
|
|
127
|
-
if type ==
|
|
122
|
+
if variable.type == WorkflowVariableType.NUMBER:
|
|
128
123
|
return "float"
|
|
129
124
|
|
|
130
|
-
if type ==
|
|
125
|
+
if variable.type == WorkflowVariableType.INTEGER:
|
|
131
126
|
return "int"
|
|
132
127
|
|
|
133
128
|
return "str"
|
|
134
129
|
|
|
130
|
+
@register_controller(ControllerType.MCP_SERVER)
|
|
135
131
|
class McpServerController(ControllerEngine):
|
|
136
132
|
def __init__(
|
|
137
133
|
self,
|
|
@@ -180,5 +176,3 @@ class McpServerController(ControllerEngine):
|
|
|
180
176
|
async def _shutdown(self) -> None:
|
|
181
177
|
if self.server:
|
|
182
178
|
self.server.should_exit = True
|
|
183
|
-
|
|
184
|
-
ControllerEngineMap[ControllerType.MCP_SERVER] = McpServerController
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from mindor.dsl.schema.controller import ControllerConfig
|
|
3
|
+
from mindor.dsl.schema.workflow import WorkflowVariableType, WorkflowVariableFormat
|
|
3
4
|
from mindor.core.workflow.schema import WorkflowSchema
|
|
4
5
|
from mindor.core.utils.mcp_client import McpClient, ContentBlock, TextContent, ImageContent, AudioContent
|
|
5
6
|
from mindor.core.utils.streaming import StreamResource, FileStreamResource, Base64StreamResource
|
|
@@ -29,23 +30,21 @@ class McpControllerClient(ControllerClient):
|
|
|
29
30
|
|
|
30
31
|
if len(workflow.output) == 1 and not workflow.output[0].name:
|
|
31
32
|
content, variable = contents[0], workflow.output[0]
|
|
32
|
-
|
|
33
|
-
return await self._convert_output_value(content, type, subtype, format)
|
|
33
|
+
return await self._convert_output_value(content, variable.type, variable.subtype, variable.format)
|
|
34
34
|
|
|
35
35
|
output = {}
|
|
36
36
|
for content, variable in zip(contents, workflow.output):
|
|
37
|
-
|
|
38
|
-
output[variable.name or "output"] = await self._convert_output_value(content, type, subtype, format)
|
|
37
|
+
output[variable.name or "output"] = await self._convert_output_value(content, variable.type, variable.subtype, variable.format)
|
|
39
38
|
return output
|
|
40
39
|
|
|
41
|
-
async def _convert_output_value(self, content: ContentBlock, type:
|
|
40
|
+
async def _convert_output_value(self, content: ContentBlock, type: WorkflowVariableType, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Any:
|
|
42
41
|
if isinstance(content, TextContent):
|
|
43
|
-
if type in [
|
|
42
|
+
if type in [ WorkflowVariableType.JSON, WorkflowVariableType.OBJECTS ]:
|
|
44
43
|
return json.loads(content.text)
|
|
45
|
-
if type in [
|
|
44
|
+
if type in [ WorkflowVariableType.IMAGE, WorkflowVariableType.AUDIO, WorkflowVariableType.VIDEO, WorkflowVariableType.FILE ]:
|
|
46
45
|
if not format and os.path.exists(content.text):
|
|
47
46
|
return FileStreamResource(content.text)
|
|
48
|
-
if format ==
|
|
47
|
+
if format == WorkflowVariableFormat.BASE64: # content.text is path
|
|
49
48
|
return await encode_stream_to_base64(FileStreamResource(content.text))
|
|
50
49
|
return content.text
|
|
51
50
|
|
|
@@ -54,11 +53,11 @@ class McpControllerClient(ControllerClient):
|
|
|
54
53
|
|
|
55
54
|
return None
|
|
56
55
|
|
|
57
|
-
async def _load_image_from_value(self, value: Any, subtype: Optional[str], format: Optional[
|
|
58
|
-
if format ==
|
|
56
|
+
async def _load_image_from_value(self, value: Any, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Optional[str]:
|
|
57
|
+
if format == WorkflowVariableFormat.BASE64 and isinstance(value, str):
|
|
59
58
|
return await load_image_from_stream(Base64StreamResource(value), subtype)
|
|
60
59
|
|
|
61
|
-
if format ==
|
|
60
|
+
if format == WorkflowVariableFormat.URL and isinstance(value, str):
|
|
62
61
|
return await load_image_from_stream(await create_stream_with_url(value), subtype)
|
|
63
62
|
|
|
64
63
|
if isinstance(value, StreamResource):
|