model-compose 0.2.1__tar.gz → 0.2.3__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.
Files changed (147) hide show
  1. {model_compose-0.2.1 → model_compose-0.2.3}/PKG-INFO +1 -1
  2. {model_compose-0.2.1 → model_compose-0.2.3}/pyproject.toml +1 -1
  3. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/base.py +18 -1
  4. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/component.py +3 -3
  5. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/http_client.py +7 -7
  6. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/http_server.py +4 -3
  7. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/mcp_client.py +3 -3
  8. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/mcp_server.py +4 -3
  9. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/shell.py +3 -3
  10. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/workflow.py +7 -8
  11. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/base.py +20 -10
  12. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/engine/http_server.py +4 -4
  13. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/engine/mcp_server.py +18 -23
  14. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/runner/mcp_client.py +10 -11
  15. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/runner/runner.py +3 -4
  16. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/webui/gradio.py +31 -34
  17. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/webui/webui.py +1 -3
  18. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/gateway/engine/http_tunnel.py +3 -3
  19. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/http_client.py +1 -1
  20. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/renderer.py +3 -1
  21. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/streaming.py +20 -1
  22. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/job/base.py +3 -2
  23. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/job/impl/action.py +5 -5
  24. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/job/job.py +3 -2
  25. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/workflow.py +9 -8
  26. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/common.py +2 -2
  27. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/http_client.py +26 -21
  28. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/http_server.py +2 -2
  29. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/common.py +4 -2
  30. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/http_client.py +2 -2
  31. model_compose-0.2.3/src/mindor/dsl/schema/controller/impl/common.py +13 -0
  32. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/controller/impl/http_server.py +4 -4
  33. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/controller/impl/mcp_server.py +3 -3
  34. model_compose-0.2.3/src/mindor/dsl/schema/controller/impl/webui.py +11 -0
  35. model_compose-0.2.3/src/mindor/dsl/schema/gateway/impl/common.py +9 -0
  36. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/gateway/impl/http_tunnel.py +5 -1
  37. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/impl/common.py +1 -1
  38. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/impl/delay.py +1 -1
  39. model_compose-0.2.3/src/mindor/dsl/schema/listener/impl/common.py +9 -0
  40. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/listener/impl/http_callback.py +8 -8
  41. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/runtime/impl/common.py +1 -1
  42. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/runtime/runtime.py +5 -0
  43. {model_compose-0.2.1 → model_compose-0.2.3}/src/model_compose.egg-info/PKG-INFO +1 -1
  44. model_compose-0.2.1/src/mindor/dsl/schema/controller/impl/common.py +0 -12
  45. model_compose-0.2.1/src/mindor/dsl/schema/controller/impl/webui.py +0 -7
  46. model_compose-0.2.1/src/mindor/dsl/schema/gateway/impl/common.py +0 -8
  47. model_compose-0.2.1/src/mindor/dsl/schema/listener/impl/common.py +0 -8
  48. {model_compose-0.2.1 → model_compose-0.2.3}/LICENSE +0 -0
  49. {model_compose-0.2.1 → model_compose-0.2.3}/README.md +0 -0
  50. {model_compose-0.2.1 → model_compose-0.2.3}/setup.cfg +0 -0
  51. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/__init__.py +0 -0
  52. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/cli/__init__.py +0 -0
  53. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/cli/compose.py +0 -0
  54. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/__init__.py +0 -0
  55. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/__init__.py +0 -0
  56. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/context.py +0 -0
  57. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/component/engine/__init__.py +0 -0
  58. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/compose/__init__.py +0 -0
  59. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/compose/compose.py +0 -0
  60. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/compose/manager.py +0 -0
  61. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/__init__.py +0 -0
  62. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/controller.py +0 -0
  63. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/engine/__init__.py +0 -0
  64. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/runner/__init__.py +0 -0
  65. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/runner/client.py +0 -0
  66. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/runner/http_client.py +0 -0
  67. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/controller/webui/__init__.py +0 -0
  68. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/gateway/__init__.py +0 -0
  69. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/gateway/base.py +0 -0
  70. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/gateway/engine/__init__.py +0 -0
  71. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/gateway/engine/ssh_tunnel.py +0 -0
  72. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/gateway/gateway.py +0 -0
  73. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/listener/__init__.py +0 -0
  74. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/listener/base.py +0 -0
  75. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/listener/engine/__init__.py +0 -0
  76. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/listener/engine/http_callback.py +0 -0
  77. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/listener/listener.py +0 -0
  78. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/runtime/__init__.py +0 -0
  79. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/runtime/env.py +0 -0
  80. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/services/__init__.py +0 -0
  81. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/services/async_service.py +0 -0
  82. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/__init__.py +0 -0
  83. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/expiring.py +0 -0
  84. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/http_request.py +0 -0
  85. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/http_status.py +0 -0
  86. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/image.py +0 -0
  87. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/mcp_client.py +0 -0
  88. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/ssh_client.py +0 -0
  89. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/time.py +0 -0
  90. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/utils/workqueue.py +0 -0
  91. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/__init__.py +0 -0
  92. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/context.py +0 -0
  93. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/job/__init__.py +0 -0
  94. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/job/impl/__init__.py +0 -0
  95. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/job/impl/delay.py +0 -0
  96. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/core/workflow/schema.py +0 -0
  97. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/__init__.py +0 -0
  98. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/loader.py +0 -0
  99. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/__init__.py +0 -0
  100. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/__init__.py +0 -0
  101. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/action.py +0 -0
  102. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/__init__.py +0 -0
  103. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
  104. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
  105. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
  106. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/action/impl/workflow.py +0 -0
  107. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/__init__.py +0 -0
  108. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/component.py +0 -0
  109. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/__init__.py +0 -0
  110. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
  111. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
  112. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
  113. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
  114. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/types.py +0 -0
  115. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/component/impl/workflow.py +0 -0
  116. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/compose.py +0 -0
  117. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/controller/__init__.py +0 -0
  118. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/controller/controller.py +0 -0
  119. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
  120. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
  121. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
  122. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
  123. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
  124. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
  125. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
  126. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/__init__.py +0 -0
  127. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/impl/__init__.py +0 -0
  128. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/impl/action.py +0 -0
  129. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/impl/types.py +0 -0
  130. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/job/job.py +0 -0
  131. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/listener/__init__.py +0 -0
  132. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
  133. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
  134. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/listener/listener.py +0 -0
  135. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
  136. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/runtime/impl/__init__.py +0 -0
  137. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/runtime/impl/docker.py +0 -0
  138. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/runtime/impl/types.py +0 -0
  139. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/utils/__init__.py +0 -0
  140. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/utils/annotation.py +0 -0
  141. {model_compose-0.2.1 → model_compose-0.2.3}/src/mindor/dsl/schema/workflow.py +0 -0
  142. {model_compose-0.2.1 → model_compose-0.2.3}/src/model_compose.egg-info/SOURCES.txt +0 -0
  143. {model_compose-0.2.1 → model_compose-0.2.3}/src/model_compose.egg-info/dependency_links.txt +0 -0
  144. {model_compose-0.2.1 → model_compose-0.2.3}/src/model_compose.egg-info/entry_points.txt +0 -0
  145. {model_compose-0.2.1 → model_compose-0.2.3}/src/model_compose.egg-info/requires.txt +0 -0
  146. {model_compose-0.2.1 → model_compose-0.2.3}/src/model_compose.egg-info/top_level.txt +0 -0
  147. {model_compose-0.2.1 → model_compose-0.2.3}/tests/test_cli.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: model-compose
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: model-compose: Declarative AI Model and Workflow Orchestrator
5
5
  Author-email: Hanyeol Cho <hanyeol.cho@gmail.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "model-compose"
