model-compose 0.3.13__tar.gz → 0.3.14__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 (251) hide show
  1. {model_compose-0.3.13 → model_compose-0.3.14}/PKG-INFO +2 -1
  2. {model_compose-0.3.13 → model_compose-0.3.14}/README.md +1 -0
  3. {model_compose-0.3.13 → model_compose-0.3.14}/pyproject.toml +1 -1
  4. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/__init__.py +1 -0
  5. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/image_to_text.py +3 -3
  6. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/summarization.py +3 -3
  7. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/text_classification.py +3 -3
  8. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/text_embedding.py +3 -3
  9. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/text_generation.py +3 -3
  10. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/translation.py +3 -3
  11. model_compose-0.3.14/src/mindor/core/component/services/vector_store/__init__.py +1 -0
  12. model_compose-0.3.14/src/mindor/core/component/services/vector_store/base.py +28 -0
  13. model_compose-0.3.14/src/mindor/core/component/services/vector_store/drivers/__init__.py +2 -0
  14. model_compose-0.3.14/src/mindor/core/component/services/vector_store/drivers/chroma.py +278 -0
  15. model_compose-0.3.14/src/mindor/core/component/services/vector_store/drivers/milvus.py +333 -0
  16. model_compose-0.3.14/src/mindor/core/component/services/vector_store/vector_store.py +37 -0
  17. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/services/http_server.py +1 -1
  18. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/webui/gradio.py +10 -1
  19. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/schema.py +4 -2
  20. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/__init__.py +1 -0
  21. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/common.py +1 -1
  22. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/image_to_text.py +2 -2
  23. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/summarization.py +1 -1
  24. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/text_classification.py +1 -1
  25. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/text_embedding.py +1 -1
  26. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/text_generation.py +1 -1
  27. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/translation.py +1 -1
  28. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/__init__.py +1 -0
  29. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/impl/__init__.py +4 -0
  30. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/impl/chroma.py +28 -0
  31. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/impl/common.py +85 -0
  32. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/impl/faiss.py +26 -0
  33. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/impl/milvus.py +30 -0
  34. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/impl/qdrant.py +26 -0
  35. model_compose-0.3.14/src/mindor/dsl/schema/action/impl/vector_store/vector_store.py +9 -0
  36. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/component.py +1 -0
  37. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/__init__.py +1 -0
  38. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/common.py +0 -2
  39. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/types.py +1 -0
  40. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/__init__.py +1 -0
  41. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/__init__.py +4 -0
  42. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/chroma.py +27 -0
  43. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/common.py +10 -0
  44. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/faiss.py +18 -0
  45. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/milvus.py +32 -0
  46. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/qdrant.py +41 -0
  47. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/impl/types.py +7 -0
  48. model_compose-0.3.14/src/mindor/dsl/schema/component/impl/vector_store/vector_store.py +12 -0
  49. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/delay.py +1 -1
  50. {model_compose-0.3.13 → model_compose-0.3.14}/src/model_compose.egg-info/PKG-INFO +2 -1
  51. {model_compose-0.3.13 → model_compose-0.3.14}/src/model_compose.egg-info/SOURCES.txt +23 -0
  52. {model_compose-0.3.13 → model_compose-0.3.14}/LICENSE +0 -0
  53. {model_compose-0.3.13 → model_compose-0.3.14}/setup.cfg +0 -0
  54. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/__init__.py +0 -0
  55. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/cli/__init__.py +0 -0
  56. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/cli/compose.py +0 -0
  57. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/__init__.py +0 -0
  58. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/__init__.py +0 -0
  59. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/base.py +0 -0
  60. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/component.py +0 -0
  61. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/context.py +0 -0
  62. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/http_client.py +0 -0
  63. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/http_server.py +0 -0
  64. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/mcp_client.py +0 -0
  65. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/mcp_server.py +0 -0
  66. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/__init__.py +0 -0
  67. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/base.py +0 -0
  68. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/model.py +0 -0
  69. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/model/tasks/__init__.py +0 -0
  70. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/shell.py +0 -0
  71. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/text_splitter.py +0 -0
  72. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/component/services/workflow.py +0 -0
  73. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/compose/__init__.py +0 -0
  74. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/compose/compose.py +0 -0
  75. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/compose/manager.py +0 -0
  76. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/__init__.py +0 -0
  77. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/base.py +0 -0
  78. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/controller.py +0 -0
  79. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runner/__init__.py +0 -0
  80. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runner/client.py +0 -0
  81. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runner/http_client.py +0 -0
  82. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runner/mcp_client.py +0 -0
  83. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runner/runner.py +0 -0
  84. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/__init__.py +0 -0
  85. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/docker/__init__.py +0 -0
  86. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/docker/context/Dockerfile +0 -0
  87. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/docker/docker.py +0 -0
  88. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/native/__init__.py +0 -0
  89. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/native/native.py +0 -0
  90. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/runtime/specs.py +0 -0
  91. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/services/__init__.py +0 -0
  92. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/services/mcp_server.py +0 -0
  93. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/webui/__init__.py +0 -0
  94. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/controller/webui/webui.py +0 -0
  95. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/gateway/__init__.py +0 -0
  96. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/gateway/base.py +0 -0
  97. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/gateway/gateway.py +0 -0
  98. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/gateway/services/__init__.py +0 -0
  99. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/gateway/services/http_tunnel.py +0 -0
  100. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/gateway/services/ssh_tunnel.py +0 -0
  101. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/listener/__init__.py +0 -0
  102. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/listener/base.py +0 -0
  103. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/listener/listener.py +0 -0
  104. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/listener/services/__init__.py +0 -0
  105. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/listener/services/http_callback.py +0 -0
  106. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/__init__.py +0 -0
  107. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/base.py +0 -0
  108. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/logger.py +0 -0
  109. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/logging.py +0 -0
  110. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/services/__init__.py +0 -0
  111. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/services/console.py +0 -0
  112. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/logger/services/file.py +0 -0
  113. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/runtime/__init__.py +0 -0
  114. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/runtime/docker/__init__.py +0 -0
  115. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/runtime/docker/docker.py +0 -0
  116. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/runtime/env.py +0 -0
  117. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/services/__init__.py +0 -0
  118. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/services/async_service.py +0 -0
  119. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/__init__.py +0 -0
  120. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/caching.py +0 -0
  121. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/http_client.py +0 -0
  122. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/http_request.py +0 -0
  123. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/http_response.py +0 -0
  124. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/http_status.py +0 -0
  125. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/image.py +0 -0
  126. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/mcp_client.py +0 -0
  127. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/renderers.py +0 -0
  128. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/resolvers.py +0 -0
  129. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/shell.py +0 -0
  130. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/ssh_client.py +0 -0
  131. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/streamer.py +0 -0
  132. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/streaming.py +0 -0
  133. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/time.py +0 -0
  134. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/utils/workqueue.py +0 -0
  135. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/__init__.py +0 -0
  136. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/context.py +0 -0
  137. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/__init__.py +0 -0
  138. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/base.py +0 -0
  139. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/__init__.py +0 -0
  140. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/action.py +0 -0
  141. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/delay.py +0 -0
  142. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/filter.py +0 -0
  143. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/if_.py +0 -0
  144. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/random_router.py +0 -0
  145. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/impl/switch.py +0 -0
  146. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/job/job.py +0 -0
  147. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/core/workflow/workflow.py +0 -0
  148. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/__init__.py +0 -0
  149. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/loader.py +0 -0
  150. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/__init__.py +0 -0
  151. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/__init__.py +0 -0
  152. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/action.py +0 -0
  153. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/common.py +0 -0
  154. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/http_client.py +0 -0
  155. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/http_server.py +0 -0
  156. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
  157. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
  158. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/__init__.py +0 -0
  159. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/impl/__init__.py +0 -0
  160. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/model/model.py +0 -0
  161. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
  162. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/text_splitter.py +0 -0
  163. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/action/impl/workflow.py +0 -0
  164. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/__init__.py +0 -0
  165. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/common.py +0 -0
  166. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/http_client.py +0 -0
  167. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
  168. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
  169. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
  170. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/__init__.py +0 -0
  171. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/__init__.py +0 -0
  172. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/image_to_text.py +0 -0
  173. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/summarization.py +0 -0
  174. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/text_classification.py +0 -0
  175. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/text_embedding.py +0 -0
  176. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/text_generation.py +0 -0
  177. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/translation.py +0 -0
  178. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/impl/types.py +0 -0
  179. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/model/model.py +0 -0
  180. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
  181. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/text_splitter.py +0 -0
  182. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/component/impl/workflow.py +0 -0
  183. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/compose.py +0 -0
  184. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/__init__.py +0 -0
  185. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/controller.py +0 -0
  186. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
  187. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/impl/common.py +0 -0
  188. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/impl/http_server.py +0 -0
  189. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/impl/mcp_server.py +0 -0
  190. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
  191. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/__init__.py +0 -0
  192. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/impl/__init__.py +0 -0
  193. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/impl/common.py +0 -0
  194. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/impl/dynamic.py +0 -0
  195. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/impl/gradio.py +0 -0
  196. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/impl/static.py +0 -0
  197. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/controller/webui/webui.py +0 -0
  198. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
  199. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
  200. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
  201. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/common.py +0 -0
  202. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/http_tunnel/__init__.py +0 -0
  203. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/http_tunnel/http_tunnel.py +0 -0
  204. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/__init__.py +0 -0
  205. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/cloudflare.py +0 -0
  206. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/common.py +0 -0
  207. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/http_tunnel/impl/ngrok.py +0 -0
  208. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
  209. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
  210. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/__init__.py +0 -0
  211. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/__init__.py +0 -0
  212. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/action.py +0 -0
  213. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/common.py +0 -0
  214. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/filter.py +0 -0
  215. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/if_.py +0 -0
  216. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/random_router.py +0 -0
  217. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/switch.py +0 -0
  218. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/impl/types.py +0 -0
  219. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/job/job.py +0 -0
  220. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/listener/__init__.py +0 -0
  221. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
  222. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/listener/impl/common.py +0 -0
  223. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/listener/impl/http_callback.py +0 -0
  224. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
  225. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/listener/listener.py +0 -0
  226. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/__init__.py +0 -0
  227. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/impl/__init__.py +0 -0
  228. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/impl/common.py +0 -0
  229. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/impl/console.py +0 -0
  230. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/impl/file.py +0 -0
  231. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/impl/types.py +0 -0
  232. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/logger/logger.py +0 -0
  233. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
  234. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/impl/__init__.py +0 -0
  235. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/impl/common.py +0 -0
  236. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/impl/docker.py +0 -0
  237. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/impl/native.py +0 -0
  238. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/impl/types.py +0 -0
  239. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/runtime/runtime.py +0 -0
  240. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/transport/__init__.py +0 -0
  241. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/transport/http.py +0 -0
  242. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/transport/ssh.py +0 -0
  243. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/schema/workflow.py +0 -0
  244. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/utils/__init__.py +0 -0
  245. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/utils/annotation.py +0 -0
  246. {model_compose-0.3.13 → model_compose-0.3.14}/src/mindor/dsl/utils/enum.py +0 -0
  247. {model_compose-0.3.13 → model_compose-0.3.14}/src/model_compose.egg-info/dependency_links.txt +0 -0
  248. {model_compose-0.3.13 → model_compose-0.3.14}/src/model_compose.egg-info/entry_points.txt +0 -0
  249. {model_compose-0.3.13 → model_compose-0.3.14}/src/model_compose.egg-info/requires.txt +0 -0
  250. {model_compose-0.3.13 → model_compose-0.3.14}/src/model_compose.egg-info/top_level.txt +0 -0
  251. {model_compose-0.3.13 → model_compose-0.3.14}/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.13
