model-compose 0.2.12__tar.gz → 0.3.1__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.12/src/model_compose.egg-info → model_compose-0.3.1}/PKG-INFO +159 -23
- {model_compose-0.2.12 → model_compose-0.3.1}/README.md +157 -22
- {model_compose-0.2.12 → model_compose-0.3.1}/pyproject.toml +7 -2
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/cli/compose.py +9 -2
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/compose/compose.py +4 -4
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/compose/manager.py +4 -6
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/base.py +48 -18
- model_compose-0.3.1/src/mindor/core/controller/runtime/docker/__init__.py +1 -0
- model_compose-0.3.1/src/mindor/core/controller/runtime/docker/context/Dockerfile +42 -0
- model_compose-0.3.1/src/mindor/core/controller/runtime/docker/docker.py +102 -0
- model_compose-0.3.1/src/mindor/core/controller/runtime/specs.py +40 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/webui/gradio.py +5 -5
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/services/console.py +1 -1
- model_compose-0.3.1/src/mindor/core/runtime/docker/__init__.py +1 -0
- model_compose-0.3.1/src/mindor/core/runtime/docker/docker.py +259 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/runtime/env.py +0 -2
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/job/base.py +5 -1
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/job/impl/__init__.py +2 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/job/impl/action.py +2 -2
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/job/impl/delay.py +13 -5
- model_compose-0.3.1/src/mindor/core/workflow/job/impl/if_.py +57 -0
- model_compose-0.3.1/src/mindor/core/workflow/job/impl/switch.py +21 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/job/job.py +1 -1
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/schema.py +9 -7
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/workflow.py +39 -12
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/compose.py +5 -5
- model_compose-0.3.1/src/mindor/dsl/schema/controller/impl/common.py +21 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/impl/http_server.py +4 -4
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/impl/mcp_server.py +3 -3
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/impl/webui.py +2 -2
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/impl/__init__.py +2 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/impl/action.py +2 -2
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/impl/common.py +6 -1
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/impl/delay.py +3 -3
- model_compose-0.3.1/src/mindor/dsl/schema/job/impl/if_.py +46 -0
- model_compose-0.3.1/src/mindor/dsl/schema/job/impl/switch.py +29 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/impl/types.py +2 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/job.py +3 -1
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/runtime/impl/__init__.py +1 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/runtime/impl/common.py +1 -1
- model_compose-0.3.1/src/mindor/dsl/schema/runtime/impl/docker.py +72 -0
- model_compose-0.2.12/src/mindor/dsl/schema/runtime/impl/docker.py → model_compose-0.3.1/src/mindor/dsl/schema/runtime/impl/native.py +3 -3
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/runtime/impl/types.py +1 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/runtime/runtime.py +2 -5
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/workflow.py +2 -2
- model_compose-0.3.1/src/mindor/dsl/utils/__init__.py +0 -0
- model_compose-0.3.1/src/mindor/dsl/utils/enum.py +27 -0
- {model_compose-0.2.12 → model_compose-0.3.1/src/model_compose.egg-info}/PKG-INFO +159 -23
- {model_compose-0.2.12 → model_compose-0.3.1}/src/model_compose.egg-info/SOURCES.txt +13 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/model_compose.egg-info/requires.txt +1 -0
- model_compose-0.2.12/src/mindor/dsl/schema/controller/impl/common.py +0 -13
- {model_compose-0.2.12 → model_compose-0.3.1}/LICENSE +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/setup.cfg +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/cli/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/base.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/component.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/context.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/http_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/http_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/mcp_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/mcp_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/base.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/model.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/tasks/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/tasks/summarization.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/tasks/text_classification.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/tasks/text_embedding.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/tasks/text_generation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/model/tasks/translation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/shell.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/component/services/workflow.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/compose/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/controller.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/runner/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/runner/client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/runner/http_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/runner/mcp_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/runner/runner.py +0 -0
- {model_compose-0.2.12/src/mindor/core → model_compose-0.3.1/src/mindor/core/controller}/runtime/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/services/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/services/http_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/services/mcp_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/webui/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/controller/webui/webui.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/gateway/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/gateway/base.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/gateway/gateway.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/gateway/services/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/gateway/services/http_tunnel.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/gateway/services/ssh_tunnel.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/listener/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/listener/base.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/listener/listener.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/listener/services/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/listener/services/http_callback.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/base.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/logger.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/logging.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/services/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/logger/services/file.py +0 -0
- {model_compose-0.2.12/src/mindor/core/utils → model_compose-0.3.1/src/mindor/core/runtime}/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/services/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/services/async_service.py +0 -0
- {model_compose-0.2.12/src/mindor/dsl → model_compose-0.3.1/src/mindor/core/utils}/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/expiring.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/http_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/http_request.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/http_status.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/image.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/mcp_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/renderer.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/ssh_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/streaming.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/time.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/utils/workqueue.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/context.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/core/workflow/job/__init__.py +0 -0
- {model_compose-0.2.12/src/mindor/dsl/schema → model_compose-0.3.1/src/mindor/dsl}/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/loader.py +0 -0
- {model_compose-0.2.12/src/mindor/dsl/utils → model_compose-0.3.1/src/mindor/dsl/schema}/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/action.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/http_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/http_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/summarization.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/text_classification.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/text_embedding.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/text_generation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/impl/translation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/model/model.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/action/impl/workflow.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/component.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/http_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/summarization.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/text_classification.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/text_embedding.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/text_generation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/translation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/impl/types.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/model/model.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/types.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/component/impl/workflow.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/controller.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/impl/http_tunnel.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/job/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/listener/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/listener/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/listener/impl/http_callback.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/listener/listener.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/impl/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/impl/common.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/impl/console.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/impl/file.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/impl/types.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/logger/logger.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/mindor/dsl/utils/annotation.py +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/model_compose.egg-info/dependency_links.txt +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/model_compose.egg-info/entry_points.txt +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/src/model_compose.egg-info/top_level.txt +0 -0
- {model_compose-0.2.12 → model_compose-0.3.1}/tests/test_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: model-compose
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
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
|
|
@@ -24,6 +24,7 @@ Requires-Dist: transformers>=4.21.0
|
|
|
24
24
|
Requires-Dist: torch
|
|
25
25
|
Requires-Dist: sentencepiece
|
|
26
26
|
Requires-Dist: accelerate
|
|
27
|
+
Requires-Dist: docker
|
|
27
28
|
Dynamic: license-file
|
|
28
29
|
|
|
29
30
|
# model-compose: Declarative AI Model and Workflow Orchestrator
|
|
@@ -32,22 +33,21 @@ Dynamic: license-file
|
|
|
32
33
|
[](https://opensource.org/licenses/MIT)
|
|
33
34
|
[](http://makeapullrequest.com)
|
|
34
35
|
|
|
35
|
-

|
|
36
|
-
|
|
37
36
|
**model-compose** is an open-source, declarative workflow orchestrator inspired by `docker-compose`. It lets you define and run AI model pipelines using simple YAML files — no custom code required. Effortlessly connect external AI services or run local AI models, all within powerful, composable workflows.
|
|
38
37
|
|
|
39
38
|
---
|
|
40
39
|
|
|
41
40
|
## ✨ Features
|
|
42
41
|
|
|
43
|
-
- **Declarative by Design
|
|
44
|
-
- **Compose Anything
|
|
45
|
-
- **Built for Orchestration
|
|
46
|
-
- **Multi-Workflow Support
|
|
47
|
-
- **Modular Components
|
|
48
|
-
- **Flexible I/O Routing
|
|
49
|
-
- **Run Locally, Serve Remotely
|
|
50
|
-
- **
|
|
42
|
+
- **Declarative by Design**: Define complete AI workflows using simple YAML files—no complex scripting required.
|
|
43
|
+
- **Compose Anything**: Combine multiple AI models, APIs, and tools into a single, unified pipeline.
|
|
44
|
+
- **Built for Orchestration**: Orchestrate multi-step model interactions with ease. Transform individual API calls into maintainable, end-to-end systems.
|
|
45
|
+
- **Multi-Workflow Support**: Define multiple named workflows in one project. Run them by name or set a default for quick execution.
|
|
46
|
+
- **Modular Components**: Break down logic into reusable components and jobs. Easily plug, swap, and extend them across workflows.
|
|
47
|
+
- **Flexible I/O Routing**: Connect inputs and outputs between jobs using clean, scoped variables—no glue code needed.
|
|
48
|
+
- **Run Locally, Serve Remotely**: Execute workflows from the CLI or expose them as HTTP or MCP endpoints with an optional Web UI.
|
|
49
|
+
- **Docker Deployment**: Build and deploy your workflow controller as a Docker container for consistent and portable execution environments.
|
|
50
|
+
- **Environment Variable Support**: Easily inject secrets and configuration via `.env` files or environment variables to keep your YAML clean and secure.
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
@@ -84,8 +84,8 @@ By default, this command will:
|
|
|
84
84
|
|
|
85
85
|
- Look for a file named `model-compose.yml` in the **current working directory**
|
|
86
86
|
- Automatically load environment variables from a `.env` file in the **same directory**, if it exists
|
|
87
|
-
- Start the workflow controller (default: http://localhost:8080)
|
|
88
|
-
- Optionally launch the Web UI (default: http://localhost:8081
|
|
87
|
+
- Start the workflow controller (default: `http://localhost:8080`)
|
|
88
|
+
- Optionally launch the Web UI (default: `http://localhost:8081`, if configured)
|
|
89
89
|
|
|
90
90
|
To run in the background (detached mode):
|
|
91
91
|
|
|
@@ -113,7 +113,7 @@ model-compose up --env OPENAI_API_KEY=... --env ELEVENLABS_API_KEY=...
|
|
|
113
113
|
|
|
114
114
|
> 💡 Once the controller is running, you can trigger workflows via the REST API or, if using MCP, via JSON-RPC. You can also access them through the Web UI.
|
|
115
115
|
|
|
116
|
-
####
|
|
116
|
+
#### 🔽 Shutting Down the Server (`down`)
|
|
117
117
|
To gracefully stop and remove the workflow controller and all associated services:
|
|
118
118
|
|
|
119
119
|
```
|
|
@@ -139,19 +139,18 @@ This is useful for testing, automation, or scripting.
|
|
|
139
139
|
| `model-compose stop` | Temporarily pause the currently running controller |
|
|
140
140
|
|
|
141
141
|
---
|
|
142
|
-
|
|
143
142
|
## 🧾 `model-compose.yml`
|
|
144
143
|
|
|
145
144
|
The `model-compose.yml` file is the central configuration file that defines how your workflows are composed and executed.
|
|
146
145
|
|
|
147
146
|
It includes:
|
|
148
147
|
|
|
149
|
-
- **Controller
|
|
150
|
-
- **Components
|
|
151
|
-
- **Workflows
|
|
152
|
-
- **Jobs
|
|
153
|
-
- **Listeners
|
|
154
|
-
- **Gateways
|
|
148
|
+
- **Controller**: configures the HTTP/MCP server, API endpoints, and optional Web UI
|
|
149
|
+
- **Components**: reusable definitions for calling APIs, running local AI models, or executing commands
|
|
150
|
+
- **Workflows**: named sets of jobs that define the flow of data
|
|
151
|
+
- **Jobs**: steps that execute specific components, with support for inputs, outputs, and dependencies
|
|
152
|
+
- **Listeners**: optional callback listeners that handle asynchronous responses from external services
|
|
153
|
+
- **Gateways**: optional tunneling services that expose your local controller to the public internet
|
|
155
154
|
|
|
156
155
|
By default, `model-compose` automatically looks for a file named `model-compose.yml` in the current working directory when running commands like `up` or `run`.
|
|
157
156
|
|
|
@@ -161,6 +160,7 @@ By default, `model-compose` automatically looks for a file named `model-compose.
|
|
|
161
160
|
controller:
|
|
162
161
|
type: http-server
|
|
163
162
|
port: 8080
|
|
163
|
+
base_path: /api
|
|
164
164
|
webui:
|
|
165
165
|
port: 8081
|
|
166
166
|
|
|
@@ -213,7 +213,7 @@ listener:
|
|
|
213
213
|
result: ${item.choices[0].message.content}
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
This listener sets up an HTTP callback endpoint at http://localhost:8090/callbacks/chat-ai to handle asynchronous responses from an external service that behaves like ChatGPT but supports delayed or push-based results. This is useful when integrating with services that notify results via webhook-style callbacks.
|
|
216
|
+
This listener sets up an HTTP callback endpoint at `http://localhost:8090/callbacks/chat-ai` to handle asynchronous responses from an external service that behaves like ChatGPT but supports delayed or push-based results. This is useful when integrating with services that notify results via webhook-style callbacks.
|
|
217
217
|
|
|
218
218
|
#### 🌐 Gateway Example
|
|
219
219
|
|
|
@@ -224,10 +224,146 @@ gateway:
|
|
|
224
224
|
port: 8090
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
-
This gateway configuration exposes the local listener defined above to the public internet using an HTTP tunnel powered by ngrok. It forwards incoming traffic from a secure, public URL (e.g., https://abc123.ngrok.io) directly to your local callback endpoint at http://localhost:8090
|
|
227
|
+
This gateway configuration exposes the local listener defined above to the public internet using an HTTP tunnel powered by ngrok. It forwards incoming traffic from a secure, public URL (e.g., `https://abc123.ngrok.io`) directly to your local callback endpoint at `http://localhost:8090`. This is essential when integrating with third-party services that need to push data back to your workflow via webhooks or asynchronous callbacks.
|
|
228
228
|
|
|
229
229
|
> 📁 For more example model-compose.yml configurations, check the [examples directory](examples) in the source code.
|
|
230
230
|
|
|
231
|
+
---
|
|
232
|
+
## 🖥 Web UI
|
|
233
|
+
**model-compose** optionally provides a lightweight **Web UI** to help you visually trigger workflows, inspect inputs and outputs, and monitor execution logs.
|
|
234
|
+
|
|
235
|
+

|
|
236
|
+
|
|
237
|
+
#### ✅ Enabling the Web UI
|
|
238
|
+
To enable the Web UI, simply add the `webui` section under your `controller` in the `model-compose.yml` file:
|
|
239
|
+
```
|
|
240
|
+
controller:
|
|
241
|
+
type: http-server
|
|
242
|
+
port: 8080
|
|
243
|
+
webui:
|
|
244
|
+
port: 8081
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Once enabled, the Web UI will be available at:
|
|
248
|
+
```
|
|
249
|
+
http://localhost:8081
|
|
250
|
+
```
|
|
251
|
+
> By default, the Web UI is powered by [Gradio](https://www.gradio.app), but support for other drivers may be added in the future.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
## 🛰 MCP Server Support
|
|
255
|
+
You can also expose your workflows via the **Model Context Protocol (MCP)** server to enable remote execution, automation, or system integration using a lightweight JSON-RPC interface.
|
|
256
|
+
|
|
257
|
+
#### ✅ Minimal MCP Server Example
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
controller:
|
|
261
|
+
type: mcp-server
|
|
262
|
+
port: 8080
|
|
263
|
+
base_path: /mcp
|
|
264
|
+
|
|
265
|
+
components:
|
|
266
|
+
chatgpt:
|
|
267
|
+
type: http-client
|
|
268
|
+
base_url: https://api.openai.com/v1
|
|
269
|
+
path: /chat/completions
|
|
270
|
+
method: POST
|
|
271
|
+
headers:
|
|
272
|
+
Authorization: Bearer ${env.OPENAI_API_KEY}
|
|
273
|
+
Content-Type: application/json
|
|
274
|
+
body:
|
|
275
|
+
model: gpt-4o
|
|
276
|
+
messages:
|
|
277
|
+
- role: user
|
|
278
|
+
content: "Write an inspiring quote."
|
|
279
|
+
output:
|
|
280
|
+
quote: ${response.choices[0].message.content}
|
|
281
|
+
|
|
282
|
+
workflows:
|
|
283
|
+
generate-quote:
|
|
284
|
+
default: true
|
|
285
|
+
jobs:
|
|
286
|
+
get-quote:
|
|
287
|
+
component: chatgpt
|
|
288
|
+
```
|
|
289
|
+
This configuration launches the controller as an **MCP server**, which listens on port 8080 and exposes your workflows over a **JSON-RPC API**.
|
|
290
|
+
|
|
291
|
+
Once running, you can invoke workflows remotely using a standard MCP request:
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
{
|
|
295
|
+
"jsonrpc": "2.0",
|
|
296
|
+
"id": 1,
|
|
297
|
+
"method": "callTool",
|
|
298
|
+
"params": {
|
|
299
|
+
"name": "generate-quote",
|
|
300
|
+
"arguments": {}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
You can send this request via any HTTP client to:
|
|
306
|
+
```
|
|
307
|
+
POST http://localhost:8080/mcp
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
## 🐳 Docker Runtime Support
|
|
312
|
+
You can run the workflow controller inside a Docker container by specifying the runtime option in your `model-compose.yml` file.
|
|
313
|
+
|
|
314
|
+
#### ✅ Minimal Docker Runtime Example
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
controller:
|
|
318
|
+
type: http-server
|
|
319
|
+
port: 8080
|
|
320
|
+
runtime: docker
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
This configuration will launch the controller inside a lightweight Docker container automatically managed by **model-compose**. It uses default settings such as container name, image, and volume mappings.
|
|
324
|
+
|
|
325
|
+
#### ⚙️ Advanced Docker Runtime Options
|
|
326
|
+
You can fully configure the Docker runtime by using an object under the `runtime` key:
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
controller:
|
|
330
|
+
type: http-server
|
|
331
|
+
port: 8080
|
|
332
|
+
runtime:
|
|
333
|
+
type: docker
|
|
334
|
+
image: 192.168.0.23/custom-image:latest
|
|
335
|
+
container_name: my-controller
|
|
336
|
+
volumes:
|
|
337
|
+
- ./models:/models
|
|
338
|
+
- ./cache:/cache
|
|
339
|
+
ports:
|
|
340
|
+
- "5000:8080"
|
|
341
|
+
- "5001:8081"
|
|
342
|
+
env:
|
|
343
|
+
MODEL_STORAGE_PATH: /models
|
|
344
|
+
command: [ "python", "-m", "mindor.cli.compose", "up" ]
|
|
345
|
+
...
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
This gives you full control over:
|
|
349
|
+
|
|
350
|
+
- **container_name**: Custom name for the container
|
|
351
|
+
- **image**: Docker image to use
|
|
352
|
+
- **volumes**: Bind mounts for sharing files between host and container
|
|
353
|
+
- **ports**: Port mappings for host ↔ container communication
|
|
354
|
+
- **env**: Environment variables to inject
|
|
355
|
+
- **command**: Override the default entrypoint
|
|
356
|
+
- *and many more*
|
|
357
|
+
|
|
358
|
+
All of these are optional, allowing you to start simple and customize only what you need.
|
|
359
|
+
|
|
360
|
+
#### 🐳 Benefits of Docker Runtime
|
|
361
|
+
|
|
362
|
+
- Run your controller in a clean, isolated environment
|
|
363
|
+
- Avoid dependency conflicts with your host Python setup
|
|
364
|
+
- Easily deploy your project to remote servers or CI pipelines
|
|
365
|
+
- Share reproducible workflows with others
|
|
366
|
+
|
|
231
367
|
---
|
|
232
368
|
## 🏗 Architecture
|
|
233
369
|
|
|
@@ -4,22 +4,21 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](http://makeapullrequest.com)
|
|
6
6
|
|
|
7
|
-

|
|
8
|
-
|
|
9
7
|
**model-compose** is an open-source, declarative workflow orchestrator inspired by `docker-compose`. It lets you define and run AI model pipelines using simple YAML files — no custom code required. Effortlessly connect external AI services or run local AI models, all within powerful, composable workflows.
|
|
10
8
|
|
|
11
9
|
---
|
|
12
10
|
|
|
13
11
|
## ✨ Features
|
|
14
12
|
|
|
15
|
-
- **Declarative by Design
|
|
16
|
-
- **Compose Anything
|
|
17
|
-
- **Built for Orchestration
|
|
18
|
-
- **Multi-Workflow Support
|
|
19
|
-
- **Modular Components
|
|
20
|
-
- **Flexible I/O Routing
|
|
21
|
-
- **Run Locally, Serve Remotely
|
|
22
|
-
- **
|
|
13
|
+
- **Declarative by Design**: Define complete AI workflows using simple YAML files—no complex scripting required.
|
|
14
|
+
- **Compose Anything**: Combine multiple AI models, APIs, and tools into a single, unified pipeline.
|
|
15
|
+
- **Built for Orchestration**: Orchestrate multi-step model interactions with ease. Transform individual API calls into maintainable, end-to-end systems.
|
|
16
|
+
- **Multi-Workflow Support**: Define multiple named workflows in one project. Run them by name or set a default for quick execution.
|
|
17
|
+
- **Modular Components**: Break down logic into reusable components and jobs. Easily plug, swap, and extend them across workflows.
|
|
18
|
+
- **Flexible I/O Routing**: Connect inputs and outputs between jobs using clean, scoped variables—no glue code needed.
|
|
19
|
+
- **Run Locally, Serve Remotely**: Execute workflows from the CLI or expose them as HTTP or MCP endpoints with an optional Web UI.
|
|
20
|
+
- **Docker Deployment**: Build and deploy your workflow controller as a Docker container for consistent and portable execution environments.
|
|
21
|
+
- **Environment Variable Support**: Easily inject secrets and configuration via `.env` files or environment variables to keep your YAML clean and secure.
|
|
23
22
|
|
|
24
23
|
---
|
|
25
24
|
|
|
@@ -56,8 +55,8 @@ By default, this command will:
|
|
|
56
55
|
|
|
57
56
|
- Look for a file named `model-compose.yml` in the **current working directory**
|
|
58
57
|
- Automatically load environment variables from a `.env` file in the **same directory**, if it exists
|
|
59
|
-
- Start the workflow controller (default: http://localhost:8080)
|
|
60
|
-
- Optionally launch the Web UI (default: http://localhost:8081
|
|
58
|
+
- Start the workflow controller (default: `http://localhost:8080`)
|
|
59
|
+
- Optionally launch the Web UI (default: `http://localhost:8081`, if configured)
|
|
61
60
|
|
|
62
61
|
To run in the background (detached mode):
|
|
63
62
|
|
|
@@ -85,7 +84,7 @@ model-compose up --env OPENAI_API_KEY=... --env ELEVENLABS_API_KEY=...
|
|
|
85
84
|
|
|
86
85
|
> 💡 Once the controller is running, you can trigger workflows via the REST API or, if using MCP, via JSON-RPC. You can also access them through the Web UI.
|
|
87
86
|
|
|
88
|
-
####
|
|
87
|
+
#### 🔽 Shutting Down the Server (`down`)
|
|
89
88
|
To gracefully stop and remove the workflow controller and all associated services:
|
|
90
89
|
|
|
91
90
|
```
|
|
@@ -111,19 +110,18 @@ This is useful for testing, automation, or scripting.
|
|
|
111
110
|
| `model-compose stop` | Temporarily pause the currently running controller |
|
|
112
111
|
|
|
113
112
|
---
|
|
114
|
-
|
|
115
113
|
## 🧾 `model-compose.yml`
|
|
116
114
|
|
|
117
115
|
The `model-compose.yml` file is the central configuration file that defines how your workflows are composed and executed.
|
|
118
116
|
|
|
119
117
|
It includes:
|
|
120
118
|
|
|
121
|
-
- **Controller
|
|
122
|
-
- **Components
|
|
123
|
-
- **Workflows
|
|
124
|
-
- **Jobs
|
|
125
|
-
- **Listeners
|
|
126
|
-
- **Gateways
|
|
119
|
+
- **Controller**: configures the HTTP/MCP server, API endpoints, and optional Web UI
|
|
120
|
+
- **Components**: reusable definitions for calling APIs, running local AI models, or executing commands
|
|
121
|
+
- **Workflows**: named sets of jobs that define the flow of data
|
|
122
|
+
- **Jobs**: steps that execute specific components, with support for inputs, outputs, and dependencies
|
|
123
|
+
- **Listeners**: optional callback listeners that handle asynchronous responses from external services
|
|
124
|
+
- **Gateways**: optional tunneling services that expose your local controller to the public internet
|
|
127
125
|
|
|
128
126
|
By default, `model-compose` automatically looks for a file named `model-compose.yml` in the current working directory when running commands like `up` or `run`.
|
|
129
127
|
|
|
@@ -133,6 +131,7 @@ By default, `model-compose` automatically looks for a file named `model-compose.
|
|
|
133
131
|
controller:
|
|
134
132
|
type: http-server
|
|
135
133
|
port: 8080
|
|
134
|
+
base_path: /api
|
|
136
135
|
webui:
|
|
137
136
|
port: 8081
|
|
138
137
|
|
|
@@ -185,7 +184,7 @@ listener:
|
|
|
185
184
|
result: ${item.choices[0].message.content}
|
|
186
185
|
```
|
|
187
186
|
|
|
188
|
-
This listener sets up an HTTP callback endpoint at http://localhost:8090/callbacks/chat-ai to handle asynchronous responses from an external service that behaves like ChatGPT but supports delayed or push-based results. This is useful when integrating with services that notify results via webhook-style callbacks.
|
|
187
|
+
This listener sets up an HTTP callback endpoint at `http://localhost:8090/callbacks/chat-ai` to handle asynchronous responses from an external service that behaves like ChatGPT but supports delayed or push-based results. This is useful when integrating with services that notify results via webhook-style callbacks.
|
|
189
188
|
|
|
190
189
|
#### 🌐 Gateway Example
|
|
191
190
|
|
|
@@ -196,10 +195,146 @@ gateway:
|
|
|
196
195
|
port: 8090
|
|
197
196
|
```
|
|
198
197
|
|
|
199
|
-
This gateway configuration exposes the local listener defined above to the public internet using an HTTP tunnel powered by ngrok. It forwards incoming traffic from a secure, public URL (e.g., https://abc123.ngrok.io) directly to your local callback endpoint at http://localhost:8090
|
|
198
|
+
This gateway configuration exposes the local listener defined above to the public internet using an HTTP tunnel powered by ngrok. It forwards incoming traffic from a secure, public URL (e.g., `https://abc123.ngrok.io`) directly to your local callback endpoint at `http://localhost:8090`. This is essential when integrating with third-party services that need to push data back to your workflow via webhooks or asynchronous callbacks.
|
|
200
199
|
|
|
201
200
|
> 📁 For more example model-compose.yml configurations, check the [examples directory](examples) in the source code.
|
|
202
201
|
|
|
202
|
+
---
|
|
203
|
+
## 🖥 Web UI
|
|
204
|
+
**model-compose** optionally provides a lightweight **Web UI** to help you visually trigger workflows, inspect inputs and outputs, and monitor execution logs.
|
|
205
|
+
|
|
206
|
+

|
|
207
|
+
|
|
208
|
+
#### ✅ Enabling the Web UI
|
|
209
|
+
To enable the Web UI, simply add the `webui` section under your `controller` in the `model-compose.yml` file:
|
|
210
|
+
```
|
|
211
|
+
controller:
|
|
212
|
+
type: http-server
|
|
213
|
+
port: 8080
|
|
214
|
+
webui:
|
|
215
|
+
port: 8081
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Once enabled, the Web UI will be available at:
|
|
219
|
+
```
|
|
220
|
+
http://localhost:8081
|
|
221
|
+
```
|
|
222
|
+
> By default, the Web UI is powered by [Gradio](https://www.gradio.app), but support for other drivers may be added in the future.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
## 🛰 MCP Server Support
|
|
226
|
+
You can also expose your workflows via the **Model Context Protocol (MCP)** server to enable remote execution, automation, or system integration using a lightweight JSON-RPC interface.
|
|
227
|
+
|
|
228
|
+
#### ✅ Minimal MCP Server Example
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
controller:
|
|
232
|
+
type: mcp-server
|
|
233
|
+
port: 8080
|
|
234
|
+
base_path: /mcp
|
|
235
|
+
|
|
236
|
+
components:
|
|
237
|
+
chatgpt:
|
|
238
|
+
type: http-client
|
|
239
|
+
base_url: https://api.openai.com/v1
|
|
240
|
+
path: /chat/completions
|
|
241
|
+
method: POST
|
|
242
|
+
headers:
|
|
243
|
+
Authorization: Bearer ${env.OPENAI_API_KEY}
|
|
244
|
+
Content-Type: application/json
|
|
245
|
+
body:
|
|
246
|
+
model: gpt-4o
|
|
247
|
+
messages:
|
|
248
|
+
- role: user
|
|
249
|
+
content: "Write an inspiring quote."
|
|
250
|
+
output:
|
|
251
|
+
quote: ${response.choices[0].message.content}
|
|
252
|
+
|
|
253
|
+
workflows:
|
|
254
|
+
generate-quote:
|
|
255
|
+
default: true
|
|
256
|
+
jobs:
|
|
257
|
+
get-quote:
|
|
258
|
+
component: chatgpt
|
|
259
|
+
```
|
|
260
|
+
This configuration launches the controller as an **MCP server**, which listens on port 8080 and exposes your workflows over a **JSON-RPC API**.
|
|
261
|
+
|
|
262
|
+
Once running, you can invoke workflows remotely using a standard MCP request:
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
{
|
|
266
|
+
"jsonrpc": "2.0",
|
|
267
|
+
"id": 1,
|
|
268
|
+
"method": "callTool",
|
|
269
|
+
"params": {
|
|
270
|
+
"name": "generate-quote",
|
|
271
|
+
"arguments": {}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
You can send this request via any HTTP client to:
|
|
277
|
+
```
|
|
278
|
+
POST http://localhost:8080/mcp
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
## 🐳 Docker Runtime Support
|
|
283
|
+
You can run the workflow controller inside a Docker container by specifying the runtime option in your `model-compose.yml` file.
|
|
284
|
+
|
|
285
|
+
#### ✅ Minimal Docker Runtime Example
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
controller:
|
|
289
|
+
type: http-server
|
|
290
|
+
port: 8080
|
|
291
|
+
runtime: docker
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
This configuration will launch the controller inside a lightweight Docker container automatically managed by **model-compose**. It uses default settings such as container name, image, and volume mappings.
|
|
295
|
+
|
|
296
|
+
#### ⚙️ Advanced Docker Runtime Options
|
|
297
|
+
You can fully configure the Docker runtime by using an object under the `runtime` key:
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
controller:
|
|
301
|
+
type: http-server
|
|
302
|
+
port: 8080
|
|
303
|
+
runtime:
|
|
304
|
+
type: docker
|
|
305
|
+
image: 192.168.0.23/custom-image:latest
|
|
306
|
+
container_name: my-controller
|
|
307
|
+
volumes:
|
|
308
|
+
- ./models:/models
|
|
309
|
+
- ./cache:/cache
|
|
310
|
+
ports:
|
|
311
|
+
- "5000:8080"
|
|
312
|
+
- "5001:8081"
|
|
313
|
+
env:
|
|
314
|
+
MODEL_STORAGE_PATH: /models
|
|
315
|
+
command: [ "python", "-m", "mindor.cli.compose", "up" ]
|
|
316
|
+
...
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
This gives you full control over:
|
|
320
|
+
|
|
321
|
+
- **container_name**: Custom name for the container
|
|
322
|
+
- **image**: Docker image to use
|
|
323
|
+
- **volumes**: Bind mounts for sharing files between host and container
|
|
324
|
+
- **ports**: Port mappings for host ↔ container communication
|
|
325
|
+
- **env**: Environment variables to inject
|
|
326
|
+
- **command**: Override the default entrypoint
|
|
327
|
+
- *and many more*
|
|
328
|
+
|
|
329
|
+
All of these are optional, allowing you to start simple and customize only what you need.
|
|
330
|
+
|
|
331
|
+
#### 🐳 Benefits of Docker Runtime
|
|
332
|
+
|
|
333
|
+
- Run your controller in a clean, isolated environment
|
|
334
|
+
- Avoid dependency conflicts with your host Python setup
|
|
335
|
+
- Easily deploy your project to remote servers or CI pipelines
|
|
336
|
+
- Share reproducible workflows with others
|
|
337
|
+
|
|
203
338
|
---
|
|
204
339
|
## 🏗 Architecture
|
|
205
340
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "model-compose"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.1"
|
|
4
4
|
description = "model-compose: Declarative AI Model and Workflow Orchestrator"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Hanyeol Cho", email = "hanyeol.cho@gmail.com" }
|
|
@@ -24,7 +24,8 @@ dependencies = [
|
|
|
24
24
|
"transformers>=4.21.0",
|
|
25
25
|
"torch",
|
|
26
26
|
"sentencepiece",
|
|
27
|
-
"accelerate"
|
|
27
|
+
"accelerate",
|
|
28
|
+
"docker"
|
|
28
29
|
]
|
|
29
30
|
|
|
30
31
|
[project.scripts]
|
|
@@ -39,6 +40,10 @@ build-backend = "setuptools.build_meta"
|
|
|
39
40
|
|
|
40
41
|
[tool.setuptools]
|
|
41
42
|
package-dir = { "" = "src" }
|
|
43
|
+
include-package-data = true
|
|
42
44
|
|
|
43
45
|
[tool.setuptools.packages.find]
|
|
44
46
|
where = ["src"]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.package-data]
|
|
49
|
+
"mindor.core.controller.runtime.docker" = ["context/*"]
|
|
@@ -61,18 +61,20 @@ def up_command(
|
|
|
61
61
|
"--env", "-e", "env_data", multiple=True,
|
|
62
62
|
help="Environment variable in the form KEY=VALUE. Repeatable.",
|
|
63
63
|
)
|
|
64
|
+
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output.")
|
|
64
65
|
@click.pass_context
|
|
65
66
|
def down_command(
|
|
66
67
|
ctx: click.Context,
|
|
67
68
|
env_files: List[Path],
|
|
68
69
|
env_data: List[str],
|
|
70
|
+
verbose: bool
|
|
69
71
|
) -> None:
|
|
70
72
|
config_files = ctx.obj.get("config_files", [])
|
|
71
73
|
async def _async_command():
|
|
72
74
|
try:
|
|
73
75
|
env = load_env_files(".", env_files or [])
|
|
74
76
|
config = load_compose_config(".", config_files, env)
|
|
75
|
-
await
|
|
77
|
+
await terminate_services(config, verbose)
|
|
76
78
|
except Exception as e:
|
|
77
79
|
click.echo(f"❌ {e}", err=True)
|
|
78
80
|
asyncio.run(_async_command())
|
|
@@ -117,18 +119,20 @@ def start_command(
|
|
|
117
119
|
"--env", "-e", "env_data", multiple=True,
|
|
118
120
|
help="Environment variable in the form KEY=VALUE. Repeatable.",
|
|
119
121
|
)
|
|
122
|
+
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output.")
|
|
120
123
|
@click.pass_context
|
|
121
124
|
def stop_command(
|
|
122
125
|
ctx: click.Context,
|
|
123
126
|
env_files: List[Path],
|
|
124
127
|
env_data: List[str],
|
|
128
|
+
verbose: bool
|
|
125
129
|
) -> None:
|
|
126
130
|
config_files = ctx.obj.get("config_files", [])
|
|
127
131
|
async def _async_command():
|
|
128
132
|
try:
|
|
129
133
|
env = load_env_files(".", env_files or [])
|
|
130
134
|
config = load_compose_config(".", config_files, env)
|
|
131
|
-
await stop_services(config)
|
|
135
|
+
await stop_services(config, verbose)
|
|
132
136
|
except Exception as e:
|
|
133
137
|
click.echo(f"❌ {e}", err=True)
|
|
134
138
|
asyncio.run(_async_command())
|
|
@@ -184,3 +188,6 @@ compose_command.add_command(down_command)
|
|
|
184
188
|
compose_command.add_command(start_command)
|
|
185
189
|
compose_command.add_command(stop_command)
|
|
186
190
|
compose_command.add_command(run_command)
|
|
191
|
+
|
|
192
|
+
if __name__ == "__main__":
|
|
193
|
+
compose_command()
|
|
@@ -5,14 +5,14 @@ from .manager import ComposeManager, TaskState
|
|
|
5
5
|
async def launch_services(config: ComposeConfig, detach: bool, verbose: bool):
|
|
6
6
|
await ComposeManager(config, daemon=True).launch_services(detach, verbose)
|
|
7
7
|
|
|
8
|
-
async def
|
|
9
|
-
await ComposeManager(config, daemon=False).
|
|
8
|
+
async def terminate_services(config: ComposeConfig, verbose: bool):
|
|
9
|
+
await ComposeManager(config, daemon=False).terminate_services(verbose)
|
|
10
10
|
|
|
11
11
|
async def start_services(config: ComposeConfig, verbose: bool):
|
|
12
12
|
await ComposeManager(config, daemon=False).start_services(verbose)
|
|
13
13
|
|
|
14
|
-
async def stop_services(config: ComposeConfig):
|
|
15
|
-
await ComposeManager(config, daemon=False).stop_services()
|
|
14
|
+
async def stop_services(config: ComposeConfig, verbose: bool):
|
|
15
|
+
await ComposeManager(config, daemon=False).stop_services(verbose)
|
|
16
16
|
|
|
17
17
|
async def run_workflow(config: ComposeConfig, workflow_id: Optional[str], input: Dict[str, Any], verbose: bool) -> TaskState:
|
|
18
18
|
return await ComposeManager(config, daemon=False).run_workflow(workflow_id, input, verbose)
|
|
@@ -16,17 +16,15 @@ class ComposeManager:
|
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
async def launch_services(self, detach: bool, verbose: bool):
|
|
19
|
-
await self.controller.
|
|
20
|
-
await self.controller.wait_until_stopped()
|
|
19
|
+
await self.controller.launch(detach, verbose)
|
|
21
20
|
|
|
22
|
-
async def
|
|
23
|
-
await self.controller.
|
|
21
|
+
async def terminate_services(self, verbose: bool):
|
|
22
|
+
await self.controller.terminate(verbose)
|
|
24
23
|
|
|
25
24
|
async def start_services(self, verbose: bool):
|
|
26
25
|
await self.controller.start()
|
|
27
|
-
await self.controller.wait_until_stopped()
|
|
28
26
|
|
|
29
|
-
async def stop_services(self):
|
|
27
|
+
async def stop_services(self, verbose: bool):
|
|
30
28
|
await self.controller.stop()
|
|
31
29
|
|
|
32
30
|
async def run_workflow(self, workflow_id: Optional[str], input: Dict[str, Any], verbose: bool) -> TaskState:
|