model-compose 0.2.11__tar.gz → 0.3.0__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.11/src/model_compose.egg-info → model_compose-0.3.0}/PKG-INFO +3 -2
- {model_compose-0.2.11 → model_compose-0.3.0}/pyproject.toml +8 -3
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/cli/compose.py +9 -2
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/tasks/__init__.py +1 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/tasks/summarization.py +22 -19
- model_compose-0.3.0/src/mindor/core/component/services/model/tasks/text_classification.py +78 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/tasks/text_embedding.py +18 -14
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/tasks/text_generation.py +21 -18
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/tasks/translation.py +21 -18
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/compose/compose.py +4 -4
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/compose/manager.py +4 -6
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/base.py +48 -18
- model_compose-0.3.0/src/mindor/core/controller/runtime/docker/__init__.py +1 -0
- model_compose-0.3.0/src/mindor/core/controller/runtime/docker/context/Dockerfile +42 -0
- model_compose-0.3.0/src/mindor/core/controller/runtime/docker/docker.py +102 -0
- model_compose-0.3.0/src/mindor/core/controller/runtime/specs.py +40 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/services/console.py +1 -1
- model_compose-0.3.0/src/mindor/core/runtime/docker/__init__.py +1 -0
- model_compose-0.3.0/src/mindor/core/runtime/docker/docker.py +263 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/runtime/env.py +0 -2
- {model_compose-0.2.11/src/mindor/dsl/schema/component → model_compose-0.3.0/src/mindor/dsl/schema/action}/impl/model/impl/__init__.py +1 -0
- model_compose-0.3.0/src/mindor/dsl/schema/action/impl/model/impl/summarization.py +18 -0
- model_compose-0.3.0/src/mindor/dsl/schema/action/impl/model/impl/text_classification.py +12 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/model/impl/text_embedding.py +4 -4
- model_compose-0.3.0/src/mindor/dsl/schema/action/impl/model/impl/text_generation.py +16 -0
- model_compose-0.3.0/src/mindor/dsl/schema/action/impl/model/impl/translation.py +16 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/model/model.py +1 -0
- {model_compose-0.2.11/src/mindor/dsl/schema/action → model_compose-0.3.0/src/mindor/dsl/schema/component}/impl/model/impl/__init__.py +1 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/impl/common.py +3 -0
- model_compose-0.3.0/src/mindor/dsl/schema/component/impl/model/impl/text_classification.py +9 -0
- model_compose-0.3.0/src/mindor/dsl/schema/component/impl/model/impl/types.py +8 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/model.py +1 -0
- model_compose-0.3.0/src/mindor/dsl/schema/controller/impl/common.py +21 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/impl/http_server.py +4 -4
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/impl/mcp_server.py +3 -3
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/impl/webui.py +2 -2
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/runtime/impl/__init__.py +1 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/runtime/impl/common.py +1 -1
- model_compose-0.3.0/src/mindor/dsl/schema/runtime/impl/docker.py +72 -0
- model_compose-0.2.11/src/mindor/dsl/schema/runtime/impl/docker.py → model_compose-0.3.0/src/mindor/dsl/schema/runtime/impl/native.py +3 -3
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/runtime/impl/types.py +1 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/runtime/runtime.py +2 -5
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/workflow.py +2 -2
- model_compose-0.3.0/src/mindor/dsl/utils/__init__.py +0 -0
- model_compose-0.3.0/src/mindor/dsl/utils/enum.py +27 -0
- {model_compose-0.2.11 → model_compose-0.3.0/src/model_compose.egg-info}/PKG-INFO +3 -2
- {model_compose-0.2.11 → model_compose-0.3.0}/src/model_compose.egg-info/SOURCES.txt +12 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/model_compose.egg-info/requires.txt +2 -1
- model_compose-0.2.11/src/mindor/dsl/schema/action/impl/model/impl/summarization.py +0 -17
- model_compose-0.2.11/src/mindor/dsl/schema/action/impl/model/impl/text_generation.py +0 -15
- model_compose-0.2.11/src/mindor/dsl/schema/action/impl/model/impl/translation.py +0 -15
- model_compose-0.2.11/src/mindor/dsl/schema/component/impl/model/impl/types.py +0 -7
- model_compose-0.2.11/src/mindor/dsl/schema/controller/impl/common.py +0 -13
- {model_compose-0.2.11 → model_compose-0.3.0}/LICENSE +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/README.md +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/setup.cfg +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/cli/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/base.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/component.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/context.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/http_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/http_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/mcp_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/mcp_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/base.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/model/model.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/shell.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/component/services/workflow.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/compose/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/controller.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/runner/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/runner/client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/runner/http_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/runner/mcp_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/runner/runner.py +0 -0
- {model_compose-0.2.11/src/mindor/core → model_compose-0.3.0/src/mindor/core/controller}/runtime/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/services/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/services/http_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/services/mcp_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/webui/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/webui/gradio.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/controller/webui/webui.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/gateway/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/gateway/base.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/gateway/gateway.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/gateway/services/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/gateway/services/http_tunnel.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/gateway/services/ssh_tunnel.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/listener/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/listener/base.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/listener/listener.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/listener/services/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/listener/services/http_callback.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/base.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/logger.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/logging.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/services/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/logger/services/file.py +0 -0
- {model_compose-0.2.11/src/mindor/core/utils → model_compose-0.3.0/src/mindor/core/runtime}/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/services/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/services/async_service.py +0 -0
- {model_compose-0.2.11/src/mindor/dsl → model_compose-0.3.0/src/mindor/core/utils}/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/expiring.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/http_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/http_request.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/http_status.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/image.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/mcp_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/renderer.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/ssh_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/streaming.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/time.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/utils/workqueue.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/context.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/job/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/job/base.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/job/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/job/impl/action.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/job/impl/delay.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/job/job.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/schema.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/core/workflow/workflow.py +0 -0
- {model_compose-0.2.11/src/mindor/dsl/schema → model_compose-0.3.0/src/mindor/dsl}/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/loader.py +0 -0
- {model_compose-0.2.11/src/mindor/dsl/utils → model_compose-0.3.0/src/mindor/dsl/schema}/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/action.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/http_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/http_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/model/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/model/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/action/impl/workflow.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/component.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/http_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/impl/summarization.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/impl/text_embedding.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/impl/text_generation.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/model/impl/translation.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/types.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/component/impl/workflow.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/compose.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/controller.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/impl/action.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/impl/delay.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/impl/types.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/job/job.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/listener/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/listener/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/listener/impl/http_callback.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/listener/listener.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/impl/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/impl/common.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/impl/console.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/impl/file.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/impl/types.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/logger/logger.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/mindor/dsl/utils/annotation.py +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/model_compose.egg-info/dependency_links.txt +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/model_compose.egg-info/entry_points.txt +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/src/model_compose.egg-info/top_level.txt +0 -0
- {model_compose-0.2.11 → model_compose-0.3.0}/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.0
|
|
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
|
|
@@ -20,10 +20,11 @@ Requires-Dist: pyngrok
|
|
|
20
20
|
Requires-Dist: ulid
|
|
21
21
|
Requires-Dist: gradio
|
|
22
22
|
Requires-Dist: Pillow
|
|
23
|
-
Requires-Dist: transformers
|
|
23
|
+
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "model-compose"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "model-compose: Declarative AI Model and Workflow Orchestrator"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Hanyeol Cho", email = "hanyeol.cho@gmail.com" }
|
|
@@ -21,10 +21,11 @@ dependencies = [
|
|
|
21
21
|
"ulid",
|
|
22
22
|
"gradio",
|
|
23
23
|
"Pillow",
|
|
24
|
-
"transformers",
|
|
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()
|
|
@@ -16,7 +16,6 @@ class SummarizationTaskAction:
|
|
|
16
16
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
17
17
|
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
18
18
|
|
|
19
|
-
# Model parameters
|
|
20
19
|
max_input_length = await context.render_variable(self.config.params.max_input_length)
|
|
21
20
|
max_output_length = await context.render_variable(self.config.params.max_output_length)
|
|
22
21
|
min_output_length = await context.render_variable(self.config.params.min_output_length)
|
|
@@ -24,28 +23,32 @@ class SummarizationTaskAction:
|
|
|
24
23
|
length_penalty = await context.render_variable(self.config.params.length_penalty)
|
|
25
24
|
early_stopping = await context.render_variable(self.config.params.early_stopping)
|
|
26
25
|
do_sample = await context.render_variable(self.config.params.do_sample)
|
|
26
|
+
batch_size = await context.render_variable(self.config.params.batch_size)
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
texts: List[str] = [ text ] if isinstance(text, str) else text
|
|
29
|
+
results = []
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
**inputs,
|
|
35
|
-
max_length=max_output_length,
|
|
36
|
-
min_length=min_output_length,
|
|
37
|
-
num_beams=num_beams,
|
|
38
|
-
length_penalty=length_penalty,
|
|
39
|
-
early_stopping=early_stopping,
|
|
40
|
-
do_sample=do_sample,
|
|
41
|
-
pad_token_id=getattr(self.tokenizer, "pad_token_id", None),
|
|
42
|
-
eos_token_id=getattr(self.tokenizer, "eos_token_id", None)
|
|
43
|
-
)
|
|
31
|
+
for index in range(0, len(texts), batch_size):
|
|
32
|
+
batch_texts = texts[index:index + batch_size]
|
|
33
|
+
inputs = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True).to(self.model.device)
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
with torch.no_grad():
|
|
36
|
+
outputs = self.model.generate(
|
|
37
|
+
**inputs,
|
|
38
|
+
max_length=max_output_length,
|
|
39
|
+
min_length=min_output_length,
|
|
40
|
+
num_beams=num_beams,
|
|
41
|
+
length_penalty=length_penalty,
|
|
42
|
+
early_stopping=early_stopping,
|
|
43
|
+
do_sample=do_sample,
|
|
44
|
+
pad_token_id=getattr(self.tokenizer, "pad_token_id", None),
|
|
45
|
+
eos_token_id=getattr(self.tokenizer, "eos_token_id", None)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
outputs = self.tokenizer.batch_decode(outputs, skip_special_tokens=True)
|
|
49
|
+
results.extend(outputs)
|
|
47
50
|
|
|
48
|
-
result =
|
|
51
|
+
result = results if len(results) > 1 else results[0]
|
|
49
52
|
context.register_source("result", result)
|
|
50
53
|
|
|
51
54
|
return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else result
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
|
+
from mindor.dsl.schema.component import ModelComponentConfig
|
|
3
|
+
from mindor.dsl.schema.action import ModelActionConfig, TextClassificationModelActionConfig
|
|
4
|
+
from mindor.core.logger import logging
|
|
5
|
+
from ..base import ModelTaskService, ModelTaskType, register_model_task_service
|
|
6
|
+
from ..base import ComponentActionContext
|
|
7
|
+
from transformers import AutoModelForSequenceClassification, AutoTokenizer, PreTrainedModel, PreTrainedTokenizer
|
|
8
|
+
from transformers.modeling_outputs import SequenceClassifierOutput
|
|
9
|
+
import torch.nn.functional as F
|
|
10
|
+
import torch
|
|
11
|
+
|
|
12
|
+
class TextClassificationTaskAction:
|
|
13
|
+
def __init__(self, config: TextClassificationModelActionConfig, model: PreTrainedModel, tokenizer: PreTrainedTokenizer):
|
|
14
|
+
self.config: TextClassificationModelActionConfig = config
|
|
15
|
+
self.model: PreTrainedModel = model
|
|
16
|
+
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
17
|
+
|
|
18
|
+
async def run(self, context: ComponentActionContext, labels: Optional[List[str]]) -> Any:
|
|
19
|
+
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
20
|
+
|
|
21
|
+
return_probabilities = await context.render_variable(self.config.params.return_probabilities)
|
|
22
|
+
batch_size = await context.render_variable(self.config.params.batch_size)
|
|
23
|
+
|
|
24
|
+
texts: List[str] = [ text ] if isinstance(text, str) else text
|
|
25
|
+
results = []
|
|
26
|
+
|
|
27
|
+
for index in range(0, len(texts), batch_size):
|
|
28
|
+
batch_texts = texts[index:index + batch_size]
|
|
29
|
+
inputs = self.tokenizer(batch_texts, return_tensors="pt", padding=True, truncation=True).to(self.model.device)
|
|
30
|
+
|
|
31
|
+
with torch.no_grad():
|
|
32
|
+
outputs: SequenceClassifierOutput = self.model(**inputs)
|
|
33
|
+
logits = outputs.logits # shape: (batch_size, num_classes)
|
|
34
|
+
|
|
35
|
+
predicted = []
|
|
36
|
+
if return_probabilities:
|
|
37
|
+
probs = F.softmax(logits, dim=-1).cpu()
|
|
38
|
+
for prob in probs:
|
|
39
|
+
predicted_index = torch.argmax(prob).item()
|
|
40
|
+
predicted.append({
|
|
41
|
+
"label": labels[predicted_index] if labels else predicted_index,
|
|
42
|
+
"probabilities": prob.tolist()
|
|
43
|
+
})
|
|
44
|
+
else:
|
|
45
|
+
predicted_indices = torch.argmax(logits, dim=-1).tolist()
|
|
46
|
+
for predicted_index in predicted_indices:
|
|
47
|
+
predicted.append(labels[predicted_index] if labels else predicted_index)
|
|
48
|
+
|
|
49
|
+
results.extend(predicted)
|
|
50
|
+
|
|
51
|
+
result = results if len(results) > 1 else results[0]
|
|
52
|
+
context.register_source("result", result)
|
|
53
|
+
|
|
54
|
+
return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else result
|
|
55
|
+
|
|
56
|
+
@register_model_task_service(ModelTaskType.TEXT_CLASSIFICATION)
|
|
57
|
+
class TextClassificationTaskService(ModelTaskService):
|
|
58
|
+
def __init__(self, id: str, config: ModelComponentConfig, daemon: bool):
|
|
59
|
+
super().__init__(id, config, daemon)
|
|
60
|
+
|
|
61
|
+
self.model: Optional[PreTrainedModel] = None
|
|
62
|
+
self.tokenizer: Optional[PreTrainedTokenizer] = None
|
|
63
|
+
|
|
64
|
+
async def _serve(self) -> None:
|
|
65
|
+
try:
|
|
66
|
+
self.model = AutoModelForSequenceClassification.from_pretrained(self.config.model).to(torch.device(self.config.device))
|
|
67
|
+
self.tokenizer = AutoTokenizer.from_pretrained(self.config.model, use_fast=self.config.fast_tokenizer)
|
|
68
|
+
logging.info(f"Model and tokenizer loaded successfully on device '{self.config.device}': {self.config.model}")
|
|
69
|
+
except Exception as e:
|
|
70
|
+
logging.error(f"Failed to load model '{self.config.model}': {e}")
|
|
71
|
+
raise
|
|
72
|
+
|
|
73
|
+
async def _shutdown(self) -> None:
|
|
74
|
+
self.model = None
|
|
75
|
+
self.tokenizer = None
|
|
76
|
+
|
|
77
|
+
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
78
|
+
return await TextClassificationTaskAction(action, self.model, self.tokenizer).run(context, self.config.labels)
|
|
@@ -16,29 +16,33 @@ class TextEmbeddingTaskAction:
|
|
|
16
16
|
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
17
17
|
|
|
18
18
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
19
|
-
text = await context.render_variable(self.config.text)
|
|
19
|
+
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
20
20
|
|
|
21
|
-
# Model parameters
|
|
22
21
|
max_input_length = await context.render_variable(self.config.params.max_input_length)
|
|
23
22
|
pooling = await context.render_variable(self.config.params.pooling)
|
|
24
23
|
normalize = await context.render_variable(self.config.params.normalize)
|
|
24
|
+
batch_size = await context.render_variable(self.config.params.batch_size)
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
attention_mask: Tensor = inputs.get("attention_mask", None)
|
|
26
|
+
texts: List[str] = [ text ] if isinstance(text, str) else text
|
|
27
|
+
results = []
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
for index in range(0, len(texts), batch_size):
|
|
30
|
+
batch_texts = texts[index:index + batch_size]
|
|
31
|
+
inputs = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True).to(self.model.device)
|
|
32
|
+
attention_mask: Tensor = inputs.get("attention_mask", None)
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
with torch.no_grad():
|
|
35
|
+
outputs: BaseModelOutput = self.model(**inputs)
|
|
36
|
+
last_hidden_state = outputs.last_hidden_state # (batch_size, seq_len, hidden_size)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
embedding = torch.nn.functional.normalize(embedding, p=2, dim=1)
|
|
38
|
+
embeddings = self._pool_hidden_state(last_hidden_state, attention_mask, pooling)
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
if normalize:
|
|
41
|
+
embeddings = torch.nn.functional.normalize(embeddings, p=2, dim=1)
|
|
42
|
+
|
|
43
|
+
results.extend(embeddings.cpu().tolist())
|
|
44
|
+
|
|
45
|
+
result = results if len(results) > 1 else results[0]
|
|
42
46
|
context.register_source("result", result)
|
|
43
47
|
|
|
44
48
|
return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else result
|
|
@@ -16,32 +16,35 @@ class TextGenerationTaskAction:
|
|
|
16
16
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
17
17
|
prompt: Union[str, List[str]] = await context.render_variable(self.config.prompt)
|
|
18
18
|
|
|
19
|
-
# Model parameters
|
|
20
19
|
max_output_length = await context.render_variable(self.config.params.max_output_length)
|
|
21
20
|
num_return_sequences = await context.render_variable(self.config.params.num_return_sequences)
|
|
22
21
|
temperature = await context.render_variable(self.config.params.temperature)
|
|
23
22
|
top_k = await context.render_variable(self.config.params.top_k)
|
|
24
23
|
top_p = await context.render_variable(self.config.params.top_p)
|
|
24
|
+
batch_size = await context.render_variable(self.config.params.batch_size)
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
prompts: List[str] = [ prompt ] if isinstance(prompt, str) else prompt
|
|
27
|
+
results = []
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
**inputs,
|
|
33
|
-
max_length=max_output_length,
|
|
34
|
-
num_return_sequences=num_return_sequences,
|
|
35
|
-
temperature=temperature,
|
|
36
|
-
top_k=top_k,
|
|
37
|
-
top_p=top_p,
|
|
38
|
-
do_sample=True
|
|
39
|
-
)
|
|
29
|
+
for index in range(0, len(prompts), batch_size):
|
|
30
|
+
batch_prompts = prompts[index:index + batch_size]
|
|
31
|
+
inputs = self.tokenizer(batch_prompts, return_tensors="pt").to(self.model.device)
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
33
|
+
with torch.no_grad():
|
|
34
|
+
outputs = self.model.generate(
|
|
35
|
+
**inputs,
|
|
36
|
+
max_new_tokens=max_output_length,
|
|
37
|
+
num_return_sequences=num_return_sequences,
|
|
38
|
+
temperature=temperature,
|
|
39
|
+
top_k=top_k,
|
|
40
|
+
top_p=top_p,
|
|
41
|
+
do_sample=True
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
outputs = self.tokenizer.batch_decode(outputs, skip_special_tokens=True)
|
|
45
|
+
results.extend(outputs)
|
|
46
|
+
|
|
47
|
+
result = results if len(results) > 1 else results[0]
|
|
45
48
|
context.register_source("result", result)
|
|
46
49
|
|
|
47
50
|
return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else result
|
|
@@ -16,33 +16,36 @@ class TranslationTaskAction:
|
|
|
16
16
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
17
17
|
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
18
18
|
|
|
19
|
-
# Model parameters
|
|
20
19
|
max_input_length = await context.render_variable(self.config.params.max_input_length)
|
|
21
20
|
max_output_length = await context.render_variable(self.config.params.max_output_length)
|
|
22
21
|
min_output_length = await context.render_variable(self.config.params.min_output_length)
|
|
23
22
|
num_beams = await context.render_variable(self.config.params.num_beams)
|
|
24
23
|
length_penalty = await context.render_variable(self.config.params.length_penalty)
|
|
24
|
+
batch_size = await context.render_variable(self.config.params.batch_size)
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
texts: List[str] = [ text ] if isinstance(text, str) else text
|
|
27
|
+
results = []
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
**inputs,
|
|
33
|
-
max_length=max_output_length,
|
|
34
|
-
min_length=min_output_length,
|
|
35
|
-
num_beams=num_beams,
|
|
36
|
-
length_penalty=length_penalty,
|
|
37
|
-
do_sample=False,
|
|
38
|
-
pad_token_id=getattr(self.tokenizer, "pad_token_id", None),
|
|
39
|
-
eos_token_id=getattr(self.tokenizer, "eos_token_id", None)
|
|
40
|
-
)
|
|
29
|
+
for index in range(0, len(texts), batch_size):
|
|
30
|
+
batch_texts = texts[index:index + batch_size]
|
|
31
|
+
inputs = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True).to(self.model.device)
|
|
41
32
|
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
with torch.no_grad():
|
|
34
|
+
outputs = self.model.generate(
|
|
35
|
+
**inputs,
|
|
36
|
+
max_length=max_output_length,
|
|
37
|
+
min_length=min_output_length,
|
|
38
|
+
num_beams=num_beams,
|
|
39
|
+
length_penalty=length_penalty,
|
|
40
|
+
do_sample=False,
|
|
41
|
+
pad_token_id=getattr(self.tokenizer, "pad_token_id", None),
|
|
42
|
+
eos_token_id=getattr(self.tokenizer, "eos_token_id", None)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
outputs = self.tokenizer.batch_decode(outputs, skip_special_tokens=True)
|
|
46
|
+
results.extend(outputs)
|
|
44
47
|
|
|
45
|
-
result =
|
|
48
|
+
result = results if len(results) > 1 else results[0]
|
|
46
49
|
context.register_source("result", result)
|
|
47
50
|
|
|
48
51
|
return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else result
|
|
@@ -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:
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
2
|
from enum import Enum
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
+
from pydantic import BaseModel
|
|
4
5
|
from mindor.dsl.schema.controller import ControllerConfig, ControllerType
|
|
5
6
|
from mindor.dsl.schema.component import ComponentConfig
|
|
6
7
|
from mindor.dsl.schema.listener import ListenerConfig
|
|
7
8
|
from mindor.dsl.schema.gateway import GatewayConfig
|
|
8
|
-
from mindor.dsl.schema.logger import LoggerConfig, LoggerType, ConsoleLoggerConfig
|
|
9
9
|
from mindor.dsl.schema.workflow import WorkflowConfig
|
|
10
|
+
from mindor.dsl.schema.runtime import RuntimeType, DockerBuildConfig
|
|
11
|
+
from mindor.dsl.schema.logger import LoggerConfig, LoggerType, ConsoleLoggerConfig
|
|
10
12
|
from mindor.core.services import AsyncService
|
|
11
13
|
from mindor.core.component import ComponentService, ComponentGlobalConfigs, create_component
|
|
12
14
|
from mindor.core.listener import ListenerService, create_listener
|
|
@@ -16,6 +18,8 @@ from mindor.core.logger import LoggerService, create_logger
|
|
|
16
18
|
from mindor.core.controller.webui import ControllerWebUI
|
|
17
19
|
from mindor.core.utils.workqueue import WorkQueue
|
|
18
20
|
from mindor.core.utils.expiring import ExpiringDict
|
|
21
|
+
from .runtime.specs import ControllerRuntimeSpecs
|
|
22
|
+
from .runtime.docker import DockerRuntimeLauncher
|
|
19
23
|
from threading import Lock
|
|
20
24
|
import asyncio, ulid
|
|
21
25
|
|
|
@@ -58,6 +62,29 @@ class ControllerService(AsyncService):
|
|
|
58
62
|
if self.config.max_concurrent_count > 0:
|
|
59
63
|
self.queue = WorkQueue(self.config.max_concurrent_count, self._run_workflow)
|
|
60
64
|
|
|
65
|
+
async def launch(self, detach: bool, verbose: bool) -> None:
|
|
66
|
+
if self.config.runtime.type == RuntimeType.NATIVE:
|
|
67
|
+
if detach:
|
|
68
|
+
pass
|
|
69
|
+
await self.start()
|
|
70
|
+
await self.wait_until_stopped()
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
if self.config.runtime.type == RuntimeType.DOCKER:
|
|
74
|
+
await self._start_loggers()
|
|
75
|
+
await DockerRuntimeLauncher(self.config, verbose).launch(self._get_runtime_specs(), detach)
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
async def terminate(self, verbose: bool) -> None:
|
|
79
|
+
if self.config.runtime.type == RuntimeType.NATIVE:
|
|
80
|
+
await self.stop()
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if self.config.runtime.type == RuntimeType.DOCKER:
|
|
84
|
+
await self._start_loggers()
|
|
85
|
+
await DockerRuntimeLauncher(self.config, verbose).terminate()
|
|
86
|
+
return
|
|
87
|
+
|
|
61
88
|
async def run_workflow(self, workflow_id: Optional[str], input: Dict[str, Any], wait_for_completion: bool = True) -> TaskState:
|
|
62
89
|
task_id = ulid.ulid()
|
|
63
90
|
state = TaskState(task_id=task_id, status=TaskStatus.PENDING)
|
|
@@ -138,23 +165,6 @@ class ControllerService(AsyncService):
|
|
|
138
165
|
async def _stop_webui(self) -> None:
|
|
139
166
|
await asyncio.gather(*[ self._create_webui().stop() ])
|
|
140
167
|
|
|
141
|
-
async def _run_workflow(self, task_id: str, workflow_id: Optional[str], input: Dict[str, Any]) -> TaskState:
|
|
142
|
-
state = TaskState(task_id=task_id, status=TaskStatus.PROCESSING)
|
|
143
|
-
with self.task_states_lock:
|
|
144
|
-
self.task_states.set(task_id, state)
|
|
145
|
-
|
|
146
|
-
try:
|
|
147
|
-
workflow = self._create_workflow(workflow_id)
|
|
148
|
-
output = await workflow.run(task_id, input)
|
|
149
|
-
state = TaskState(task_id=task_id, status=TaskStatus.COMPLETED, output=output)
|
|
150
|
-
except Exception as e:
|
|
151
|
-
state = TaskState(task_id=task_id, status=TaskStatus.FAILED, error=str(e))
|
|
152
|
-
|
|
153
|
-
with self.task_states_lock:
|
|
154
|
-
self.task_states.set(task_id, state, 1 * 3600)
|
|
155
|
-
|
|
156
|
-
return state
|
|
157
|
-
|
|
158
168
|
def _create_listeners(self) -> List[ListenerService]:
|
|
159
169
|
return [ create_listener(f"listener-{index}", config, self.daemon) for index, config in enumerate(self.listeners) ]
|
|
160
170
|
|
|
@@ -175,12 +185,32 @@ class ControllerService(AsyncService):
|
|
|
175
185
|
global_configs = self._get_component_global_configs()
|
|
176
186
|
return create_workflow(*WorkflowResolver(self.workflows).resolve(workflow_id), global_configs)
|
|
177
187
|
|
|
188
|
+
def _get_runtime_specs(self) -> ControllerRuntimeSpecs:
|
|
189
|
+
return ControllerRuntimeSpecs(self.config, self.components, self.listeners, self.gateways, self.workflows)
|
|
190
|
+
|
|
178
191
|
def _get_component_global_configs(self) -> ComponentGlobalConfigs:
|
|
179
192
|
return ComponentGlobalConfigs(self.components, self.listeners, self.gateways, self.workflows)
|
|
180
193
|
|
|
181
194
|
def _get_default_logger_config(self) -> LoggerConfig:
|
|
182
195
|
return ConsoleLoggerConfig(type=LoggerType.CONSOLE)
|
|
183
196
|
|
|
197
|
+
async def _run_workflow(self, task_id: str, workflow_id: Optional[str], input: Dict[str, Any]) -> TaskState:
|
|
198
|
+
state = TaskState(task_id=task_id, status=TaskStatus.PROCESSING)
|
|
199
|
+
with self.task_states_lock:
|
|
200
|
+
self.task_states.set(task_id, state)
|
|
201
|
+
|
|
202
|
+
try:
|
|
203
|
+
workflow = self._create_workflow(workflow_id)
|
|
204
|
+
output = await workflow.run(task_id, input)
|
|
205
|
+
state = TaskState(task_id=task_id, status=TaskStatus.COMPLETED, output=output)
|
|
206
|
+
except Exception as e:
|
|
207
|
+
state = TaskState(task_id=task_id, status=TaskStatus.FAILED, error=str(e))
|
|
208
|
+
|
|
209
|
+
with self.task_states_lock:
|
|
210
|
+
self.task_states.set(task_id, state, 1 * 3600)
|
|
211
|
+
|
|
212
|
+
return state
|
|
213
|
+
|
|
184
214
|
def register_controller(type: ControllerType):
|
|
185
215
|
def decorator(cls: Type[ControllerService]) -> Type[ControllerService]:
|
|
186
216
|
ControllerRegistry[type] = cls
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .docker import *
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
FROM ubuntu:22.04
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
RUN apt update && apt install -y \
|
|
6
|
+
python3.11 \
|
|
7
|
+
python3.11-venv \
|
|
8
|
+
python3-pip \
|
|
9
|
+
gcc \
|
|
10
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
11
|
+
|
|
12
|
+
RUN ln -sf /usr/bin/python3.11 /usr/bin/python && \
|
|
13
|
+
ln -sf /usr/bin/python3.11 /usr/bin/python3
|
|
14
|
+
|
|
15
|
+
RUN python -m pip install --upgrade pip
|
|
16
|
+
RUN pip install --no-cache-dir \
|
|
17
|
+
click \
|
|
18
|
+
pyyaml \
|
|
19
|
+
pydantic \
|
|
20
|
+
python-dotenv \
|
|
21
|
+
aiohttp \
|
|
22
|
+
requests \
|
|
23
|
+
fastapi \
|
|
24
|
+
uvicorn \
|
|
25
|
+
'mcp>=1.10.1' \
|
|
26
|
+
pyngrok \
|
|
27
|
+
ulid \
|
|
28
|
+
gradio \
|
|
29
|
+
Pillow \
|
|
30
|
+
'transformers>=4.21.0' \
|
|
31
|
+
torch \
|
|
32
|
+
sentencepiece \
|
|
33
|
+
accelerate \
|
|
34
|
+
docker
|
|
35
|
+
|
|
36
|
+
COPY requirements.txt .
|
|
37
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
38
|
+
|
|
39
|
+
COPY src .
|
|
40
|
+
COPY model-compose.yml .
|
|
41
|
+
|
|
42
|
+
CMD [ "python", "-m", "mindor.cli.compose", "up" ]
|