3
- version = "0.2.1"
3
+ version = "0.2.3"
4
4
  description = "model-compose: Declarative AI Model and Workflow Orchestrator"
5
5
  authors = [
6
6
  { name = "Hanyeol Cho", email = "hanyeol.cho@gmail.com" }
@@ -2,6 +2,9 @@ from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annot
2
2
  from abc import ABC, abstractmethod
3
3
  from mindor.dsl.schema.component import ComponentConfig, ComponentType
4
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
5
8
  from mindor.core.services import AsyncService
6
9
  from mindor.core.utils.workqueue import WorkQueue
7
10
  from .context import ComponentActionContext
@@ -29,12 +32,26 @@ class ActionResolver:
29
32
 
30
33
  return default_ids[0] if default_ids else "__default__"
31
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
+
32
48
  class ComponentEngine(AsyncService):
33
- def __init__(self, id: str, config: ComponentConfig, daemon: bool):
49
+ def __init__(self, id: str, config: ComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
34
50
  super().__init__(daemon)
35
51
 
36
52
  self.id: str = id
37
53
  self.config: ComponentConfig = config
54
+ self.global_configs: ComponentGlobalConfigs = global_configs
38
55
  self.queue: Optional[WorkQueue] = None
39
56
 
40
57
  if self.config.max_concurrent_count > 0:
@@ -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 .base import ComponentEngine, ComponentRegistry
3
+ from .base import ComponentEngine, ComponentGlobalConfigs, ComponentRegistry
4
4
 
5
5
  ComponentInstances: Dict[str, ComponentEngine] = {}
6
6
 
@@ -27,14 +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
36
  from . import engine
37
- component = ComponentRegistry[config.type](id, config, daemon)
37
+ component = ComponentRegistry[config.type](id, config, global_configs, daemon)
38
38
  ComponentInstances[id] = component
39
39
 
40
40
  return component
@@ -1,12 +1,12 @@
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 ..base import ComponentEngine, ComponentType, register_component
9
+ from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
10
10
  from ..context import ComponentActionContext
11
11
  from datetime import datetime, timezone
12
12
  import asyncio
@@ -63,7 +63,7 @@ class HttpClientPollingCompletion(HttpClientCompletion):
63
63
  return await context.render_variable(self.config.endpoint)
64
64
 
65
65
  class HttpClientCallbackCompletion(HttpClientCompletion):
66
- async def run(self, context: ComponentActionContext) -> Any:
66
+ async def run(self, context: ComponentActionContext, client: HttpClient) -> Any:
67
67
  callback_id = await context.render_variable(self.config.wait_for)
68
68
  future: asyncio.Future = asyncio.get_event_loop().create_future()
69
69
  HttpCallbackListener.register_pending_future(callback_id, future)
@@ -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 == "polling":
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 == "callback":
86
+ if self.config.completion.type == HttpClientCompletionType.CALLBACK:
87
87
  self.completion = HttpClientCallbackCompletion(self.config.completion)
88
88
  return
89
89
 
@@ -113,8 +113,8 @@ class HttpClientAction:
113
113
 
114
114
  @register_component(ComponentType.HTTP_CLIENT)
115
115
  class HttpClientComponent(ComponentEngine):
116
- def __init__(self, id: str, config: HttpClientComponentConfig, daemon: bool):
117
- 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)
118
118
 
119
119
  self.client: HttpClient = None
120
120
 
@@ -1,12 +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 ..base import ComponentEngine, ComponentType, ActionConfig, register_component
3
+ from mindor.dsl.schema.action import ActionConfig, HttpServerActionConfig
4
+ from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
4
5
  from ..context import ComponentActionContext
5
6
 
6
7
  @register_component(ComponentType.HTTP_SERVER)
7
8
  class HttpServerComponent(ComponentEngine):
8
- def __init__(self, id: str, config: HttpServerComponentConfig, daemon: bool):
9
- 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)
10
11
 
