model-compose 0.3.18__tar.gz → 0.4.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.
Files changed (255) hide show
  1. {model_compose-0.3.18 → model_compose-0.4.0}/PKG-INFO +15 -15
  2. {model_compose-0.3.18 → model_compose-0.4.0}/README.md +14 -14
  3. {model_compose-0.3.18 → model_compose-0.4.0}/pyproject.toml +1 -1
  4. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runner/http_client.py +1 -2
  5. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/services/http_server.py +50 -47
  6. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/webui/gradio.py +28 -7
  7. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/schema.py +5 -2
  8. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/if_.py +1 -1
  9. {model_compose-0.3.18 → model_compose-0.4.0}/src/model_compose.egg-info/PKG-INFO +15 -15
  10. {model_compose-0.3.18 → model_compose-0.4.0}/LICENSE +0 -0
  11. {model_compose-0.3.18 → model_compose-0.4.0}/setup.cfg +0 -0
  12. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/__init__.py +0 -0
  13. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/cli/__init__.py +0 -0
  14. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/cli/compose.py +0 -0
  15. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/__init__.py +0 -0
  16. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/__init__.py +0 -0
  17. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/base.py +0 -0
  18. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/component.py +0 -0
  19. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/context.py +0 -0
  20. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/__init__.py +0 -0
  21. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/http_client.py +0 -0
  22. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/http_server.py +0 -0
  23. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/mcp_client.py +0 -0
  24. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/mcp_server.py +0 -0
  25. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/__init__.py +0 -0
  26. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/base.py +0 -0
  27. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/loader.py +0 -0
  28. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/model.py +0 -0
  29. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/__init__.py +0 -0
  30. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/image_to_text.py +0 -0
  31. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/summarization.py +0 -0
  32. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/text_classification.py +0 -0
  33. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/text_embedding.py +0 -0
  34. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/text_generation.py +0 -0
  35. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/model/tasks/translation.py +0 -0
  36. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/shell.py +0 -0
  37. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/text_splitter.py +0 -0
  38. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/vector_store/__init__.py +0 -0
  39. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/vector_store/base.py +0 -0
  40. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/vector_store/drivers/__init__.py +0 -0
  41. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/vector_store/drivers/chroma.py +0 -0
  42. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/vector_store/drivers/milvus.py +0 -0
  43. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/vector_store/vector_store.py +0 -0
  44. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/component/services/workflow.py +0 -0
  45. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/compose/__init__.py +0 -0
  46. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/compose/compose.py +0 -0
  47. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/compose/manager.py +0 -0
  48. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/__init__.py +0 -0
  49. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/base.py +0 -0
  50. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/controller.py +0 -0
  51. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runner/__init__.py +0 -0
  52. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runner/client.py +0 -0
  53. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runner/mcp_client.py +0 -0
  54. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runner/runner.py +0 -0
  55. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/__init__.py +0 -0
  56. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/docker/__init__.py +0 -0
  57. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/docker/context/Dockerfile +0 -0
  58. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/docker/docker.py +0 -0
  59. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/native/__init__.py +0 -0
  60. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/native/native.py +0 -0
  61. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/runtime/specs.py +0 -0
  62. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/services/__init__.py +0 -0
  63. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/services/mcp_server.py +0 -0
  64. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/webui/__init__.py +0 -0
  65. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/controller/webui/webui.py +0 -0
  66. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/gateway/__init__.py +0 -0
  67. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/gateway/base.py +0 -0
  68. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/gateway/gateway.py +0 -0
  69. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/gateway/services/__init__.py +0 -0
  70. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/gateway/services/http_tunnel.py +0 -0
  71. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/gateway/services/ssh_tunnel.py +0 -0
  72. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/listener/__init__.py +0 -0
  73. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/listener/base.py +0 -0
  74. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/listener/listener.py +0 -0
  75. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/listener/services/__init__.py +0 -0
  76. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/listener/services/http_callback.py +0 -0
  77. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/__init__.py +0 -0
  78. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/base.py +0 -0
  79. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/logger.py +0 -0
  80. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/logging.py +0 -0
  81. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/services/__init__.py +0 -0
  82. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/services/console.py +0 -0
  83. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/logger/services/file.py +0 -0
  84. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/runtime/__init__.py +0 -0
  85. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/runtime/docker/__init__.py +0 -0
  86. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/runtime/docker/docker.py +0 -0
  87. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/runtime/env.py +0 -0
  88. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/services/__init__.py +0 -0
  89. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/services/async_service.py +0 -0
  90. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/__init__.py +0 -0
  91. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/caching.py +0 -0
  92. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/http_client.py +0 -0
  93. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/http_request.py +0 -0
  94. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/http_response.py +0 -0
  95. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/http_status.py +0 -0
  96. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/image.py +0 -0
  97. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/mcp_client.py +0 -0
  98. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/package.py +0 -0
  99. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/renderers.py +0 -0
  100. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/resolvers.py +0 -0
  101. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/shell.py +0 -0
  102. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/ssh_client.py +0 -0
  103. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/streamer.py +0 -0
  104. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/streaming.py +0 -0
  105. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/time.py +0 -0
  106. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/utils/workqueue.py +0 -0
  107. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/__init__.py +0 -0
  108. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/context.py +0 -0
  109. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/__init__.py +0 -0
  110. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/base.py +0 -0
  111. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/__init__.py +0 -0
  112. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/action.py +0 -0
  113. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/delay.py +0 -0
  114. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/filter.py +0 -0
  115. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/if_.py +0 -0
  116. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/random_router.py +0 -0
  117. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/impl/switch.py +0 -0
  118. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/job/job.py +0 -0
  119. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/core/workflow/workflow.py +0 -0
  120. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/__init__.py +0 -0
  121. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/loader.py +0 -0
  122. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/__init__.py +0 -0
  123. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/__init__.py +0 -0
  124. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/action.py +0 -0
  125. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/__init__.py +0 -0
  126. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/common.py +0 -0
  127. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/http_client.py +0 -0
  128. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/http_server.py +0 -0
  129. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
  130. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
  131. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/__init__.py +0 -0
  132. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/__init__.py +0 -0
  133. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/chat_completion.py +0 -0
  134. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/common.py +0 -0
  135. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/image_to_text.py +0 -0
  136. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/summarization.py +0 -0
  137. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/text_classification.py +0 -0
  138. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/text_embedding.py +0 -0
  139. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/text_generation.py +0 -0
  140. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/impl/translation.py +0 -0
  141. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/model/model.py +0 -0
  142. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
  143. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/text_splitter.py +0 -0
  144. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/__init__.py +0 -0
  145. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/impl/__init__.py +0 -0
  146. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/impl/chroma.py +0 -0
  147. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/impl/common.py +0 -0
  148. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/impl/faiss.py +0 -0
  149. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/impl/milvus.py +0 -0
  150. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/impl/qdrant.py +0 -0
  151. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/vector_store/vector_store.py +0 -0
  152. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/action/impl/workflow.py +0 -0
  153. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/__init__.py +0 -0
  154. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/component.py +0 -0
  155. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/__init__.py +0 -0
  156. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/common.py +0 -0
  157. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/http_client.py +0 -0
  158. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
  159. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
  160. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
  161. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/__init__.py +0 -0
  162. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/__init__.py +0 -0
  163. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/chat_completion.py +0 -0
  164. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/common.py +0 -0
  165. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/image_to_text.py +0 -0
  166. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/summarization.py +0 -0
  167. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/text_classification.py +0 -0
  168. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/text_embedding.py +0 -0
  169. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/text_generation.py +0 -0
  170. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/translation.py +0 -0
  171. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/impl/types.py +0 -0
  172. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/model/model.py +0 -0
  173. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
  174. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/text_splitter.py +0 -0
  175. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/types.py +0 -0
  176. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/__init__.py +0 -0
  177. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/__init__.py +0 -0
  178. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/chroma.py +0 -0
  179. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/common.py +0 -0
  180. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/faiss.py +0 -0
  181. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/milvus.py +0 -0
  182. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/qdrant.py +0 -0
  183. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/impl/types.py +0 -0
  184. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/vector_store/vector_store.py +0 -0
  185. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/component/impl/workflow.py +0 -0
  186. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/compose.py +0 -0
  187. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/__init__.py +0 -0
  188. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/controller.py +0 -0
  189. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
  190. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/impl/common.py +0 -0
  191. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/impl/http_server.py +0 -0
  192. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/impl/mcp_server.py +0 -0
  193. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
  194. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/__init__.py +0 -0
  195. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/impl/__init__.py +0 -0
  196. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/impl/common.py +0 -0
  197. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/impl/dynamic.py +0 -0
  198. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/impl/gradio.py +0 -0
  199. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/impl/static.py +0 -0
  200. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/controller/webui/webui.py +0 -0
  201. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
  202. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
  203. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
  204. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/common.py +0 -0
  205. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel/__init__.py +0 -0
  206. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel/http_tunnel.py +0 -0
  207. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/__init__.py +0 -0
  208. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/cloudflare.py +0 -0
  209. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/common.py +0 -0
  210. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/ngrok.py +0 -0
  211. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
  212. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
  213. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/__init__.py +0 -0
  214. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/__init__.py +0 -0
  215. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/action.py +0 -0
  216. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/common.py +0 -0
  217. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/delay.py +0 -0
  218. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/filter.py +0 -0
  219. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/random_router.py +0 -0
  220. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/switch.py +0 -0
  221. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/impl/types.py +0 -0
  222. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/job/job.py +0 -0
  223. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/listener/__init__.py +0 -0
  224. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
  225. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/listener/impl/common.py +0 -0
  226. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/listener/impl/http_callback.py +0 -0
  227. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
  228. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/listener/listener.py +0 -0
  229. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/__init__.py +0 -0
  230. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/impl/__init__.py +0 -0
  231. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/impl/common.py +0 -0
  232. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/impl/console.py +0 -0
  233. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/impl/file.py +0 -0
  234. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/impl/types.py +0 -0
  235. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/logger/logger.py +0 -0
  236. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
  237. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/impl/__init__.py +0 -0
  238. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/impl/common.py +0 -0
  239. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/impl/docker.py +0 -0
  240. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/impl/native.py +0 -0
  241. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/impl/types.py +0 -0
  242. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/runtime/runtime.py +0 -0
  243. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/transport/__init__.py +0 -0
  244. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/transport/http.py +0 -0
  245. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/transport/ssh.py +0 -0
  246. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/schema/workflow.py +0 -0
  247. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/utils/__init__.py +0 -0
  248. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/utils/annotation.py +0 -0
  249. {model_compose-0.3.18 → model_compose-0.4.0}/src/mindor/dsl/utils/enum.py +0 -0
  250. {model_compose-0.3.18 → model_compose-0.4.0}/src/model_compose.egg-info/SOURCES.txt +0 -0
  251. {model_compose-0.3.18 → model_compose-0.4.0}/src/model_compose.egg-info/dependency_links.txt +0 -0
  252. {model_compose-0.3.18 → model_compose-0.4.0}/src/model_compose.egg-info/entry_points.txt +0 -0
  253. {model_compose-0.3.18 → model_compose-0.4.0}/src/model_compose.egg-info/requires.txt +0 -0
  254. {model_compose-0.3.18 → model_compose-0.4.0}/src/model_compose.egg-info/top_level.txt +0 -0
  255. {model_compose-0.3.18 → model_compose-0.4.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.18
3
+ Version: 0.4.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
@@ -153,7 +153,7 @@ By default, `model-compose` automatically looks for a file named `model-compose.
153
153
 
154
154
  #### 🧪 Minimal Example (with Components and Workflows)
155
155
 
156
- ```
156
+ ```yaml
157
157
  controller:
158
158
  type: http-server
159
159
  port: 8080
@@ -174,7 +174,7 @@ components:
174
174
  model: gpt-4o
175
175
  messages:
176
176
  - role: user
177
- content: "Write an inspiring quote."
177
+ content: Write an inspiring quote.
178
178
  output:
179
179
  quote: ${response.choices[0].message.content}
180
180
 
@@ -197,7 +197,7 @@ You can easily expand this example by adding more components (e.g., text-to-spee
197
197
 
198
198
  #### 📡 Listener Example
199
199
 
200
- ```
200
+ ```yaml
201
201
  listener:
202
202
  type: http-callback
203
203
  port: 8090
@@ -214,7 +214,7 @@ This listener sets up an HTTP callback endpoint at `http://localhost:8090/callba
214
214
 
215
215
  #### 🌐 Gateway Example
216
216
 
217
- ```
217
+ ```yaml
218
218
  gateway:
219
219
  type: http-tunnel
220
220
  driver: ngrok
@@ -233,7 +233,7 @@ This gateway configuration exposes the local listener defined above to the publi
233
233
 
234
234
  #### ✅ Enabling the Web UI
235
235
  To enable the Web UI, simply add the `webui` section under your `controller` in the `model-compose.yml` file:
236
- ```
236
+ ```yaml
237
237
  controller:
238
238
  type: http-server
239
239
  port: 8080
@@ -253,7 +253,7 @@ By default, `model-compose` uses [Gradio](https://www.gradio.app) as the interac
253
253
 
254
254
  Here’s how you can do it:
255
255
 
256
- ```
256
+ ```yaml
257
257
  controller:
258
258
  type: http-server
259
259
  port: 8080
@@ -292,7 +292,7 @@ You can also expose your workflows via the **Model Context Protocol (MCP)** serv
292
292
 
293
293
  #### ✅ Minimal MCP Server Example
294
294
 
295
- ```
295
+ ```yaml
296
296
  controller:
297
297
  type: mcp-server
298
298
  port: 8080
@@ -311,7 +311,7 @@ components:
311
311
  model: gpt-4o
312
312
  messages:
313
313
  - role: user
314
- content: "Write an inspiring quote."
314
+ content: Write an inspiring quote.
315
315
  output:
316
316
  quote: ${response.choices[0].message.content}
317
317
 
@@ -326,7 +326,7 @@ This configuration launches the controller as an **MCP server**, which listens o
326
326
 
327
327
  Once running, you can invoke workflows remotely using a standard MCP request:
328
328
 
329
- ```
329
+ ```json
330
330
  {
331
331
  "jsonrpc": "2.0",
332
332
  "id": 1,
@@ -349,7 +349,7 @@ You can run the workflow controller inside a Docker container by specifying the
349
349
 
350
350
  #### ✅ Minimal Docker Runtime Example
351
351
 
352
- ```
352
+ ```yaml
353
353
  controller:
354
354
  type: http-server
355
355
  port: 8080
@@ -361,7 +361,7 @@ This configuration will launch the controller inside a lightweight Docker contai
361
361
  #### ⚙️ Advanced Docker Runtime Options
362
362
  You can fully configure the Docker runtime by using an object under the `runtime` key:
363
363
 
364
- ```
364
+ ```yaml
365
365
  controller:
366
366
  type: http-server
367
367
  port: 8080
@@ -373,11 +373,11 @@ controller:
373
373
  - ./models:/models
374
374
  - ./cache:/cache
375
375
  ports:
376
- - "5000:8080"
377
- - "5001:8081"
376
+ - 5000:8080
377
+ - 5001:8081
378
378
  env:
379
379
  MODEL_STORAGE_PATH: /models
380
- command: [ "python", "-m", "mindor.cli.compose", "up" ]
380
+ command: [python, -m, mindor.cli.compose, up]
381
381
  ...
382
382
  ```
383
383
 
@@ -128,7 +128,7 @@ By default, `model-compose` automatically looks for a file named `model-compose.
128
128
 
129
129
  #### 🧪 Minimal Example (with Components and Workflows)
130
130
 
131
- ```
131
+ ```yaml
132
132
  controller:
133
133
  type: http-server
134
134
  port: 8080
@@ -149,7 +149,7 @@ components:
149
149
  model: gpt-4o
150
150
  messages:
151
151
  - role: user
152
- content: "Write an inspiring quote."
152
+ content: Write an inspiring quote.
153
153
  output:
154
154
  quote: ${response.choices[0].message.content}
155
155
 
@@ -172,7 +172,7 @@ You can easily expand this example by adding more components (e.g., text-to-spee
172
172
 
173
173
  #### 📡 Listener Example
174
174
 
175
- ```
175
+ ```yaml
176
176
  listener:
177
177
  type: http-callback
178
178
  port: 8090
@@ -189,7 +189,7 @@ This listener sets up an HTTP callback endpoint at `http://localhost:8090/callba
189
189
 
190
190
  #### 🌐 Gateway Example
191
191
 
192
- ```
192
+ ```yaml
193
193
  gateway:
194
194
  type: http-tunnel
195
195
  driver: ngrok
@@ -208,7 +208,7 @@ This gateway configuration exposes the local listener defined above to the publi
208
208
 
209
209
  #### ✅ Enabling the Web UI
210
210
  To enable the Web UI, simply add the `webui` section under your `controller` in the `model-compose.yml` file:
211
- ```
211
+ ```yaml
212
212
  controller:
213
213
  type: http-server
214
214
  port: 8080
@@ -228,7 +228,7 @@ By default, `model-compose` uses [Gradio](https://www.gradio.app) as the interac
228
228
 
229
229
  Here’s how you can do it:
230
230
 
231
- ```
231
+ ```yaml
232
232
  controller:
233
233
  type: http-server
234
234
  port: 8080
@@ -267,7 +267,7 @@ You can also expose your workflows via the **Model Context Protocol (MCP)** serv
267
267
 
268
268
  #### ✅ Minimal MCP Server Example
269
269
 
270
- ```
270
+ ```yaml
271
271
  controller:
272
272
  type: mcp-server
273
273
  port: 8080
@@ -286,7 +286,7 @@ components:
286
286
  model: gpt-4o
287
287
  messages:
288
288
  - role: user
289
- content: "Write an inspiring quote."
289
+ content: Write an inspiring quote.
290
290
  output:
291
291
  quote: ${response.choices[0].message.content}
292
292
 
@@ -301,7 +301,7 @@ This configuration launches the controller as an **MCP server**, which listens o
301
301
 
302
302
  Once running, you can invoke workflows remotely using a standard MCP request:
303
303
 
304
- ```
304
+ ```json
305
305
  {
306
306
  "jsonrpc": "2.0",
307
307
  "id": 1,
@@ -324,7 +324,7 @@ You can run the workflow controller inside a Docker container by specifying the
324
324
 
325
325
  #### ✅ Minimal Docker Runtime Example
326
326
 
327
- ```
327
+ ```yaml
328
328
  controller:
329
329
  type: http-server
330
330
  port: 8080
@@ -336,7 +336,7 @@ This configuration will launch the controller inside a lightweight Docker contai
336
336
  #### ⚙️ Advanced Docker Runtime Options
337
337
  You can fully configure the Docker runtime by using an object under the `runtime` key:
338
338
 
339
- ```
339
+ ```yaml
340
340
  controller:
341
341
  type: http-server
342
342
  port: 8080
@@ -348,11 +348,11 @@ controller:
348
348
  - ./models:/models
349
349
  - ./cache:/cache
350
350
  ports:
351
- - "5000:8080"
352
- - "5001:8081"
351
+ - 5000:8080
352
+ - 5001:8081
353
353
  env:
354
354
  MODEL_STORAGE_PATH: /models
355
- command: [ "python", "-m", "mindor.cli.compose", "up" ]
355
+ command: [python, -m, mindor.cli.compose, up]
356
356
  ...
357
357
  ```
358
358
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "model-compose"
3
- version = "0.3.18"
3
+ version = "0.4.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" }
@@ -13,7 +13,6 @@ class HttpControllerClient(ControllerClient):
13
13
 
14
14
  async def run_workflow(self, workflow_id: Optional[str], input: Any, workflow: WorkflowSchema) -> Any:
15
15
  body = {
16
- "workflow_id": workflow_id,
17
16
  "input": input,
18
17
  "wait_for_completion": True,
19
18
  "output_only": True
@@ -28,7 +27,7 @@ class HttpControllerClient(ControllerClient):
28
27
  "Content-Type": "multipart/form-data"
29
28
  }
30
29
 
31
- return await self.client.request("/workflows", "POST", None, body, headers)
30
+ return await self.client.request(f"/workflows/{workflow_id}/runs", "POST", None, body, headers)
32
31
 
33
32
  async def close(self) -> None:
34
33
  await self.client.close()
@@ -19,8 +19,7 @@ from fastapi.responses import Response, JSONResponse, StreamingResponse
19
19
  from starlette.background import BackgroundTask
20
20
  import uvicorn
21
21
 
22
- class WorkflowTaskRequestBody(BaseModel):
23
- workflow_id: Optional[str] = None
22
+ class WorkflowRunRequestBody(BaseModel):
24
23
  input: Optional[Any] = None
25
24
  wait_for_completion: bool = True
26
25
  output_only: bool = False
@@ -74,6 +73,7 @@ class WorkflowSchemaResult(BaseModel):
74
73
  description: Optional[str] = None
75
74
  input: List[WorkflowVariableResult]
76
75
  output: List[Union[WorkflowVariableResult, WorkflowVariableGroupResult]]
76
+ default: bool = False
77
77
 
78
78
  @classmethod
79
79
  def from_instance(cls, instance: WorkflowSchema) -> Self:
@@ -83,10 +83,11 @@ class WorkflowSchemaResult(BaseModel):
83
83
  description=instance.description,
84
84
  input=[ cls._to_variable_result(variable) for variable in instance.input ],
85
85
  output=[ cls._to_variable_result(variable) for variable in instance.output ],
86
+ default=instance.default
86
87
  )
87
-
88
+
88
89
  @classmethod
89
- def _to_variable_result(cls, variable: Union[WorkflowVariableConfig, WorkflowVariableGroupConfig ]) -> Union[WorkflowVariableResult, WorkflowVariableGroupResult]:
90
+ def _to_variable_result(cls, variable: Union[WorkflowVariableConfig, WorkflowVariableGroupConfig]) -> Union[WorkflowVariableResult, WorkflowVariableGroupResult]:
90
91
  if isinstance(variable, WorkflowVariableGroupConfig):
91
92
  return WorkflowVariableGroupResult.from_instance(variable)
92
93
  return WorkflowVariableResult.from_instance(variable)
@@ -123,23 +124,34 @@ class HttpServerController(ControllerService):
123
124
  )
124
125
 
125
126
  def _configure_routes(self) -> None:
126
- @self.router.post("/workflows")
127
- async def run_workflow(
127
+ @self.router.post("/workflows/runs")
128
+ async def run_default_workflow(
128
129
  request: Request
129
130
  ):
130
- body = await self._parse_workflow_body(request)
131
- state = await self.run_workflow(body.workflow_id, body.input, body.wait_for_completion)
131
+ return await self._handle_workflow_run_request(request, None)
132
132
 
133
- if body.output_only and not body.wait_for_completion:
134
- raise HTTPException(status_code=400, detail="output_only requires wait_for_completion=true.")
135
-
136
- if not body.output_only and isinstance(state.output, (StreamResource, AsyncGeneratorType)):
137
- raise HTTPException(status_code=400, detail="Streaming output is only allowed when output_only=true.")
133
+ @self.router.post("/workflows/{workflow_id}/runs")
134
+ async def run_workflow(
135
+ request: Request,
136
+ workflow_id: str
137
+ ):
138
+ if workflow_id not in self.workflow_schemas:
139
+ raise HTTPException(status_code=404, detail="Workflow not found.")
138
140
 
139
- if body.output_only:
140
- return self._render_task_output(state)
141
-
142
- return self._render_task_state(state)
141
+ return await self._handle_workflow_run_request(request, workflow_id)
142
+
143
+ @self.router.get("/workflows/schemas")
144
+ async def get_workflow_schemas():
145
+ return self._render_workflow_schemas(self.workflow_schemas)
146
+
147
+ @self.router.get("/workflows/{workflow_id}/schema")
148
+ async def get_workflow_schema(
149
+ workflow_id: str
150
+ ):
151
+ if workflow_id not in self.workflow_schemas:
152
+ raise HTTPException(status_code=404, detail="Workflow not found.")
153
+
154
+ return self._render_workflow_schema(self.workflow_schemas[workflow_id])
143
155
 
144
156
  @self.router.get("/tasks/{task_id}")
145
157
  async def get_task_state(
@@ -151,34 +163,7 @@ class HttpServerController(ControllerService):
151
163
  if not state:
152
164
  raise HTTPException(status_code=404, detail="Task not found.")
153
165
 
154
- if not output_only and isinstance(state.output, (StreamResource, AsyncGeneratorType)):
155
- raise HTTPException(status_code=400, detail="Streaming output is only allowed when output_only=true.")
156
-
157
- if output_only:
158
- return self._render_task_output(state)
159
-
160
- return self._render_task_state(state)
161
-
162
- @self.router.get("/tasks/{task_id}/jobs")
163
- async def get_task_jobs(
164
- task_id: str
165
- ):
166
- return None
167
-
168
- @self.router.get("/workflows")
169
- async def get_workflow_schemas():
170
- return self._render_workflow_schemas(self.workflow_schemas)
171
-
172
- @self.router.get("/workflows/{workflow_id}")
173
- async def get_workflow_schema(
174
- workflow_id: str,
175
- ):
176
- workflow = self.workflow_schemas[workflow_id] if workflow_id in self.workflow_schemas else None
177
-
178
- if not workflow:
179
- raise HTTPException(status_code=404, detail="Workflow not found.")
180
-
181
- return self._render_workflow_schema(workflow)
166
+ return self._render_task_response(state, output_only)
182
167
 
183
168
  async def _serve(self) -> None:
184
169
  self.server = uvicorn.Server(uvicorn.Config(
@@ -196,7 +181,16 @@ class HttpServerController(ControllerService):
196
181
  if self.server:
197
182
  self.server.should_exit = True
198
183
 
199
- async def _parse_workflow_body(self, request: Request) -> WorkflowTaskRequestBody:
184
+ async def _handle_workflow_run_request(self, request: Request, workflow_id: Optional[str]) -> Response:
185
+ body = await self._parse_workflow_run_body(request)
186
+ state = await self.run_workflow(workflow_id, body.input, body.wait_for_completion)
187
+
188
+ if body.output_only and not body.wait_for_completion:
189
+ raise HTTPException(status_code=400, detail="output_only requires wait_for_completion=true.")
190
+
191
+ return self._render_task_response(state, body.output_only)
192
+
193
+ async def _parse_workflow_run_body(self, request: Request) -> WorkflowRunRequestBody:
200
194
  content_type, _ = parse_options_header(request.headers, "Content-Type")
201
195
 
202
196
  if content_type not in [ "application/json", "multipart/form-data", "application/x-www-form-urlencoded" ]:
@@ -206,10 +200,19 @@ class HttpServerController(ControllerService):
206
200
  raise HTTPException(status_code=400, detail=f"Unsupported Content-Type: {content_type}")
207
201
 
208
202
  try:
209
- return WorkflowTaskRequestBody(**await parse_request_body(request, content_type, nested=True))
203
+ return WorkflowRunRequestBody(**await parse_request_body(request, content_type, nested=True))
210
204
  except Exception as e:
211
205
  raise HTTPException(status_code=400, detail=f"Invalid request body: {e}")
212
206
 
207
+ def _render_task_response(self, state: TaskState, output_only: bool) -> Response:
208
+ if not output_only and isinstance(state.output, (StreamResource, AsyncGeneratorType)):
209
+ raise HTTPException(status_code=400, detail="Streaming output is only allowed when output_only=true.")
210
+
211
+ if output_only:
212
+ return self._render_task_output(state)
213
+
214
+ return self._render_task_state(state)
215
+
213
216
  def _render_task_state(self, state: TaskState) -> Response:
214
217
  return JSONResponse(content=TaskResult.from_instance(state).model_dump(exclude_none=True))
215
218
 
@@ -9,7 +9,9 @@ from mindor.core.utils.image import load_image_from_stream
9
9
  from mindor.core.utils.resolvers import FieldResolver
10
10
  from PIL import Image as PILImage
11
11
  import gradio as gr
12
- import json
12
+ import json, re
13
+
14
+ _variable_name_regex = re.compile(r"^([^[]+)(?:\[(\w+)\])?$")
13
15
 
14
16
  class ComponentGroup:
15
17
  def __init__(self, group: gr.Component, components: List[gr.Component]):
@@ -193,20 +195,39 @@ class GradioWebUIBuilder:
193
195
  flattened = []
194
196
  for variable in variables:
195
197
  if isinstance(variable, WorkflowVariableGroupConfig):
196
- group = output[variable.name] if isinstance(output, dict) and variable.name in output else None if variable.name else output
198
+ group = self._resolve_variable_output(output, variable)
197
199
  for value in group or ():
198
200
  flattened.extend(await self._flatten_output_value(value, variable.variables))
199
201
  else:
200
- value = output[variable.name] if isinstance(output, dict) and variable.name in output else None if variable.name else output
202
+ value = self._resolve_variable_output(output, variable)
201
203
  flattened.append(await self._convert_output_value(value, variable.type, variable.subtype, variable.format, variable.internal))
202
204
  return flattened
203
205
 
206
+ def _resolve_variable_output(self, output: Any, variable: Union[WorkflowVariableConfig, WorkflowVariableGroupConfig]) -> Any:
207
+ if isinstance(output, dict) and variable.name:
208
+ m = re.match(_variable_name_regex, variable.name)
209
+ if not m:
210
+ return None
211
+
212
+ name, index = m.group(1, 2)
213
+ if name not in output:
214
+ return None
215
+
216
+ if isinstance(output[name], list) and index:
217
+ if int(index) < len(output[name]):
218
+ return output[name][int(index)]
219
+ return None
220
+
221
+ return output[name]
222
+
223
+ return None if variable.name else output
224
+
204
225
  async def _convert_output_value(self, value: Any, type: WorkflowVariableType, subtype: Optional[str], format: Optional[WorkflowVariableFormat], internal: bool) -> Any:
205
226
  if format == WorkflowVariableFormat.SSE_JSON:
206
- return await self._resolve_json_field_from_bytes(value, subtype, format)
227
+ return self._resolve_json_field_from_bytes(value, subtype, format)
207
228
 
208
229
  if type in [ WorkflowVariableType.STRING, WorkflowVariableType.TEXT ]:
209
- return await self._convert_value_to_string(value, subtype, format)
230
+ return self._convert_value_to_string(value, subtype, format)
210
231
 
211
232
  if type == WorkflowVariableType.IMAGE:
212
233
  return await self._load_image_from_value(value, subtype, format)
@@ -216,7 +237,7 @@ class GradioWebUIBuilder:
216
237
 
217
238
  return value
218
239
 
219
- async def _convert_value_to_string(self, value: Any, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Optional[str]:
240
+ def _convert_value_to_string(self, value: Any, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Optional[str]:
220
241
  if isinstance(value, (dict, list)):
221
242
  return json.dumps(value)
222
243
 
@@ -228,7 +249,7 @@ class GradioWebUIBuilder:
228
249
 
229
250
  return None
230
251
 
231
- async def _resolve_json_field_from_bytes(self, value: Any, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Optional[Any]:
252
+ def _resolve_json_field_from_bytes(self, value: Any, subtype: Optional[str], format: Optional[WorkflowVariableFormat]) -> Optional[Any]:
232
253
  try:
233
254
  return self.field_resolver.resolve(json.loads(value), subtype)
234
255
  except Exception:
@@ -292,7 +292,8 @@ class WorkflowSchema:
292
292
  title: Optional[str],
293
293
  description: Optional[str],
294
294
  input: List[WorkflowVariableConfig],
295
- output: List[Union[WorkflowVariableConfig, WorkflowVariableGroupConfig]]
295
+ output: List[Union[WorkflowVariableConfig, WorkflowVariableGroupConfig]],
296
+ default: bool
296
297
  ):
297
298
  self.workflow_id: str = workflow_id
298
299
  self.name: Optional[str] = name
@@ -300,6 +301,7 @@ class WorkflowSchema:
300
301
  self.description: Optional[str] = description
301
302
  self.input: List[WorkflowVariableConfig] = input
302
303
  self.output: List[Union[WorkflowVariableConfig, WorkflowVariableGroupConfig]] = output
304
+ self.default: bool = default
303
305
 
304
306
  def create_workflow_schemas(workflows: List[WorkflowConfig], components: List[ComponentConfig]) -> Dict[str, WorkflowSchema]:
305
307
  schema: Dict[str, WorkflowSchema] = {}
@@ -311,7 +313,8 @@ def create_workflow_schemas(workflows: List[WorkflowConfig], components: List[Co
311
313
  title=workflow.title,
312
314
  description=workflow.description,
313
315
  input=WorkflowInputVariableResolver().resolve(workflow, workflows, components),
314
- output=WorkflowOutputVariableResolver().resolve(workflow, workflows, components)
316
+ output=WorkflowOutputVariableResolver().resolve(workflow, workflows, components),
317
+ default=workflow.default
315
318
  )
316
319
 
317
320
  return schema
@@ -16,7 +16,7 @@ class IfConditionOperator(str, Enum):
16
16
  STARTS_WITH = "starts-with"
17
17
  ENDS_WITH = "ends-with"
18
18
  MATCH = "match"
19
-
19
+
20
20
  class IfConditionConfig(BaseModel):
21
21
  operator: IfConditionOperator = Field(default=IfConditionOperator.EQ, description="Condition operator.")
22
22
  input: Optional[Any] = Field(default=None, description="Input to evaluate.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: model-compose
3
- Version: 0.3.18
3
+ Version: 0.4.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
@@ -153,7 +153,7 @@ By default, `model-compose` automatically looks for a file named `model-compose.
153
153
 
154
154
  #### 🧪 Minimal Example (with Components and Workflows)
155
155
 
156
- ```
156
+ ```yaml
157
157
  controller:
158
158
  type: http-server
159
159
  port: 8080
@@ -174,7 +174,7 @@ components:
174
174
  model: gpt-4o
175
175
  messages:
176
176
  - role: user
177
- content: "Write an inspiring quote."
177
+ content: Write an inspiring quote.
178
178
  output:
179
179
  quote: ${response.choices[0].message.content}
180
180
 
@@ -197,7 +197,7 @@ You can easily expand this example by adding more components (e.g., text-to-spee
197
197
 
198
198
  #### 📡 Listener Example
199
199
 
200
- ```
200
+ ```yaml
201
201
  listener:
202
202
  type: http-callback
203
203
  port: 8090
@@ -214,7 +214,7 @@ This listener sets up an HTTP callback endpoint at `http://localhost:8090/callba
214
214
 
215
215
  #### 🌐 Gateway Example
216
216
 
217
- ```
217
+ ```yaml
218
218
  gateway:
219
219
  type: http-tunnel
220
220
  driver: ngrok
@@ -233,7 +233,7 @@ This gateway configuration exposes the local listener defined above to the publi
233
233
 
234
234
  #### ✅ Enabling the Web UI
235
235
  To enable the Web UI, simply add the `webui` section under your `controller` in the `model-compose.yml` file:
236
- ```
236
+ ```yaml
237
237
  controller:
238
238
  type: http-server
239
239
  port: 8080
@@ -253,7 +253,7 @@ By default, `model-compose` uses [Gradio](https://www.gradio.app) as the interac
253
253
 
254
254
  Here’s how you can do it:
255
255
 
256
- ```
256
+ ```yaml
257
257
  controller:
258
258
  type: http-server
259
259
  port: 8080
@@ -292,7 +292,7 @@ You can also expose your workflows via the **Model Context Protocol (MCP)** serv
292
292
 
293
293
  #### ✅ Minimal MCP Server Example
294
294
 
295
- ```
295
+ ```yaml
296
296
  controller:
297
297
  type: mcp-server
298
298
  port: 8080
@@ -311,7 +311,7 @@ components:
311
311
  model: gpt-4o
312
312
  messages:
313
313
  - role: user
314
- content: "Write an inspiring quote."
314
+ content: Write an inspiring quote.
315
315
  output:
316
316
  quote: ${response.choices[0].message.content}
317
317
 
@@ -326,7 +326,7 @@ This configuration launches the controller as an **MCP server**, which listens o
326
326
 
327
327
  Once running, you can invoke workflows remotely using a standard MCP request:
328
328
 
329
- ```
329
+ ```json
330
330
  {
331
331
  "jsonrpc": "2.0",
332
332
  "id": 1,
@@ -349,7 +349,7 @@ You can run the workflow controller inside a Docker container by specifying the
349
349
 
350
350
  #### ✅ Minimal Docker Runtime Example
351
351
 
352
- ```
352
+ ```yaml
353
353
  controller:
354
354
  type: http-server
355
355
  port: 8080
@@ -361,7 +361,7 @@ This configuration will launch the controller inside a lightweight Docker contai
361
361
  #### ⚙️ Advanced Docker Runtime Options
362
362
  You can fully configure the Docker runtime by using an object under the `runtime` key:
363
363
 
364
- ```
364
+ ```yaml
365
365
  controller:
366
366
  type: http-server
367
367
  port: 8080
@@ -373,11 +373,11 @@ controller:
373
373
  - ./models:/models
374
374
  - ./cache:/cache
375
375
  ports:
376
- - "5000:8080"
377
- - "5001:8081"
376
+ - 5000:8080
377
+ - 5001:8081
378
378
  env:
379
379
  MODEL_STORAGE_PATH: /models
380
- command: [ "python", "-m", "mindor.cli.compose", "up" ]
380
+ command: [python, -m, mindor.cli.compose, up]
381
381
  ...
382
382
  ```
383
383
 
File without changes
File without changes