3
+ Version: 0.3.14
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
@@ -45,6 +45,7 @@ Dynamic: license-file
45
45
  - **Multi-Workflow Support**: Define multiple named workflows in one project. Run them by name or set a default for quick execution.
46
46
  - **Modular Components**: Break down logic into reusable components and jobs. Easily plug, swap, and extend them across workflows.
47
47
  - **Flexible I/O Routing**: Connect inputs and outputs between jobs using clean, scoped variables—no glue code needed.
48
+ - **Streaming Mode Support**: Stream real-time outputs from models and APIs, enabling interactive applications and faster feedback loops.
48
49
  - **Run Locally, Serve Remotely**: Execute workflows from the CLI or expose them as HTTP or MCP endpoints with an optional Web UI.
49
50
  - **Docker Deployment**: Build and deploy your workflow controller as a Docker container for consistent and portable execution environments.
50
51
  - **Environment Variable Support**: Easily inject secrets and configuration via `.env` files or environment variables to keep your YAML clean and secure.
@@ -16,6 +16,7 @@
16
16
  - **Multi-Workflow Support**: Define multiple named workflows in one project. Run them by name or set a default for quick execution.
17
17
  - **Modular Components**: Break down logic into reusable components and jobs. Easily plug, swap, and extend them across workflows.
