versionhq 1.1.11.7__tar.gz → 1.1.11.8__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 (105) hide show
  1. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.gitignore +2 -0
  2. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/PKG-INFO +1 -1
  3. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/pyproject.toml +1 -1
  4. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/__init__.py +1 -1
  5. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/model.py +36 -77
  6. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/source_docling.py +13 -10
  7. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/llm/llm_vars.py +17 -2
  8. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/llm/model.py +87 -55
  9. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/model.py +1 -1
  10. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq.egg-info/PKG-INFO +1 -1
  11. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/agent/agent_test.py +0 -5
  12. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/llm/llm_test.py +1 -2
  13. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/task/__init__.py +0 -8
  14. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/task/task_test.py +7 -57
  15. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/uv.lock +34 -23
  16. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.github/workflows/publish.yml +0 -0
  17. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.github/workflows/publish_testpypi.yml +0 -0
  18. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.github/workflows/run_tests.yml +0 -0
  19. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.github/workflows/security_check.yml +0 -0
  20. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.pre-commit-config.yaml +0 -0
  21. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/.python-version +0 -0
  22. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/LICENSE +0 -0
  23. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/README.md +0 -0
  24. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/SECURITY.md +0 -0
  25. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/db/preprocess.py +0 -0
  26. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/requirements-dev.txt +0 -0
  27. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/requirements.txt +0 -0
  28. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/runtime.txt +0 -0
  29. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/setup.cfg +0 -0
  30. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/_utils/__init__.py +0 -0
  31. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/_utils/i18n.py +0 -0
  32. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/_utils/logger.py +0 -0
  33. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/_utils/process_config.py +0 -0
  34. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/_utils/usage_metrics.py +0 -0
  35. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/_utils/vars.py +0 -0
  36. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/TEMPLATES/Backstory.py +0 -0
  37. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/TEMPLATES/__init__.py +0 -0
  38. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/__init__.py +0 -0
  39. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/default_agents.py +0 -0
  40. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/parser.py +0 -0
  41. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/agent/rpm_controller.py +0 -0
  42. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/cli/__init__.py +0 -0
  43. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/__init__.py +0 -0
  44. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/customer/__init__.py +0 -0
  45. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/customer/model.py +0 -0
  46. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/product/__init__.py +0 -0
  47. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/product/model.py +0 -0
  48. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/workflow/__init__.py +0 -0
  49. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/clients/workflow/model.py +0 -0
  50. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/__init__.py +0 -0
  51. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/_utils.py +0 -0
  52. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/embedding.py +0 -0
  53. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/model.py +0 -0
  54. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/source.py +0 -0
  55. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/knowledge/storage.py +0 -0
  56. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/llm/__init__.py +0 -0
  57. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/memory/__init__.py +0 -0
  58. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/memory/contextual_memory.py +0 -0
  59. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/memory/model.py +0 -0
  60. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/__init__.py +0 -0
  61. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/base.py +0 -0
  62. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/ltm_sqlite_storage.py +0 -0
  63. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/mem0_storage.py +0 -0
  64. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/rag_storage.py +0 -0
  65. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/task_output_storage.py +0 -0
  66. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/storage/utils.py +0 -0
  67. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/TEMPLATES/Description.py +0 -0
  68. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/__init__.py +0 -0
  69. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/evaluate.py +0 -0
  70. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/formatter.py +0 -0
  71. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/log_handler.py +0 -0
  72. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/task/structured_response.py +0 -0
  73. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/team/__init__.py +0 -0
  74. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/team/model.py +0 -0
  75. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/team/team_planner.py +0 -0
  76. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/__init__.py +0 -0
  77. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/cache_handler.py +0 -0
  78. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/composio_tool.py +0 -0
  79. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/composio_tool_vars.py +0 -0
  80. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/decorator.py +0 -0
  81. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/model.py +0 -0
  82. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq/tool/tool_handler.py +0 -0
  83. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq.egg-info/SOURCES.txt +0 -0
  84. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq.egg-info/dependency_links.txt +0 -0
  85. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq.egg-info/requires.txt +0 -0
  86. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/src/versionhq.egg-info/top_level.txt +0 -0
  87. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/__init__.py +0 -0
  88. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/agent/__init__.py +0 -0
  89. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/cli/__init__.py +0 -0
  90. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/clients/customer_test.py +0 -0
  91. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/clients/product_test.py +0 -0
  92. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/clients/workflow_test.py +0 -0
  93. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/conftest.py +0 -0
  94. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/knowledge/__init__.py +0 -0
  95. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/knowledge/knowledge_test.py +0 -0
  96. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/knowledge/mock_report_compressed.pdf +0 -0
  97. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/llm/__init__.py +0 -0
  98. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/memory/__init__.py +0 -0
  99. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/memory/memory_test.py +0 -0
  100. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/team/Prompts/Demo_test.py +0 -0
  101. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/team/__init__.py +0 -0
  102. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/team/team_test.py +0 -0
  103. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/tool/__init__.py +0 -0
  104. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/tool/composio_test.py +0 -0
  105. {versionhq-1.1.11.7 → versionhq-1.1.11.8}/tests/tool/tool_test.py +0 -0
@@ -3,6 +3,8 @@ destinations.py
3
3
 
4
4
  entity_memory.py
5
5
 
6
+ llm_connection_test.py
7
+
6
8
  train.py
7
9
 
8
10
  dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.1.11.7
3
+ Version: 1.1.11.8
4
4
  Summary: LLM orchestration frameworks for model-agnostic AI agents that handle complex outbound workflows
5
5
  Author-email: Kuriko Iwai <kuriko@versi0n.io>
6
6
  License: MIT License
@@ -15,7 +15,7 @@ exclude = ["test*", "__pycache__", "*.egg-info"]
15
15
 
16
16
  [project]
17
17
  name = "versionhq"
18
- version = "1.1.11.7"
18
+ version = "1.1.11.8"
19
19
  authors = [{ name = "Kuriko Iwai", email = "kuriko@versi0n.io" }]
20
20
  description = "LLM orchestration frameworks for model-agnostic AI agents that handle complex outbound workflows"
21
21
  readme = "README.md"
@@ -17,7 +17,7 @@ from versionhq.tool.model import Tool
17
17
  from versionhq.tool.composio_tool import ComposioHandler
18
18
 
19
19
 