11
12
  async def _serve(self) -> None:
12
13
  pass
@@ -2,7 +2,7 @@ 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 ..base import ComponentEngine, ComponentType, ActionConfig, register_component
5
+ from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
6
6
  from ..context import ComponentActionContext
7
7
 
8
8
  class McpClientAction():
@@ -29,8 +29,8 @@ class McpClientAction():
29
29
 
30
30
  @register_component(ComponentType.MCP_CLIENT)
31
31
  class McpClientComponent(ComponentEngine):
32
- def __init__(self, id: str, config: McpClientComponentConfig, daemon: bool):
33
- 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)
34
34
 
35
35
  async def _serve(self) -> None:
36
36
  self.client = McpClient(self.config.url, self.config.headers)
@@ -1,12 +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 ..base import ComponentEngine, ComponentType, ActionConfig, register_component
3
+ from mindor.dsl.schema.action import ActionConfig, McpServerActionConfig
4
+ from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
4
5
  from ..context import ComponentActionContext
5
6
 
6
7
  @register_component(ComponentType.MCP_SERVER)
7
8
  class McpServerComponent(ComponentEngine):
8
- def __init__(self, id: str, config: McpServerComponentConfig, daemon: bool):
9
- 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)
10
11
 
11
12
  async def _serve(self) -> None:
12
13
  pass
@@ -1,7 +1,7 @@
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 ..base import ComponentEngine, ComponentType, ActionConfig, register_component
4
+ from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
5
5
  from ..context import ComponentActionContext
6
6
  from asyncio.subprocess import Process
7
7
  import asyncio, os
@@ -66,8 +66,8 @@ class ShellAction:
66
66
 
67
67
  @register_component(ComponentType.SHELL)
68
68
  class ShellComponent(ComponentEngine):