18
18
  - **Flexible I/O Routing**: Connect inputs and outputs between jobs using clean, scoped variables—no glue code needed.
19
+ - **Streaming Mode Support**: Stream real-time outputs from models and APIs, enabling interactive applications and faster feedback loops.
19
20
  - **Run Locally, Serve Remotely**: Execute workflows from the CLI or expose them as HTTP or MCP endpoints with an optional Web UI.
20
21
  - **Docker Deployment**: Build and deploy your workflow controller as a Docker container for consistent and portable execution environments.
21
22
  - **Environment Variable Support**: Easily inject secrets and configuration via `.env` files or environment variables to keep your YAML clean and secure.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "model-compose"
3
- version = "0.3.13"
3
+ version = "0.3.14"
4
4
  description = "model-compose: Declarative AI Model and Workflow Orchestrator"
5
5
  authors = [
6
6
  { name = "Hanyeol Cho", email = "hanyeol.cho@gmail.com" }
@@ -3,6 +3,7 @@ from .http_client import *
3
3
  from .mcp_server import *
4
4
  from .mcp_client import *
5
5
  from .model import *
6
+ from .vector_store import *
6
7
  from .workflow import *
7
8
  from .shell import *
8
9
  from .text_splitter import *
@@ -28,7 +28,7 @@ class ImageToTextTaskAction:
28
28
  batch_size = await context.render_variable(self.config.params.batch_size)
29
29
  stream = await context.render_variable(self.config.stream)
30
30
 
31
- is_single_input: bool = True if not isinstance(images, list) else False
31
+ is_single_input: bool = bool(not isinstance(images, list))
32
32
  images: List[PILImage.Image] = [ image ] if is_single_input else image
33
33
  prompts: Optional[List[str]] = [ prompt ] if is_single_input else prompt
34
34
  results = []
@@ -61,13 +61,13 @@ class ImageToTextTaskAction:
61
61
  _generate()
62
62
 
63
63
  if stream:
64
- async def _stream_generator():
64
+ async def _stream_output_generator():
65
65
  async for chunk in AsyncStreamer(streamer, loop):
66
66
  if chunk:
67
67
  context.register_source("result[]", chunk)
68
68
  yield (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else chunk
69
69
 
70
- return _stream_generator()
70
+ return _stream_output_generator()
71
71
  else:
72
72
  result = results[0] if is_single_input else results
73
73
  context.register_source("result", result)
@@ -32,7 +32,7 @@ class SummarizationTaskAction:
32
32
  batch_size = await context.render_variable(self.config.params.batch_size)
33
33
  stream = await context.render_variable(self.config.stream)
34
34
 
35
- is_single_input: bool = True if not isinstance(text, list) else False
35
+ is_single_input: bool = bool(not isinstance(text, list))
36
36
  texts: List[str] = [ text ] if is_single_input else text
37
37
  results = []
38
38
 
@@ -73,13 +73,13 @@ class SummarizationTaskAction:
73
73
  _generate()
74
74
 
75
75
  if stream:
76
- async def _stream_generator():
76
+ async def _stream_output_generator():
77
77
  async for chunk in AsyncStreamer(streamer, loop):
78
78
  if chunk:
79
79
  context.register_source("result[]", chunk)
80
80
  yield (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else chunk
81
81
 
82
- return _stream_generator()
82
+ return _stream_output_generator()
83
83
  else:
84
84
  result = results[0] if is_single_input else results
85
85
  context.register_source("result", result)
@@ -24,7 +24,7 @@ class TextClassificationTaskAction:
24
24
  batch_size = await context.render_variable(self.config.params.batch_size)
25
25
  stream = await context.render_variable(self.config.stream)
26
26
 
27
- is_single_input: bool = True if not isinstance(text, list) else False
27
+ is_single_input: bool = bool(not isinstance(text, list))
28
28
  is_output_array_mode: bool = context.contains_variable_reference("result[]", self.config.output)
29
29
  texts: List[str] = [ text ] if is_single_input else text
30
30
  results = []
@@ -64,7 +64,7 @@ class TextClassificationTaskAction:
64
64
  yield predictions
65
65
 
66
66
  if stream:
67
- async def _stream_generator():
67
+ async def _stream_output_generator():
68
68
  async for predictions in _predict():
69
69
  if not is_output_array_mode:
70
70
  for prediction in predictions:
@@ -74,7 +74,7 @@ class TextClassificationTaskAction:
74
74
  for prediction in predictions:
75
75
  yield prediction
76
76
 
77
- return _stream_generator()
77
+ return _stream_output_generator()
78
78
  else:
79
79
  async for predictions in _predict():
80
80
  results.extend(predictions)
@@ -25,7 +25,7 @@ class TextEmbeddingTaskAction:
25
25
  batch_size = await context.render_variable(self.config.params.batch_size)
26
26
  stream = await context.render_variable(self.config.stream)
27
27
 
28
- is_single_input: bool = True if not isinstance(text, list) else False
28
+ is_single_input: bool = bool(not isinstance(text, list))
29
29
  is_output_array_mode: bool = context.contains_variable_reference("result[]", self.config.output)
30
30
  texts: List[str] = [ text ] if is_single_input else text
31
31
  results = []
@@ -59,7 +59,7 @@ class TextEmbeddingTaskAction:
59
59
  yield embeddings
60
60
 
61
61
  if stream:
62
- async def _stream_generator():
62
+ async def _stream_output_generator():
63
63
  async for embeddings in _embed():
64
64
  if not is_output_array_mode:
65
65
  for embedding in embeddings:
@@ -69,7 +69,7 @@ class TextEmbeddingTaskAction:
69
69
  for embedding in embeddings:
70
70
  yield embedding
71
71
 
72
- return _stream_generator()
72
+ return _stream_output_generator()
73
73
  else:
74
74
  async for embeddings in _embed():
75
75
  results.extend(embeddings)
@@ -28,7 +28,7 @@ class TextGenerationTaskAction:
28
28
  batch_size = await context.render_variable(self.config.params.batch_size)
29
29
  stream = await context.render_variable(self.config.stream)
30
30
 
31
- is_single_input: bool = True if not isinstance(prompt, list) else False
31
+ is_single_input: bool = bool(not isinstance(prompt, list))
32
32
  prompts: List[str] = [ prompt ] if is_single_input else prompt
33
33
  results = []
34
34
 
@@ -65,13 +65,13 @@ class TextGenerationTaskAction:
65
65
  _generate()
66
66
 
67
67
  if stream:
68
- async def _stream_generator():
68
+ async def _stream_output_generator():
69
69
  async for chunk in AsyncStreamer(streamer, loop):
70
70
  if chunk:
71
71
  context.register_source("result[]", chunk)
72
72
  yield (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else chunk
73
73
 
74
- return _stream_generator()
74
+ return _stream_output_generator()
75
75
  else:
76
76
  result = results[0] if is_single_input else results
77
77
  context.register_source("result", result)
@@ -32,7 +32,7 @@ class TranslationTaskAction:
32
32
  batch_size = await context.render_variable(self.config.params.batch_size)
33
33
  stream = await context.render_variable(self.config.stream)
34
34
 
35
- is_single_input: bool = True if not isinstance(text, list) else False
35
+ is_single_input: bool = bool(not isinstance(text, list))
36
36
  texts: List[str] = [ text ] if is_single_input else text
37
37
  results = []
38
38
 
@@ -73,13 +73,13 @@ class TranslationTaskAction:
73
73
  _generate()
74
74
 
75
75
  if stream:
76
- async def _stream_generator():
76
+ async def _stream_output_generator():
77
77
  async for chunk in AsyncStreamer(streamer, loop):
78
78
  if chunk:
79
79
  context.register_source("result[]", chunk)
80
80
  yield (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else chunk
81
81
 
82
- return _stream_generator()
82
+ return _stream_output_generator()
83
83
  else:
84
84
  result = results[0] if is_single_input else results
85
85
  context.register_source("result", result)
@@ -0,0 +1 @@
1
+ from .vector_store import *
@@ -0,0 +1,28 @@
1
+ from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Callable, Any
2
+ from abc import ABC, abstractmethod
3
+ from mindor.dsl.schema.component import VectorStoreComponentConfig, VectorStoreDriver
4
+ from mindor.dsl.schema.action import VectorStoreActionConfig
5
+ from mindor.core.services import AsyncService
6
+ from ...context import ComponentActionContext
7
+
8
+ class VectorStoreService(AsyncService):
9
+ def __init__(self, id: str, config: VectorStoreComponentConfig, daemon: bool):
10
+ super().__init__(daemon)
11
+
12
+ self.id: str = id
13
+ self.config: VectorStoreComponentConfig = config
14
+
15
+ async def run(self, action: VectorStoreActionConfig, context: ComponentActionContext) -> Any:
16
+ return await self._run(action, context)
17
+
18
+ @abstractmethod
19
+ async def _run(self, action: VectorStoreActionConfig, context: ComponentActionContext) -> Any:
20
+ pass
21
+
22
+ def register_vector_store_service(driver: VectorStoreDriver):
23
+ def decorator(cls: Type[VectorStoreService]) -> Type[VectorStoreService]:
24
+ VectorStoreServiceRegistry[driver] = cls
25
+ return cls
26
+ return decorator
27
+
28
+ VectorStoreServiceRegistry: Dict[VectorStoreDriver, Type[VectorStoreService]] = {}
@@ -0,0 +1,2 @@
1
+ from .milvus import *
2
+ from .chroma import *
@@ -0,0 +1,278 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Callable, Any
4
+ from typing import TYPE_CHECKING
5
+ from mindor.dsl.schema.component import VectorStoreComponentConfig
6
+ from mindor.dsl.schema.action import VectorStoreActionConfig, ChromaVectorStoreActionConfig, VectorStoreActionMethod, VectorStoreFilterCondition, VectorStoreFilterOperator
7
+ from mindor.core.utils.streamer import AsyncStreamer
8
+ from mindor.core.logger import logging
9
+ from ..base import VectorStoreService, VectorStoreDriver, register_vector_store_service
10
+ from ..base import ComponentActionContext
11
+ import ulid
12
+
13
+ if TYPE_CHECKING:
14
+ from chromadb.api import ClientAPI as ChromaClient
15
+ from chromadb.api import Collection
16
+
17
+ class ChromaWhereSpecBuilder:
18
+ def build(self, filter: Any) -> Optional[Dict[str, Any]]:
19
+ spec: Dict[str, Any] = self._build_where_spec(filter)
20
+
21
+ if not spec:
22
+ return None
23
+
24
+ return spec
25
+
26
+ def _build_where_spec(self, filter: Any) -> Dict[str, Any]:
27
+ spec: Dict[str, Any] = {}
28
+
29
+ if isinstance(filter, (list, tuple, set)):
30
+ for item in filter:
31
+ spec.update(self._build_where_spec(item))
32
+ return spec
33
+
34
+ if isinstance(filter, dict):
35
+ for field, value in filter.items():
36
+ spec.update({field: { "$eq": value }})
37
+ return spec
38
+
39
+ if isinstance(filter, VectorStoreFilterCondition):
40
+ spec.update(self._build_condition_spec(filter))
41
+ return spec
42
+
43
+ return {}
44
+
45
+ def _build_condition_spec(self, condition: VectorStoreFilterCondition) -> Optional[Dict[str, Dict[str, Any]]]:
46
+ operator_map = {
47
+ VectorStoreFilterOperator.EQ: "$eq",
48
+ VectorStoreFilterOperator.NEQ: "$ne",
49
+ VectorStoreFilterOperator.GT: "$gt",
50
+ VectorStoreFilterOperator.GTE: "$gte",
51
+ VectorStoreFilterOperator.LT: "$lt",
52
+ VectorStoreFilterOperator.LTE: "$lte",
53
+ VectorStoreFilterOperator.IN: "$in",
54
+ VectorStoreFilterOperator.NOT_IN: "$nin",
55
+ }
56
+
57
+ operator = operator_map.get(condition.operator)
58
+
59
+ if not operator:
60
+ return None
61
+
62
+ return { condition.field: { operator: condition.value } }
63
+
64
+ class ChromaVectorStoreAction:
65
+ def __init__(self, config: ChromaVectorStoreActionConfig):
66
+ self.config: ChromaVectorStoreActionConfig = config
67
+
68
+ async def run(self, context: ComponentActionContext, client: ChromaClient) -> Any:
69
+ result = await self._dispatch(context, client)
70
+ context.register_source("result", result)
71
+
72
+ return (await context.render_variable(self.config.output, ignore_files=True)) if self.config.output else result
73
+
74
+ async def _dispatch(self, context: ComponentActionContext, client: ChromaClient) -> Dict[str, Any]:
75
+ if self.config.method == VectorStoreActionMethod.INSERT:
76
+ return await self._insert(context, client)
77
+
78
+ if self.config.method == VectorStoreActionMethod.UPDATE:
79
+ return await self._update(context, client)
80
+
81
+ if self.config.method == VectorStoreActionMethod.SEARCH:
82
+ return await self._search(context, client)
83
+
84
+ if self.config.method == VectorStoreActionMethod.DELETE:
85
+ return await self._delete(context, client)
86
+
87
+ raise ValueError(f"Unsupported vector action method: {self.config.method}")
88
+
89
+ async def _insert(self, context: ComponentActionContext, client: ChromaClient) -> Dict[str, Any]:
90
+ collection_name = await context.render_variable(self.config.collection)
91
+ vector = await context.render_variable(self.config.vector)
92
+ vector_id = await context.render_variable(self.config.vector_id)
93
+ document = await context.render_variable(self.config.document)
94
+ metadata = await context.render_variable(self.config.metadata)
95
+ batch_size = await context.render_variable(self.config.batch_size)
96
+
97
+ is_single_input: bool = bool(not (isinstance(vector, list) and vector and isinstance(vector[0], (list, tuple))))
98
+ vectors: List[List[float]] = [ vector ] if is_single_input else vector
99
+ vector_ids: Optional[List[Union[int, str]]] = [ vector_id ] if is_single_input and vector_id else vector_id
100
+ metadatas: Optional[List[Dict[str, Any]]] = [ metadata ] if is_single_input and metadata else metadata
101
+ documents: Optional[List[str]] = [ document ] if is_single_input and document else document
102
+ batch_size = batch_size if batch_size and batch_size > 0 else len(vectors)
103
+ inserted_ids, affected_rows = [], 0
104
+
105
+ if vector_ids is None:
106
+ vector_ids = [ ulid.ulid() for _ in vectors ]
107
+
108
+ collection: Collection = client.get_or_create_collection(name=collection_name)
109
+ for index in range(0, len(vectors), batch_size):
110
+ batch_vectors = vectors[index:index + batch_size]
111
+ batch_vector_ids = vector_ids[index:index + batch_size] if vector_ids else None
112
+ batch_metadatas = metadatas[index:index + batch_size] if metadatas else None
113
+ batch_documents = documents[index:index + batch_size] if documents else None
114
+
115
+ collection.add(
116
+ ids=batch_vector_ids,
117
+ embeddings=batch_vectors,
118
+ metadatas=batch_metadatas,
119
+ documents=batch_documents
120
+ )
121
+ inserted_ids.extend(batch_vector_ids)
122
+ affected_rows += len(batch_vector_ids)
123
+
124
+ return { "ids": inserted_ids, "affected_rows": affected_rows }
125
+
126
+ async def _update(self, context: ComponentActionContext, client: ChromaClient) -> Dict[str, Any]:
127
+ collection_name = await context.render_variable(self.config.collection)
128
+ vector_id = await context.render_variable(self.config.vector_id)
129
+ vector = await context.render_variable(self.config.vector)
130
+ metadata = await context.render_variable(self.config.metadata)
131
+ document = await context.render_variable(self.config.document)
132
+ batch_size = await context.render_variable(self.config.batch_size)
133
+
134
+ is_single_input: bool = bool(not isinstance(vector_id, list))
135
+ vector_ids: List[Union[int, str]] = [ vector_id ] if is_single_input else vector_id
136
+ vectors: List[List[float]] = [ vector ] if is_single_input and vector else vector
137
+ metadatas: List[Dict[str, Any]] = [ metadata ] if is_single_input and metadata else metadata
138
+ documents: Optional[List[str]] = [ document ] if is_single_input and document else document
139
+ batch_size = batch_size if batch_size and batch_size > 0 else len(vector_ids)
140
+ affected_rows = 0
141
+
142
+ collection: Collection = client.get_or_create_collection(name=collection_name)
143
+ for index in range(0, len(vector_ids), batch_size):
144
+ batch_vector_ids = vector_ids[index:index + batch_size]
145
+ batch_vectors = vectors[index:index + batch_size] if vectors else None
146
+ batch_metadatas = metadatas[index:index + batch_size] if metadatas else None
147
+ batch_documents = documents[index:index + batch_size] if documents else None
148
+
149
+ collection.update(
150
+ ids=batch_vector_ids,
151
+ embeddings=batch_vectors,
152
+ metadatas=batch_metadatas,
153
+ documents=batch_documents
154
+ )
155
+ affected_rows += len(batch_vector_ids)
156
+
157
+ return { "affected_rows": affected_rows }
158
+
159
+ async def _search(self, context: ComponentActionContext, client: ChromaClient) -> List[List[Dict[str, Any]]] | List[Dict[str, Any]]:
160
+ collection_name = await context.render_variable(self.config.collection)
161
+ query = await context.render_variable(self.config.query)
162
+ top_k = await context.render_variable(self.config.top_k)
163
+ filter = await context.render_variable(self.config.filter)
164
+ output_fields = await context.render_variable(self.config.output_fields)
165
+ batch_size = await context.render_variable(self.config.batch_size)
166
+
167
+ is_single_input: bool = bool(not (isinstance(query, list) and query and isinstance(query[0], (list, tuple))))
168
+ queries: List[List[float]] = [ query ] if is_single_input else query
169
+ batch_size = batch_size if batch_size and batch_size > 0 else len(queries)
170
+ results = []
171
+
172
+ collection: Collection = client.get_or_create_collection(name=collection_name)
173
+ where_spec = ChromaWhereSpecBuilder().build(filter)
174
+
175
+ for index in range(0, len(queries), batch_size):
176
+ batch_queries = queries[index:index + batch_size]
177
+
178
+ result = collection.query(
179
+ query_embeddings=batch_queries,
180
+ n_results=int(top_k),
181
+ where=where_spec,
182
+ include=[ "embeddings", "distances", "metadatas", "documents" ]
183
+ )
184
+
185
+ for n in range(len(result["ids"])):
186
+ hits = []
187
+ for index, id in enumerate(result["ids"][n]):
188
+ metadata = result["metadatas"][n][index]
189
+ if output_fields:
190
+ metadata = { key: metadata[key] for key in output_fields if key in metadata }
191
+
192
+ hits.append({
193
+ "id": id,
194
+ "embedding": result["embeddings"][n][index],
195
+ "score": 1 / (1 + result["distances"][n][index]),
196
+ "distance": result["distances"][n][index],
197
+ "metadata": metadata,
198
+ "document": result["documents"][n][index]
199
+ })
200
+ results.append(hits)
201
+
202
+ return results[0] if is_single_input else results
203
+
204
+ async def _delete(self, context: ComponentActionContext, client: ChromaClient) -> Dict[str, Any]:
205
+ collection_name = await context.render_variable(self.config.collection)
206
+ vector_id = await context.render_variable(self.config.vector_id)
207
+ filter = await context.render_variable(self.config.filter)
208
+ batch_size = await context.render_variable(self.config.batch_size)
209
+
210
+ is_single_input: bool = bool(not isinstance(vector_id, list))
211
+ vector_ids: List[Union[int, str]] = [ vector_id ] if is_single_input else vector_id
212
+ batch_size = batch_size if batch_size and batch_size > 0 else len(vector_ids)
213
+ affected_rows = 0
214
+
215
+ collection: Collection = client.get_or_create_collection(name=collection_name)
216
+ where_spec = ChromaWhereSpecBuilder().build(filter)
217
+
218
+ for index in range(0, len(vector_ids), batch_size):
219
+ batch_vector_ids = vector_ids[index:index + batch_size]
220
+
221
+ collection.delete(
222
+ ids=batch_vector_ids,
223
+ where=where_spec
224
+ )
225
+ affected_rows += len(batch_vector_ids)
226
+
227
+ return { "affected_rows": affected_rows }
228
+
229
+ @register_vector_store_service(VectorStoreDriver.CHROMA)
230
+ class ChromaVectorStoreService(VectorStoreService):
231
+ def __init__(self, id: str, config: VectorStoreComponentConfig, daemon: bool):
232
+ super().__init__(id, config, daemon)
233
+
234
+ self.client: Optional[ChromaClient] = None
235
+
236
+ async def _serve(self) -> None:
237
+ self.client = self._create_client()
238
+
239
+ async def _shutdown(self) -> None:
240
+ if self.client:
241
+ self.client = None
242
+
243
+ async def _run(self, action: VectorStoreActionConfig, context: ComponentActionContext) -> Any:
244
+ async def _run():
245
+ return await ChromaVectorStoreAction(action).run(context, self.client)
246
+
247
+ return await self.run_in_thread(_run)
248
+
249
+ def _create_client(self) -> ChromaClient:
250
+ if self.config.mode == "server":
251
+ from chromadb import HttpClient
252
+
253
+ return HttpClient(
254
+ **self._resolve_connection_params(),
255
+ **self._resolve_database_params()
256
+ )
257
+
258
+ if self.config.mode == "local":
259
+ from chromadb import PersistentClient
260
+
261
+ return PersistentClient(
262
+ path=self.config.storage_dir,
263
+ **self._resolve_database_params()
264
+ )
265
+
266
+ raise ValueError(f"Unsupported connection mode: {self.config.mode}")
267
+
268
+ def _resolve_database_params(self) -> Dict[str, Any]:
269
+ return {
270
+ **({ "tenant": self.config.tenant } if self.config.tenant else {}),
271
+ **({ "database": self.config.database } if self.config.database else {})
272
+ }
273
+
274
+ def _resolve_connection_params(self) -> Dict[str, Any]:
275
+ if self.config.endpoint:
276
+ return { "api_base": self.config.endpoint }
277
+
278
+ return { "host": self.config.host, "port": self.config.port, "ssl": bool(self.config.protocol == "https") }