20
- __version__ = "1.1.11.7"
20
+ __version__ = "1.1.11.8"
21
21
  __all__ = [
22
22
  "Agent",
23
23
  "Customer",
@@ -6,10 +6,10 @@ from typing_extensions import Self
6
6
  from dotenv import load_dotenv
7
7
  import litellm
8
8
 
9
- from pydantic import UUID4, BaseModel, Field, InstanceOf, PrivateAttr, model_validator, field_validator, ConfigDict
9
+ from pydantic import UUID4, BaseModel, Field, InstanceOf, PrivateAttr, model_validator, field_validator
10
10
  from pydantic_core import PydanticCustomError
11
11
 
12
- from versionhq.llm.model import LLM, DEFAULT_CONTEXT_WINDOW_SIZE, DEFAULT_MODEL_NAME
12
+ from versionhq.llm.model import LLM, DEFAULT_CONTEXT_WINDOW_SIZE, DEFAULT_MODEL_NAME, PROVIDERS
13
13
  from versionhq.tool.model import Tool, ToolSet
14
14
  from versionhq.knowledge.model import BaseKnowledgeSource, Knowledge
15
15
  from versionhq.memory.contextual_memory import ContextualMemory
@@ -162,90 +162,44 @@ class Agent(BaseModel):
162
162
  @model_validator(mode="after")
163
163
  def set_up_llm(self) -> Self:
164
164
  """
165
- Set up the base model and function calling model (if any) using the LLM class.
166
- Pass the model config params: `llm`, `max_tokens`, `max_execution_time`, `callbacks`,`respect_context_window` to the LLM class.
167
- The base model is selected on the client app, else use the default model.
165
+ Set up `llm` and `function_calling_llm` as valid LLM objects using the given values.
168
166
  """
169
-
170
167
  self.agent_ops_agent_name = self.role
168
+ self.llm = self._set_llm(llm=self.llm)
169
+ function_calling_llm = self.function_calling_llm if self.function_calling_llm else self.llm if self.llm else None
170
+ self.function_calling_llm = self._set_llm(llm=function_calling_llm)
171
+ return self
171
172
 
172
- if isinstance(self.llm, LLM):
173
- llm = self._set_llm_params(self.llm)
174
- self.llm = llm
175
173
 
176
- elif isinstance(self.llm, str) or self.llm is None:
177
- model_name = self.llm if self.llm is not None else DEFAULT_MODEL_NAME
178
- llm = LLM(model=model_name)
179
- updated_llm = self._set_llm_params(llm)
180
- self.llm = updated_llm
174
+ def _set_llm(self, llm: Any | None) -> LLM:
175
+ llm = llm if llm is not None else DEFAULT_MODEL_NAME
181
176
 
182
- else:
183
- if isinstance(self.llm, dict):
184
- model_name = self.llm.pop("model_name", self.llm.pop("deployment_name", str(self.llm)))
185
- llm = LLM(model=model_name if model_name is not None else DEFAULT_MODEL_NAME)
186
- updated_llm = self._set_llm_params(llm, { k: v for k, v in self.llm.items() if v is not None })
187
- self.llm = updated_llm
177
+ match llm:
178
+ case LLM():
179
+ return self._set_llm_params(llm=llm)
188
180
 
189
- else:
181
+ case str():
182
+ llm_obj = LLM(model=llm)
183
+ return self._set_llm_params(llm=llm_obj)
184
+
185
+ case dict():
186
+ model_name = llm.pop("model_name", llm.pop("deployment_name", str(llm)))
187
+ llm_obj = LLM(model=model_name if model_name else DEFAULT_MODEL_NAME)
188
+ return self._set_llm_params(llm_obj, { k: v for k, v in llm.items() if v is not None })
189
+
190
+ case _:
190
191
  model_name = (getattr(self.llm, "model_name") or getattr(self.llm, "deployment_name") or str(self.llm))
191
- llm = LLM(model=model_name)
192
+ llm_obj = LLM(model=model_name)
192
193
  llm_params = {
193
- "max_tokens": (getattr(self.llm, "max_tokens") or self.max_tokens or 3000),
194
- "timeout": getattr(self.llm, "timeout", self.max_execution_time),
195
- "callbacks": getattr(self.llm, "callbacks", None),
196
- "temperature": getattr(self.llm, "temperature", None),
197
- "logprobs": getattr(self.llm, "logprobs", None),
198
- "api_key": getattr(self.llm, "api_key", os.environ.get("LITELLM_API_KEY", None)),
199
- "base_url": getattr(self.llm, "base_url", None),
194
+ "max_tokens": (getattr(llm, "max_tokens") or self.max_tokens or 3000),
195
+ "timeout": getattr(llm, "timeout", self.max_execution_time),
196
+ "callbacks": getattr(llm, "callbacks", None),
197
+ "temperature": getattr(llm, "temperature", None),
198
+ "logprobs": getattr(llm, "logprobs", None),
199
+ "api_key": getattr(llm, "api_key", os.environ.get("LITELLM_API_KEY", None)),
200
+ "base_url": getattr(llm, "base_url", None),
200
201
  }
201
- updated_llm = self._set_llm_params(llm, llm_params)
202
- self.llm = updated_llm
203
-
204
-
205
- """
206
- Set up funcion_calling LLM as well.
207
- Check if the model supports function calling, setup LLM instance accordingly, using the same params with the LLM.
208
- """
209
- if self.function_calling_llm:
210
- if isinstance(self.function_calling_llm, LLM):
211
- if self.function_calling_llm._supports_function_calling() == False:
212
- self.function_calling_llm = LLM(model=DEFAULT_MODEL_NAME)
213
-
214
- updated_llm = self._set_llm_params(self.function_calling_llm)
215
- self.function_calling_llm = updated_llm
216
-
217
- elif isinstance(self.function_calling_llm, str):
218
- llm = LLM(model=self.function_calling_llm)
219
-
220
- if llm._supports_function_calling() == False:
221
- llm = LLM(model=DEFAULT_MODEL_NAME)
222
-
223
- updated_llm = self._set_llm_params(llm)
224
- self.function_calling_llm = updated_llm
225
-
226
- else:
227
- if isinstance(self.function_calling_llm, dict):
228
- model_name = self.function_calling_llm.pop("model_name", self.function_calling_llm.pop("deployment_name", str(self.function_calling_llm)))
229
- llm = LLM(model=model_name)
230
- updated_llm = self._set_llm_params(llm, { k: v for k, v in self.function_calling_llm.items() if v is not None })
231
- self.function_calling_llm = updated_llm
232
-
233
- else:
234
- model_name = (getattr(self.function_calling_llm, "model_name") or getattr(self.function_calling_llm, "deployment_name") or str(self.function_calling_llm))
235
- llm = LLM(model=model_name)
236
- llm_params = {
237
- "max_tokens": (getattr(self.function_calling_llm, "max_tokens") or self.max_tokens or 3000),
238
- "timeout": getattr(self.function_calling_llm, "timeout", self.max_execution_time),
239
- "callbacks": getattr(self.function_calling_llm, "callbacks", None),
240
- "temperature": getattr(self.function_calling_llm, "temperature", None),
241
- "logprobs": getattr(self.function_calling_llm, "logprobs", None),
242
- "api_key": getattr(self.function_calling_llm, "api_key", os.environ.get("LITELLM_API_KEY", None)),
243
- "base_url": getattr(self.function_calling_llm, "base_url", None),
244
- }
245
- updated_llm = self._set_llm_params(llm, llm_params)
246
- self.function_calling_llm = updated_llm
247
-
248
- return self
202
+ return self._set_llm_params(llm=llm_obj, config=llm_params)
249
203
 
250
204
 
251
205
  def _set_llm_params(self, llm: LLM, config: Dict[str, Any] = None) -> LLM:
@@ -257,6 +211,11 @@ class Agent(BaseModel):
257
211
  llm.timeout = self.max_execution_time if llm.timeout is None else llm.timeout
258
212
  llm.max_tokens = self.max_tokens if self.max_tokens else llm.max_tokens
259
213
 
214
+ if llm.provider is None:
215
+ provider_name = llm.model.split("/")[0]
216
+ valid_provider = provider_name if provider_name in PROVIDERS else None
217
+ llm.provider = valid_provider
218
+
260
219
  if self.callbacks:
261
220
  llm.callbacks = self.callbacks
262
221
  llm._set_callbacks(llm.callbacks)
@@ -12,17 +12,11 @@ try:
12
12
  except ImportError:
13
13
  import envoy
14
14
  envoy.run("uv add docling --optional docling")
15
-
16
- from docling.datamodel.base_models import InputFormat
17
- from docling.document_converter import DocumentConverter
18
- from docling.exceptions import ConversionError
19
- from docling_core.transforms.chunker.hierarchical_chunker import HierarchicalChunker
20
- from docling_core.types.doc.document import DoclingDocument
21
15
  DOCLING_AVAILABLE = True
22
16
  except:
23
17
  DOCLING_AVAILABLE = False
24
18
 
25
- from pydantic import Field, InstanceOf
19
+ from pydantic import Field
26
20
 
27
21
  from versionhq.knowledge.source import BaseKnowledgeSource
28
22
  from versionhq.storage.utils import fetch_db_storage_path
@@ -52,11 +46,20 @@ class DoclingSource(BaseKnowledgeSource):
52
46
  ))