69
- def __init__(self, id: str, config: ShellComponentConfig, daemon: bool):
70
- 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)
71
71
 
72
72
  async def _serve(self) -> None:
73
73
  pass
@@ -3,15 +3,14 @@ from mindor.dsl.schema.component import ComponentConfig, WorkflowComponentConfig
3
3
  from mindor.dsl.schema.action import ActionConfig, WorkflowActionConfig
4
4
  from mindor.dsl.schema.workflow import WorkflowConfig
5
5
  from mindor.core.workflow import Workflow, WorkflowResolver, create_workflow
6
- from ..base import ComponentEngine, ComponentType, ActionConfig, register_component
6
+ from ..base import ComponentEngine, ComponentType, ComponentGlobalConfigs, register_component
7
7
  from ..context import ComponentActionContext
8
8
  import asyncio, os
9
9
 
10
10
  class WorkflowAction:
11
- def __init__(self, config: WorkflowActionConfig):
11
+ def __init__(self, config: WorkflowActionConfig, global_configs: ComponentGlobalConfigs):
12
12
  self.config: WorkflowActionConfig = config
13
- self.components: Dict[str, ComponentConfig] = None
14
- self.workflows: Dict[str, WorkflowConfig] = None
13
+ self.global_configs: ComponentGlobalConfigs = global_configs
15
14
 
16
15
  async def run(self, context: ComponentActionContext) -> Any:
17
16
  workflow_id = await context.render_variable(self.config.workflow)
@@ -24,12 +23,12 @@ class WorkflowAction:
24
23
  return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else output
25
24
 
26
25
  def _create_workflow(self, workflow_id: Optional[str]) -> Workflow:
27
- return create_workflow(*WorkflowResolver(self.workflows).resolve(workflow_id), self.components)
26
+ return create_workflow(*WorkflowResolver(self.global_configs.workflows).resolve(workflow_id), self.global_configs)
28
27
 
29
28
  @register_component(ComponentType.WORKFLOW)
30
29
  class WorkflowComponent(ComponentEngine):
31
- def __init__(self, id: str, config: WorkflowComponentConfig, daemon: bool):
32
- super().__init__(id, config, daemon)
30
+ def __init__(self, id: str, config: WorkflowComponentConfig, global_configs: ComponentGlobalConfigs, daemon: bool):
31
+ super().__init__(id, config, global_configs, daemon)
33
32
 
34
33
  async def _serve(self) -> None:
35
34
  pass
@@ -38,4 +37,4 @@ class WorkflowComponent(ComponentEngine):
38
37
  pass
39
38
 
40
39
  async def _run(self, action: ActionConfig, context: ComponentActionContext) -> Any:
41
- return await WorkflowAction(action).run(context)
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: Literal[ "pending", "processing", "completed", "failed" ]
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="pending")
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="processing")
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
135
  workflow = self._create_workflow(workflow_id)
131
136
  output = await workflow.run(task_id, input)
132
- state = TaskState(task_id=task_id, status="completed", output=output)
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="failed", error=str(e))
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
- return [ create_component(component_id, config, self.daemon) for component_id, config in self.components.items() ]
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,7 +157,11 @@ 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
- return create_workflow(*WorkflowResolver(self.workflows).resolve(workflow_id), self.components)
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)
155
165
 
156
166
  def register_controller(type: ControllerType):
157
167
  def decorator(cls: Type[ControllerEngine]) -> Type[ControllerEngine]:
@@ -8,7 +8,7 @@ from mindor.dsl.schema.gateway import GatewayConfig
8
8
  from mindor.dsl.schema.workflow import WorkflowConfig
9
9
  from mindor.core.utils.http_request import parse_request_body, parse_options_header
10
10
  from mindor.core.utils.streaming import StreamResource
11
- from ..base import ControllerEngine, ControllerType, TaskState, register_controller
11
+ from ..base import ControllerEngine, ControllerType, TaskState, TaskStatus, register_controller
12
12
  from fastapi import FastAPI, APIRouter, Request, Body, HTTPException
13
13
  from fastapi.middleware.cors import CORSMiddleware
14
14
  from fastapi.responses import Response, JSONResponse, StreamingResponse
@@ -75,7 +75,7 @@ class HttpServerController(ControllerEngine):
75
75
  state = await self.run_workflow(body.workflow_id, body.input, body.wait_for_completion)
76
76
 
77
77
  if body.output_only and not body.wait_for_completion:
78
- raise HTTPException(status_code=400, detail="output_only requires wait_for_completion=True.")
78
+ raise HTTPException(status_code=400, detail="output_only requires wait_for_completion=true.")
79
79
 
80
80
  if body.output_only:
81
81
  return self._render_task_output(state)
@@ -129,10 +129,10 @@ class HttpServerController(ControllerEngine):
129
129
  return JSONResponse(content=TaskResult.from_instance(state).model_dump(exclude_none=True))
130
130
 
131
131
  def _render_task_output(self, state: TaskState) -> Response:
132
- if state.status in [ "pending", "processing" ]:
132
+ if state.status in [ TaskStatus.PENDING, TaskStatus.PROCESSING ]:
133
133
  raise HTTPException(status_code=202, detail="Task is still in progress.")
134
134
 
135
- if state.status == "failed":
135
+ if state.status == TaskStatus.FAILED:
136
136
  raise HTTPException(status_code=500, detail=str(state.error))
137
137
 
138
138
  if isinstance(state.output, StreamResource):
@@ -3,7 +3,7 @@ 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
@@ -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
- type, subtype, format = variable.type.value, variable.subtype, variable.format.value if variable.format else None
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: str, subtype: Optional[str], format: Optional[str], default: Optional[Any]) -> Any:
44
- if type in [ "image", "audio", "video", "file" ]:
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
- type, subtype, format = variable.type.value, variable.subtype, variable.format.value if variable.format else None
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
- type, subtype, format = variable.type.value, variable.subtype, variable.format.value if variable.format else None
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: str, subtype: Optional[str], format: Optional[str]) -> Union[TextContent, ImageContent, AudioContent]:
66
- if type in [ "image", "audio", "video", "file" ]:
67
- if format == "base64" and len(value) < 1024 * 1024: # at most 1MB
68
- if type == "image":
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 == "audio":
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 [ "path", "url" ]:
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[str]) -> Optional[str]:
82
- if format == "base64" and isinstance(value, str):
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 == "url" and isinstance(value, str):
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,15 +116,13 @@ class WorkflowToolGenerator():
119
116
  return "\n".join(lines)
120
117
 
121
118
  def _get_docstring_type(self, variable: WorkflowVariableConfig) -> str:
122
- type, subtype, format = variable.type.value, variable.subtype, variable.format.value if variable.format else None
123
-
124
- if type == "object[]":
119
+ if variable.type == WorkflowVariableType.OBJECTS:
125
120
  return "list[dict]"
126
121
 
127
- if type == "number":
122
+ if variable.type == WorkflowVariableType.NUMBER:
128
123
  return "float"
129
124
 
130
- if type == "integer":
125
+ if variable.type == WorkflowVariableType.INTEGER:
131
126
  return "int"
132
127
 
133
128
  return "str"
@@ -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
- type, subtype, format = variable.type.value, variable.subtype, variable.format.value if variable.format else None
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
- type, subtype, format = variable.type.value, variable.subtype, variable.format.value if variable.format else None
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: str, subtype: Optional[str], format: Optional[str]) -> Any:
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 [ "json", "object[]" ]:
42
+ if type in [ WorkflowVariableType.JSON, WorkflowVariableType.OBJECTS ]:
44
43
  return json.loads(content.text)
45
- if type in [ "image", "audio", "video", "file" ]:
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 == "base64": # content.text is path
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[str]) -> Optional[str]:
58
- if format == "base64" and isinstance(value, str):
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 == "url" and isinstance(value, str):
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):
@@ -1,7 +1,6 @@
1
1
  from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
2
2
  from abc import ABC, abstractmethod
3
- from mindor.dsl.schema.controller import ControllerConfig
4
- from mindor.dsl.schema.workflow import WorkflowVariableConfig, WorkflowVariableGroupConfig
3
+ from mindor.dsl.schema.controller import ControllerConfig, ControllerType
5
4
  from mindor.core.workflow.schema import WorkflowSchema
6
5
  from .client import ControllerClient
7
6
  from .http_client import HttpControllerClient
@@ -27,11 +26,11 @@ class ControllerRunner:
27
26
  self._configure_client()
28
27
 
29
28
  def _configure_client(self) -> None:
30
- if self.config.type == "http-server":
29
+ if self.config.type == ControllerType.HTTP_SERVER:
31
30
  self.client = HttpControllerClient(self.config)
32
31
  return
33
32
 
34
- if self.config.type == "mcp-server":
33
+ if self.config.type == ControllerType.MCP_SERVER:
35
34
  self.client = McpControllerClient(self.config)
36
35
  return
37
36