53
47
 
54
48
  def __init__(self, *args, **kwargs):
55
- if not DOCLING_AVAILABLE:
56
- raise ImportError("The docling package is required. Please install the package using: $ uv add docling.")
57
- else:
49
+ if DOCLING_AVAILABLE:
50
+ from docling.datamodel.base_models import InputFormat
51
+ from docling.document_converter import DocumentConverter
52
+ from docling.exceptions import ConversionError
53
+ from docling_core.transforms.chunker.hierarchical_chunker import HierarchicalChunker
54
+ from docling_core.types.doc.document import DoclingDocument
55
+
58
56
  super().__init__(*args, **kwargs)
59
57
 
58
+ else:
59
+ raise ImportError("The docling package is required. Please install the package using: $ uv add docling.")
60
+ # else:
61
+ # super().__init__(*args, **kwargs)
62
+
60
63
 
61
64
  def _convert_source_to_docling_documents(self) -> List["DoclingDocument"]:
62
65
  conv_results_iter = self.document_converter.convert_all(self.valid_file_paths)
@@ -7,7 +7,7 @@ PROVIDERS = [
7
7
  "openai",
8
8
  "gemini",
9
9
  "sagemaker",
10
-
10
+ "huggingface", # need api base
11
11
  "anthropic",
12
12
  "ollama",
13
13
  "watson",
@@ -17,6 +17,19 @@ PROVIDERS = [
17
17
  "llama",
18
18
  ]
19
19
 
20
+ ENDPOINT_PROVIDERS = [
21
+ # "openai",
22
+ # "gemini",
23
+ # "sagemaker",
24
+ "huggingface",
25
+ # "anthropic",
26
+ # "ollama",
27
+ # "watson",
28
+ # "bedrock",
29
+ # "azure",
30
+ # "cerebras",
31
+ # "llama",
32
+ ]
20
33
 
21
34
  """
22
35
  List of models available on the framework.
@@ -48,6 +61,9 @@ MODELS = {
48
61
  "claude-3-opus-20240229",
49
62
  "claude-3-haiku-20240307",
50
63
  ],
64
+ "huggingface": [
65
+ "huggingface/qwen/qwen2.5-VL-72B-Instruct",
66
+ ],
51
67
  # "sagemaker": [
52
68
  # "sagemaker/huggingface-text2text-flan-t5-base",
53
69
  # "sagemaker/huggingface-llm-gemma-7b",
@@ -61,7 +77,6 @@ MODELS = {
61
77
  "ollama/llama3.1",
62
78
  "ollama/mixtral",
63
79
  "ollama/mixtral-8x22B-Instruct-v0.1",
64
-
65
80
  ],
66
81
  "deepseek": [
67
82
  "deepseek/deepseek-reasoner",
@@ -10,10 +10,10 @@ from litellm import get_supported_openai_params, JSONSchemaValidationError
10
10
  from contextlib import contextmanager
11
11
  from typing import Any, Dict, List, Optional
12
12
  from typing_extensions import Self
13
- from pydantic import UUID4, BaseModel, Field, PrivateAttr, field_validator, model_validator, create_model, InstanceOf, ConfigDict
13
+ from pydantic import BaseModel, Field, PrivateAttr, field_validator, model_validator, create_model, InstanceOf, ConfigDict
14
14
  from pydantic_core import PydanticCustomError
15
15
 
16
- from versionhq.llm.llm_vars import LLM_CONTEXT_WINDOW_SIZES, MODELS, PARAMS
16
+ from versionhq.llm.llm_vars import LLM_CONTEXT_WINDOW_SIZES, MODELS, PARAMS, PROVIDERS, ENDPOINT_PROVIDERS
17
17
  from versionhq.tool.model import Tool, ToolSet
18
18
  from versionhq._utils.logger import Logger
19
19
 
@@ -22,7 +22,8 @@ load_dotenv(override=True)
22
22
  LITELLM_API_KEY = os.environ.get("LITELLM_API_KEY")
23
23
  LITELLM_API_BASE = os.environ.get("LITELLM_API_BASE")
24
24
  DEFAULT_CONTEXT_WINDOW_SIZE = int(8192 * 0.75)
25
- DEFAULT_MODEL_NAME = os.environ.get("DEFAULT_MODEL_NAME")
25
+ DEFAULT_MODEL_NAME = os.environ.get("DEFAULT_MODEL_NAME", "gpt-4o-mini")
26
+ DEFAULT_MODEL_PROVIDER_NAME = os.environ.get("DEFAULT_MODEL_PROVIDER_NAME", "openai")
26
27
 
27
28
  # proxy_openai_client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"), organization="versionhq", base_url=LITELLM_API_BASE)
28
29
  # openai_client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
@@ -67,10 +68,7 @@ def suppress_warnings():
67
68
 
68
69
  class LLM(BaseModel):
69
70
  """
70
- An LLM class to store params except for response formats which will be given in the task handling process.
71
- Use LiteLLM to connect with the model of choice.
72
- Some optional params are passed by the agent, else follow the default settings of the model provider.
73
- Ref. https://docs.litellm.ai/docs/completion/input
71
+ An LLM class to store params to send to the LLM. Use LiteLLM or custom providers for the endpoint.
74
72
  """
75
73
 
76
74
  _logger: Logger = PrivateAttr(default_factory=lambda: Logger(verbose=True))
@@ -78,10 +76,11 @@ class LLM(BaseModel):
78
76
  _tokens: int = PrivateAttr(default=0) # accumulate total tokens used for the call
79
77
  model_config = ConfigDict(extra="allow")
80
78
 
81
- model: str = Field(default=DEFAULT_MODEL_NAME)
82
- provider: Optional[str] = Field(default=None, description="model provider or custom model provider")
83
- base_url: Optional[str] = Field(default=None, description="api base of the model provider")
84
- api_key: Optional[str] = Field(default=None, description="api key of the model provider")
79
+ model: str = Field(default=None)
80
+ provider: Optional[str] = Field(default=None, description="model provider")
81
+ endpoint_provider: Optional[str] = Field(default=None, description="custom endpoint provider for pass through llm call. must need base_url")
82
+ base_url: Optional[str] = Field(default=None, description="api base url for endpoint provider")
83
+ api_key: Optional[str] = Field(default=None, description="api key to access the model")
85
84
 
86
85
  # optional params
87
86
  timeout: Optional[float | int] = Field(default=None)
@@ -114,54 +113,89 @@ class LLM(BaseModel):
114
113
  litellm.set_verbose = True
115
114
  os.environ['LITELLM_LOG'] = 'DEBUG'
116
115
 
116
+
117
117
  @model_validator(mode="after")
118
- def validate_base_params(self) -> Self:
118
+ def validate_model_providers(self) -> Self:
119
119
  """
120
- 1) Set up a valid model name with the provider name using the MODEL list.
121
- * Assign a default model and provider based on the given information when no model key is found in the MODEL list.
122
-
123
- 2) Set up other base parameters for the model and LiteLLM.
120
+ Validate the given model, provider, interface provider.
124
121
  """
125
122
 
126
- if self.model is None:
127
- self._logger.log(level="error", message="Model name is missing.", color="red")
128
- raise PydanticCustomError("model_missing", "The model name must be provided.", {})
123
+ self._init_model_name = self.model
129
124
 
125
+ if self.model is None and self.provider is None:
126
+ self.model = DEFAULT_MODEL_NAME
127
+ self.provider = DEFAULT_MODEL_PROVIDER_NAME
130
128
 
131
- self._init_model_name = self.model
132
- self.model = None
133
- self._tokens = 0
129
+ elif self.model is None and self.provider:
130
+ if self.provider not in PROVIDERS:
131
+ self._logger.log(level="warning", message=f"Invalid model provider is provided. We will assign a default model.", color="yellow")
132
+ self.model = DEFAULT_MODEL_NAME
133
+ self.provider = DEFAULT_MODEL_PROVIDER_NAME
134
134
 
135
- if self.provider and MODELS.get(self.provider):
136
- provider_model_list = MODELS.get(self.provider)
137
- for item in provider_model_list:
138
- if self.model is None:
139
- if item == self._init_model_name:
140
- self.model = item
141
- elif self._init_model_name in item and self.model is None:
142
- self.model = item
143
- else:
144
- temp_model = provider_model_list[0]
145
- self._logger.log(level="warning", message=f"The provided model: {self._init_model_name} is not in the list. We'll assign a model: {temp_model} from the selected model provider: {self.provider}.", color="yellow")
146
- self.model = temp_model
135
+ else:
136
+ provider_model_list = MODELS.get(self.provider)
137
+ if provider_model_list:
138
+ self.model = provider_model_list[0]
139
+ self.provider = self.provider
140
+ else:
141
+ self._logger.log(level="warning", message=f"This provider has not models to be called. We will assign a default model.", color="yellow")
142
+ self.model = DEFAULT_MODEL_NAME
143
+ self.provider = DEFAULT_MODEL_PROVIDER_NAME
144
+
145
+ elif self.model and self.provider is None:
146
+ model_match = [
147
+ item for item in [
148
+ [val for val in v if val == self.model][0] for k, v in MODELS.items() if [val for val in v if val == self.model]
149
+ ] if item
150
+ ]
151
+ model_partial_match = [
152
+ item for item in [
153
+ [val for val in v if val.find(self.model) != -1][0] for k, v in MODELS.items() if [val for val in v if val.find(self.model) != -1]
154
+ ] if item
155
+ ]
156
+ provider_match = [k for k, v in MODELS.items() if k == self.model]
157
+
158
+ if model_match:
159
+ self.model = model_match[0]
160
+ self.provider = [k for k, v in MODELS.items() if self.model in v][0]
161
+
162
+ elif model_partial_match:
163
+ self.model = model_partial_match[0]
164
+ self.provider = [k for k, v in MODELS.items() if [item for item in v if item.find(self.model) != -1]][0]
165
+
166
+ elif provider_match:
167
+ provider = provider_match[0]
168
+ if self.MODELS.get(provider):
169
+ self.provider = provider
170
+ self.model = self.MODELS.get(provider)[0]
171
+ else:
172
+ self.provider = DEFAULT_MODEL_PROVIDER_NAME
173
+ self.model = DEFAULT_MODEL_NAME
174
+
175
+ else:
176
+ self.model = DEFAULT_MODEL_NAME
177
+ self.provider = DEFAULT_MODEL_PROVIDER_NAME
147
178
 
148
179
  else:
149
- for k, v in MODELS.items():
150
- for item in v:
151
- if self.model is None:
152
- if self._init_model_name == item:
153
- self.model = item
154
- self.provider = k
155
-
156
- elif self.model is None and self._init_model_name in item:
157
- self.model = item
158
- self.provider = k
159
-
160
- if self.model is None:
161
- self._logger.log(level="warning", message=f"The provided model \'{self.model}\' is not in the list. We'll assign a default model.", color="yellow")
180
+ provider_model_list = MODELS.get(self.provider)
181
+ if self.model not in provider_model_list:
182
+ self._logger.log(level="warning", message=f"The provided model: {self._init_model_name} is not in the list. We will assign a default model.", color="yellow")
162
183
  self.model = DEFAULT_MODEL_NAME
163
- self.provider = "openai"
184
+ self.provider = DEFAULT_MODEL_PROVIDER_NAME
185
+
186
+ # trigger pass-through custom endpoint.
187
+ if self.provider in ENDPOINT_PROVIDERS:
188
+ self.endpoint_provider = self.provider
189
+
190
+ return self
191
+
164
192
 
193
+ @model_validator(mode="after")
194
+ def validate_model_params(self) -> Self:
195
+ """
196
+ After setting up a valid model, provider, interface provider, add params to the model.
197
+ """
198
+ self._tokens = 0
165
199
 
166
200
  if self.callbacks:
167
201
  self._set_callbacks(self.callbacks)
@@ -173,7 +207,8 @@ class LLM(BaseModel):
173
207
  self.api_key = os.environ.get(api_key_name, None)
174
208
 
175
209
 
176
- base_url_key_name = self.provider.upper() + "_API_BASE" if self.provider else None
210
+ base_url_key_name = self.endpoint_provider.upper() + "_API_BASE" if self.endpoint_provider else None
211
+
177
212
  if base_url_key_name:
178
213
  self.base_url = os.environ.get(base_url_key_name)
179
214
  self.api_base = self.base_url
@@ -184,11 +219,8 @@ class LLM(BaseModel):
184
219
  def _create_valid_params(self, config: Dict[str, Any], provider: str = None) -> Dict[str, Any]:
185
220
  params = dict()
186
221
  valid_keys = list()
187
-
188
- if not provider:
189
- valid_keys = PARAMS.get("litellm") + PARAMS.get("common") + PARAMS.get(self.provider) if self.provider else PARAMS.get("litellm") + PARAMS.get("common")
190
- else:
191
- valid_keys = PARAMS.get("common") + PARAMS.get(self.provider)
222
+ provider = provider if provider else self.provider if self.provider else None
223
+ valid_keys = PARAMS.get("litellm") + PARAMS.get("common") + PARAMS.get(provider) if provider and PARAMS.get(provider) else PARAMS.get("litellm") + PARAMS.get("common")
192
224
 
193
225
  for item in valid_keys:
194
226
  if hasattr(self, item) and getattr(self, item):
@@ -218,7 +250,7 @@ class LLM(BaseModel):
218
250
  self._set_callbacks(self.callbacks) # passed by agent
219
251
 
220
252
  try:
221
- provider = self.provider if self.provider else "openai"
253
+ provider = self.provider if self.provider else DEFAULT_MODEL_PROVIDER_NAME
222
254
  self.response_format = { "type": "json_object" } if tool_res_as_final == True else response_format
223
255
 
224
256
  if not tools:
@@ -639,7 +639,7 @@ Ref. Output image: {output_formats_to_follow}
639
639
 
640
640
  if self.tool_res_as_final == True:
641
641
  tool_output = agent.execute_task(task=self, context=context, task_tools=task_tools)
642
- task_output = TaskOutput(task_id=self.id, tool_output=tool_output, raw=tool_output)
642
+ task_output = TaskOutput(task_id=self.id, tool_output=tool_output, raw=str(tool_output) if tool_output else "")
643
643
 
644
644
  else:
645
645
  raw_output = agent.execute_task(task=self, context=context, task_tools=task_tools)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.1.11.7
3
+ Version: 1.1.11.8
4
4
  Summary: LLM orchestration frameworks for model-agnostic AI agents that handle complex outbound workflows
5
5
  Author-email: Kuriko Iwai <kuriko@versi0n.io>
6
6
  License: MIT License
@@ -312,8 +312,3 @@ def test_agent_with_memory_config():
312
312
  assert agent_2.short_term_memory.memory_provider == "mem0" and agent_2.short_term_memory.storage.memory_type == "stm"
313
313
  assert agent_2.long_term_memory and isinstance(agent_2.long_term_memory.storage, LTMSQLiteStorage)
314
314
  assert agent_2.user_memory and agent_2.user_memory.storage and agent_2.user_memory.storage.memory_type == "user"
315
-
316
-
317
-
318
- if __name__ == "__main__":
319
- test_agent_with_knowledge_sources()
@@ -47,10 +47,9 @@ def test_create_llm_from_invalid_name():
47
47
  def test_create_llm_from_provider():
48
48
  llm = LLM(provider="gemini", callbacks=[dummy_func,])
49
49
 
50
- assert llm._init_model_name == DEFAULT_MODEL_NAME
51
50
  assert llm.model == "gemini/gemini-1.5-flash"
52
51
  assert llm.provider == "gemini"
53
- assert llm.context_window_size == int(LLM_CONTEXT_WINDOW_SIZES.get(llm.model) *0.75) if LLM_CONTEXT_WINDOW_SIZES.get(llm.model) is not None else DEFAULT_CONTEXT_WINDOW_SIZE
52
+ assert llm.context_window_size == int(LLM_CONTEXT_WINDOW_SIZES.get(llm.model) *0.75)
54
53
  assert llm._supports_function_calling() == True
55
54
  assert llm._supports_stop_words() == True
56
55
  assert litellm.callbacks == [dummy_func,]
@@ -43,11 +43,3 @@ demo_response_fields = [
43
43
  ResponseField(title="test6", data_type=list, items=Any, required=False),
44
44
  # ResponseField(title="children", data_type=list, items=type(DemoChild)),
45
45
  ]
46
-
47
-
48
- def create_base_agent(model: str | LLM | Dict[str, Any]) -> Agent:
49
- agent = Agent(role="demo", goal="My amazing goals", llm=model, max_tokens=3000, maxit=1)
50
- return agent
51
-
52
-
53
- base_agent = create_base_agent(model=DEFAULT_MODEL_NAME)
@@ -1,23 +1,24 @@
1
- import os
2
- import pytest
3
1
  import sys
4
2
  import threading
5
3
  from unittest.mock import patch
6
- from typing import Dict, Any, List, Optional, Callable
4
+ from typing import Dict, Any, Callable
7
5
 
8
- from pydantic import BaseModel, Field, InstanceOf
6
+ from pydantic import BaseModel, Field
9
7
 
10
- from versionhq.agent.model import Agent
8
+ from versionhq.agent.model import Agent, DEFAULT_MODEL_NAME
11
9
  from versionhq.agent.rpm_controller import RPMController
12
10
  from versionhq.task.model import Task, ResponseField, TaskOutput, ConditionalTask
13
11
  from versionhq.task.evaluate import Evaluation, EvaluationItem
14
12
  from versionhq.tool.model import Tool, ToolSet
15
13
  from versionhq.tool.decorator import tool
16
- from tests.task import DemoOutcome, demo_response_fields, base_agent
14
+ from tests.task import DemoOutcome, demo_response_fields
17
15
 
18
16
  sys.setrecursionlimit(2097152)
19
17
  threading.stack_size(134217728)
20
18
 
19
+
20
+ base_agent = Agent(role="demo", goal="My amazing goals", llm=DEFAULT_MODEL_NAME, max_tokens=3000, maxit=1)
21
+
21
22
  def test_sync_execute_task_with_pydantic_outcome():
22
23
  task = Task(
23
24
  description="Output random values strictly following the data type defined in the given response format.",
@@ -365,54 +366,3 @@ def test_evaluation():
365
366
  assert [isinstance(item, EvaluationItem) and item.criteria in task.eval_criteria for item in res.evaluation.items]
366
367
  assert res.evaluation.latency and res.evaluation.tokens and res.evaluation.responsible_agent == task_evaluator
367
368
  assert res.evaluation.aggregate_score is not None and res.evaluation.suggestion_summary
368
-
369
-
370
-
371
- def test_gemini_schema():
372
- """
373
- See if response schema and tools (func_calling) works.
374
- """
375
- from tests.task import DemoOutcome
376
- agent = Agent(role="demo", goal="demo", llm="gemini/gemini-1.5-pro")
377
- task = Task(
378
- description="return random values strictly following the given response format.",
379
- pydantic_output=DemoOutcome
380
- )
381
- res = task.execute_sync(agent=agent, context="We are running a test.")
382
- assert [
383
- getattr(res.pydantic, k) and type(getattr(res.pydantic, k)) == v for k, v in DemoOutcome.__annotations__.items()
384
- ]
385
-
386
-
387
- def test_gemini_res_fields():
388
- from tests.task import demo_response_fields
389
- agent = Agent(role="demo", goal="demo", llm="gemini/gemini-1.5-pro")
390
- task = Task(
391
- description="return random values strictly following the given response format.",
392
- response_fields=demo_response_fields
393
- )
394
- res = task.execute_sync(agent=agent, context="We are running a test.")
395
- assert [k in item.title for item in demo_response_fields for k, v in res.json_dict.items()]
396
-
397
-
398
- def test_gemini_func():
399
- from tests.task import demo_response_fields
400
- from versionhq.tool.model import Tool
401
-
402
- class DemoTool(Tool):
403
- func: Callable[..., Any] = lambda x: "Gemini"
404
-
405
- agent = Agent(role="demo", goal="demo", llm="gemini/gemini-1.5-pro")
406
- task = Task(
407
- description="Simply execute the given tools.",
408
- tools=[DemoTool,],
409
- tool_res_as_final=True
410
- )
411
- res = task.execute_sync(agent=agent, context="We are running a test.")
412
- assert res.tool_output and res.raw
413
-
414
-
415
- if __name__ == "__main__":
416
- from dotenv import load_dotenv
417
- load_dotenv(override=True)
418
- test_gemini_func()
@@ -225,14 +225,15 @@ wheels = [
225
225
 
226
226
  [[package]]
227
227
  name = "beautifulsoup4"
228
- version = "4.12.3"
228
+ version = "4.13.0"
229
229
  source = { registry = "https://pypi.org/simple" }
230
230
  dependencies = [
231
231
  { name = "soupsieve" },
232
+ { name = "typing-extensions" },
232
233
  ]
233
- sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 }
234
+ sdist = { url = "https://files.pythonhosted.org/packages/4b/d3/6f4047d1de55b7a290ef8d4b4ebf59dcc24742920ebbed0909f823424205/beautifulsoup4-4.13.0.tar.gz", hash = "sha256:b6e5afb3a2b1472c8db751a92eabf7834e5c7099f990c5e4b35f1f16b60bae64", size = 558514 }
234
235
  wheels = [
235
- { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 },
236
+ { url = "https://files.pythonhosted.org/packages/6e/74/d53cf0c527b20fc87351e6fd9d51aac9b5d1e32ec5a3a32b84671806ab40/beautifulsoup4-4.13.0-py3-none-any.whl", hash = "sha256:9c4c3dfa67aba55f6cd03769c441b21e6a369797fd6766e4b4c6b3399aae2735", size = 184993 },
236
237
  ]
237
238
 
238
239
  [[package]]
@@ -693,11 +694,12 @@ wheels = [
693
694
 
694
695
  [[package]]
695
696
  name = "docling-core"
696
- version = "2.16.1"
697
+ version = "2.17.0"
697
698
  source = { registry = "https://pypi.org/simple" }
698
699
  dependencies = [
699
700
  { name = "jsonref" },
700
701
  { name = "jsonschema" },
702
+ { name = "latex2mathml" },
701
703
  { name = "pandas" },
702
704
  { name = "pillow" },
703
705
  { name = "pydantic" },
@@ -706,9 +708,9 @@ dependencies = [
706
708
  { name = "typer" },
707
709
  { name = "typing-extensions" },
708
710
  ]
709
- sdist = { url = "https://files.pythonhosted.org/packages/42/6f/378b16b63c406952d308b62a9c021d7b398b9e687830a0549c30ff00dbd3/docling_core-2.16.1.tar.gz", hash = "sha256:676f51fa5797c91a86ccbc1fdaa020effcde4cc86aa9b094a0d5d775636871ba", size = 73165 }
711
+ sdist = { url = "https://files.pythonhosted.org/packages/0c/b4/144e8f388097ab170519fa5fdccebf4a701ba902016533bf414aa01ebd07/docling_core-2.17.0.tar.gz", hash = "sha256:cfcba8d173730baf244f279369f68e3cb5ddc7680769841afd254b61e432133e", size = 74005 }
710
712
  wheels = [
711
- { url = "https://files.pythonhosted.org/packages/e7/17/1bff657266f8614ca06df1522f16248f31e9628f3779249c08fe2c5545c5/docling_core-2.16.1-py3-none-any.whl", hash = "sha256:d26af2f49e9f1f65ae5dfca972e206860339c1f91adfe427fa67d1cf95cce241", size = 93160 },
713
+ { url = "https://files.pythonhosted.org/packages/da/c4/2700972ce7633ba48613fce9ed2e9c99ee52828cbf37a22f119fc33dee33/docling_core-2.17.0-py3-none-any.whl", hash = "sha256:5c3015e0eed8e939069bdfd566761dc9f39239647893ae42c53d1333dd0a4749", size = 94026 },
712
714
  ]
713
715
 
714
716
  [package.optional-dependencies]
@@ -745,7 +747,7 @@ wheels = [
745
747
 
746
748
  [[package]]
747
749
  name = "docling-parse"
748
- version = "3.1.2"
750
+ version = "3.2.0"
749
751
  source = { registry = "https://pypi.org/simple" }
750
752
  dependencies = [
751
753
  { name = "docling-core" },
@@ -754,23 +756,23 @@ dependencies = [
754
756
  { name = "pywin32", marker = "sys_platform == 'win32'" },
755
757
  { name = "tabulate" },
756
758
  ]
757
- sdist = { url = "https://files.pythonhosted.org/packages/03/79/8a9f325bbf716692afdb6e45e7829a9dffa0f2c16095f344fe3d6a01f9fd/docling_parse-3.1.2.tar.gz", hash = "sha256:f024d4eb82b9ab48eeb19700e63d3ba7c07e5255b239a4a0f7fcd823427a106e", size = 38928649 }
759
+ sdist = { url = "https://files.pythonhosted.org/packages/a0/2e/10ccfba4ac03605ee31d3ef3940a8428c644fb28566aeb90029266ec92f2/docling_parse-3.2.0.tar.gz", hash = "sha256:d45e34860a2f845d1726d87af77e8deff17e0c6fb876707a7cf390492d408c2f", size = 44333140 }
758
760
  wheels = [
759
- { url = "https://files.pythonhosted.org/packages/44/e3/509546d65e2ffea58160f849baf472ea33214c9776a75a97d6566b80630d/docling_parse-3.1.2-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:fd934888c69eb380c4ef4df3e78fcdd7699c151005292eae69f3dacbe39b7c19", size = 22045656 },
760
- { url = "https://files.pythonhosted.org/packages/4b/5f/cb05db0e5195fdd5dfc698a34e62bbc2a6e8f7950fdf038ec4b7dbf16d25/docling_parse-3.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:628f9d296bd5db503c7d5cf5523dff620008d32eeba4fbd245af8b8758eaa7fa", size = 21928237 },
761
- { url = "https://files.pythonhosted.org/packages/61/db/1579b22dce9562773b308ab97133eba3c67b41ae0f7391e7cce764e7450e/docling_parse-3.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3a8f4199a99611a7239f078aa1590acf5695d90eb168e5b1be54c84fc45efd0", size = 22370654 },
762
- { url = "https://files.pythonhosted.org/packages/a2/8b/01e883b76ed4e17b4d9e5b80a6c13db8313848c52c140225b73bf7500793/docling_parse-3.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f634811c547e9cbcef1ac5f027ac855c75fbd89159e6c2b32ee4a83f22d79c73", size = 22437402 },
763
- { url = "https://files.pythonhosted.org/packages/3b/8d/62ddc1253bfab723c367628da49b57ff5a2770ae680ef88f7bd836391799/docling_parse-3.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:8d9bacc45d3ad9d25c49c768029277009948bb9e4a193e9bc4c5a319d9592427", size = 23233109 },
764
- { url = "https://files.pythonhosted.org/packages/be/96/2106f48a9287eb7269e620c2c180a47998d53e6d12349f1ec0ebe8748cd8/docling_parse-3.1.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:8556b21a0e5f725a598b478e53f222032ca661d581dcfc0805617be44c022b41", size = 22046121 },
765
- { url = "https://files.pythonhosted.org/packages/ff/8f/f0e09c067fc10d6a0a99f8ea1b1e5e2b80556eda70b17eae6c830cc37ac7/docling_parse-3.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2026c312982749ea09ee137715f95dbd3939a78792d32e66e91965dc6280db29", size = 21927787 },
766
- { url = "https://files.pythonhosted.org/packages/8b/6c/125a849118059b877d79f60e44f3a05b9ca29b54cfbfcfa2d5dee54df1b1/docling_parse-3.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74780285314eb0847b1779ee2587347c19881d148ff41b90f49ae8bc0685828c", size = 22369668 },
767
- { url = "https://files.pythonhosted.org/packages/55/6a/e2e1cc44d81fdeaede43e09f5731f5406410e424ae13432d80124ca198b5/docling_parse-3.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b47be7156775831036800bdea6c6db97c51685f8f7582924f7bff1b75a63e650", size = 22436780 },
768
- { url = "https://files.pythonhosted.org/packages/d1/93/8ef62ad05c44d1b5ac503b93f4a3c8defc9ccc192fbb799215c9a9c95603/docling_parse-3.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:43077e58e73711198b2f58ea43e58847b93451335b345b587c785867d5ba6a67", size = 23232992 },
769
- { url = "https://files.pythonhosted.org/packages/57/f5/0bac44f538b415928a438f374aa293c4cec2c3c573ab31041fb25f604719/docling_parse-3.1.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:1d4917459410d7275246c29396ef7055af990185e0cd95b8df3c1dcbacc3db5d", size = 22046080 },
770
- { url = "https://files.pythonhosted.org/packages/43/66/4beea48cbd0a0658ab1781966ecb6992acb616937663f7a76d9a75c507f4/docling_parse-3.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f41d5c34b98774d8015eb84295388ccc3cc0ce05f052829e7e09c3ffd46541d2", size = 21927802 },
771
- { url = "https://files.pythonhosted.org/packages/e0/da/3e60f0c85aca39ca3c74b612815af24a53addc1c757caaf421df1826f4d1/docling_parse-3.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12df0b24026b454c1741dd2c4ea6be607e96b9f821778bfeee13b1bb5915a95", size = 22369896 },
772
- { url = "https://files.pythonhosted.org/packages/b1/7e/2c9ac7dba99eb7cf61c4c262842d8e1a2555a9486b5e57199ce82c0f0129/docling_parse-3.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd341164248d20ec71b4711c33052be653f5f0972c81feb7a1c66ecc075a3140", size = 22436773 },
773
- { url = "https://files.pythonhosted.org/packages/54/c9/8b4886a24d33fea92d21c62acaa0093ca8e30e0a7ab9cab439c854340ccf/docling_parse-3.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:c4015a0bcfab6a294ae78e9b789b081d342216b6349a6832c9b6e515603f2481", size = 23232467 },
761
+ { url = "https://files.pythonhosted.org/packages/80/bc/dd5bd1b8c9780c6817f83a438e0891d2eb3975379b9a20ad3bfc524774da/docling_parse-3.2.0-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:f3616a3fb3dacc87307b6794dc81e6aec09f59afbb42f487b0100f39571e7442", size = 22049513 },
762
+ { url = "https://files.pythonhosted.org/packages/0e/6a/e2acbfd2418cd42365c88994388865fb8624aa6ab2e70b7fb72c6a07c2c6/docling_parse-3.2.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:9df9d892d8206cc2a0091bb1e2e3ce6f3ab881342980c53bc7f4bf7c831bf057", size = 21930790 },
763
+ { url = "https://files.pythonhosted.org/packages/4f/83/d5d89c86a15bd9b9724c9414ea6642eb0d4bbfa97bc2580854f0325fba18/docling_parse-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e90e9c2b21e732b3e1af697abb5e7bca9c23a3be8e25a6cc4d92221d526953c", size = 22373807 },
764
+ { url = "https://files.pythonhosted.org/packages/bf/eb/1c122ec31b84d7513dcff725e102f66d54a9a8334cfec261be8b4d21b45f/docling_parse-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71595399283ecacb255cf1768d1840177f7c33aedd58195530505f9aa8cd5a24", size = 22441982 },
765
+ { url = "https://files.pythonhosted.org/packages/ff/af/b1955551315eb540d5d780a3c61bb88bab6353baf3997184fa3e6eba40ec/docling_parse-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f2a7801d6fa843cd3243aab38cd944e2f4ff386fb5e6fb7b27be1dfa69845c7", size = 23234869 },
766
+ { url = "https://files.pythonhosted.org/packages/61/db/ab6f2e0aa5907e3b4e5e464aabe53a53a4371bf1bf44ccea74d9137657be/docling_parse-3.2.0-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:a83458692c607a393b2f5858d47509342274920553775db5c8d0072ad6aaa0fa", size = 22049762 },
767
+ { url = "https://files.pythonhosted.org/packages/65/eb/3301fd3e73877a1816e7394975ff43533b96a60b3542c186755d3d6bd10d/docling_parse-3.2.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2d17bf3dffbc2fb565c5fa8347ae7715fc091f4f94228b4ece4f8ab5c3fb428a", size = 21930638 },
768
+ { url = "https://files.pythonhosted.org/packages/89/f8/7a310ed4c1f1eb590993fcee0b1bb19bb2bc788ba84b9d76f822bde5c9ee/docling_parse-3.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f54881ebcd87384b29f7a6475b308034a9ecba0dfa85dd1d2569ef59e2f37e97", size = 22372609 },
769
+ { url = "https://files.pythonhosted.org/packages/50/54/387fa23ca2b2522b4c0aa48c8c8739d6c18e50def50db45f3f1b8262f840/docling_parse-3.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27de3b28946a615f16e6824bede965f8df5f3b2552e17560415922c79fa8546f", size = 22441245 },
770
+ { url = "https://files.pythonhosted.org/packages/53/01/21ba457089d7e1a4af6618793e609caca1f598d945813636fa36c0ccea6a/docling_parse-3.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:20265d7d51b3f4a3bb03e3de694f395d0403bde92915eb5df32f4d67adf93477", size = 23235159 },
771
+ { url = "https://files.pythonhosted.org/packages/d1/7b/38f318bb73b59e4f74b6ffcc72d886dd4d4eeb192186ba3cfa65412c0116/docling_parse-3.2.0-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:feecbef5b8593dcd9a35ceb06b29feb879515b5b900bcaa5d9be0c7a3a0ca599", size = 22049844 },
772
+ { url = "https://files.pythonhosted.org/packages/34/d1/48aeb30ec761daa39d79d1361ac4e6cf0952c791affa9027926c6b3a8b14/docling_parse-3.2.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6fc65d623e80d8d63f4a6f542408b7f88c0dc8b2842c2523858536d4607d33d5", size = 21930709 },
773
+ { url = "https://files.pythonhosted.org/packages/02/1d/a383ddbd80180e84958669737c5bcdb996791d41f312a2a81c857cd6cd77/docling_parse-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06851f88b5edaa7115871100608b9d68bc804b28434b90e57879e178098aed2", size = 22372245 },
774
+ { url = "https://files.pythonhosted.org/packages/21/84/733eff29384d204f53a3752292e8ed77b0732389f1e7342b92ff47199b7a/docling_parse-3.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2fdb3993f7affc73ce19f1202a2f28f3d8cf1716163d9e978ee9c834312c31", size = 22441879 },
775
+ { url = "https://files.pythonhosted.org/packages/e2/96/14735f503e2d50d61ce35c9889efb1343dc26cbb0b4410fd56fc7725bc4c/docling_parse-3.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:1b9e32989ff58e0bac85d6cffb3a523dd2373d350b26d46e1f8daff0110595fa", size = 23234594 },
774
776
  ]
775
777
 
776
778
  [[package]]
@@ -1616,6 +1618,15 @@ wheels = [
1616
1618
  { url = "https://files.pythonhosted.org/packages/47/3b/02313e378f6328ada43ee43ecc81a398b4f68e207c94770d1ed6aac6cca2/langsmith-0.3.4-py3-none-any.whl", hash = "sha256:f3b818ce31dc3bdf1f797e75bf32a8a7b062a411f146bd4ffdfc2be0b4b03233", size = 333291 },
1617
1619
  ]
1618
1620
 
1621
+ [[package]]
1622
+ name = "latex2mathml"
1623
+ version = "3.77.0"
1624
+ source = { registry = "https://pypi.org/simple" }
1625
+ sdist = { url = "https://files.pythonhosted.org/packages/a3/dc/6630656e3aa7430b61acefcc3d8a9c23110790193cde0eed1c27a31e4187/latex2mathml-3.77.0.tar.gz", hash = "sha256:e2f501d1878f2e489c3f6f12786bef74c62f712d2770f7f3c837eb20a55d0a1e", size = 74064 }
1626
+ wheels = [
1627
+ { url = "https://files.pythonhosted.org/packages/f2/0a/181ed55562ce90179aedf33b09fcd79db31c868a5d480f3cb71a31d19692/latex2mathml-3.77.0-py3-none-any.whl", hash = "sha256:5531e18a2a9eae7c24e257118b6a444cbba253cd27ff3e81f1bd6c41e88e786e", size = 73722 },
1628
+ ]
1629
+
1619
1630
  [[package]]
1620
1631
  name = "lazy-loader"
1621
1632
  version = "0.4"
File without changes
File without changes
File without changes
File without changes
File without changes