versionhq 1.2.1.18__tar.gz → 1.2.1.20__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 (142) hide show
  1. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/PKG-INFO +1 -1
  2. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/pyproject.toml +1 -1
  3. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/__init__.py +1 -1
  4. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/_utils/logger.py +3 -2
  5. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/model.py +23 -13
  6. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent_network/formation.py +4 -1
  7. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/model.py +1 -0
  8. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/mem0_storage.py +6 -7
  9. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/rag_storage.py +18 -20
  10. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq.egg-info/PKG-INFO +1 -1
  11. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/agent/agent_test.py +4 -2
  12. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/formation_test.py +1 -1
  13. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/usecase_test.py +1 -1
  14. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/uv.lock +1 -1
  15. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.env.sample +0 -0
  16. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.github/workflows/deploy_docs.yml +0 -0
  17. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.github/workflows/publish.yml +0 -0
  18. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.github/workflows/publish_testpypi.yml +0 -0
  19. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.github/workflows/run_tests.yml +0 -0
  20. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.github/workflows/security_check.yml +0 -0
  21. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.gitignore +0 -0
  22. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.pre-commit-config.yaml +0 -0
  23. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/.python-version +0 -0
  24. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/LICENSE +0 -0
  25. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/README.md +0 -0
  26. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/SECURITY.md +0 -0
  27. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/db/preprocess.py +0 -0
  28. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/CNAME +0 -0
  29. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/_logos/favicon.ico +0 -0
  30. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/_logos/logo192.png +0 -0
  31. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/agent/config.md +0 -0
  32. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/agent/index.md +0 -0
  33. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/agent/ref.md +0 -0
  34. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/agent/task-handling.md +0 -0
  35. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/agent-network/index.md +0 -0
  36. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/llm/index.md +0 -0
  37. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/task/evaluation.md +0 -0
  38. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/task/index.md +0 -0
  39. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/task/response-field.md +0 -0
  40. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/task/task-output.md +0 -0
  41. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/task-graph/index.md +0 -0
  42. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/core/tool.md +0 -0
  43. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/index.md +0 -0
  44. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/quickstart.md +0 -0
  45. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/stylesheets/main.css +0 -0
  46. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/docs/tags.md +0 -0
  47. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/mkdocs.yml +0 -0
  48. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/requirements-dev.txt +0 -0
  49. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/requirements.txt +0 -0
  50. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/runtime.txt +0 -0
  51. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/setup.cfg +0 -0
  52. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/_utils/__init__.py +0 -0
  53. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/_utils/i18n.py +0 -0
  54. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/_utils/process_config.py +0 -0
  55. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/_utils/usage_metrics.py +0 -0
  56. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/_utils/vars.py +0 -0
  57. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/TEMPLATES/Backstory.py +0 -0
  58. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/TEMPLATES/__init__.py +0 -0
  59. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/__init__.py +0 -0
  60. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/inhouse_agents.py +0 -0
  61. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/parser.py +0 -0
  62. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent/rpm_controller.py +0 -0
  63. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent_network/__init__.py +0 -0
  64. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/agent_network/model.py +0 -0
  65. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/cli/__init__.py +0 -0
  66. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/__init__.py +0 -0
  67. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/customer/__init__.py +0 -0
  68. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/customer/model.py +0 -0
  69. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/product/__init__.py +0 -0
  70. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/product/model.py +0 -0
  71. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/workflow/__init__.py +0 -0
  72. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/clients/workflow/model.py +0 -0
  73. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/__init__.py +0 -0
  74. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/_utils.py +0 -0
  75. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/embedding.py +0 -0
  76. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/source.py +0 -0
  77. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/source_docling.py +0 -0
  78. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/knowledge/storage.py +0 -0
  79. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/llm/__init__.py +0 -0
  80. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/llm/llm_vars.py +0 -0
  81. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/llm/model.py +0 -0
  82. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/memory/__init__.py +0 -0
  83. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/memory/contextual_memory.py +0 -0
  84. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/memory/model.py +0 -0
  85. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/__init__.py +0 -0
  86. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/base.py +0 -0
  87. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/ltm_sqlite_storage.py +0 -0
  88. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/task_output_storage.py +0 -0
  89. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/storage/utils.py +0 -0
  90. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/TEMPLATES/Description.py +0 -0
  91. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/__init__.py +0 -0
  92. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/evaluate.py +0 -0
  93. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/formatter.py +0 -0
  94. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/log_handler.py +0 -0
  95. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/model.py +0 -0
  96. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task/structured_response.py +0 -0
  97. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task_graph/__init__.py +0 -0
  98. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task_graph/colors.py +0 -0
  99. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task_graph/draft.py +0 -0
  100. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/task_graph/model.py +0 -0
  101. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/__init__.py +0 -0
  102. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/cache_handler.py +0 -0
  103. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/composio_tool.py +0 -0
  104. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/composio_tool_vars.py +0 -0
  105. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/decorator.py +0 -0
  106. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/model.py +0 -0
  107. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq/tool/tool_handler.py +0 -0
  108. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq.egg-info/SOURCES.txt +0 -0
  109. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq.egg-info/dependency_links.txt +0 -0
  110. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq.egg-info/requires.txt +0 -0
  111. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/src/versionhq.egg-info/top_level.txt +0 -0
  112. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/__init__.py +0 -0
  113. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/agent/__init__.py +0 -0
  114. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/agent/doc_test.py +0 -0
  115. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/agent_network/Prompts/Demo_test.py +0 -0
  116. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/agent_network/__init__.py +0 -0
  117. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/agent_network/agent_network_test.py +0 -0
  118. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/cli/__init__.py +0 -0
  119. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/clients/customer_test.py +0 -0
  120. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/clients/product_test.py +0 -0
  121. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/clients/workflow_test.py +0 -0
  122. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/conftest.py +0 -0
  123. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/doc_test.py +0 -0
  124. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/knowledge/__init__.py +0 -0
  125. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/knowledge/knowledge_test.py +0 -0
  126. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/knowledge/mock_report_compressed.pdf +0 -0
  127. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/llm/__init__.py +0 -0
  128. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/llm/llm_test.py +0 -0
  129. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/memory/__init__.py +0 -0
  130. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/memory/memory_test.py +0 -0
  131. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task/__init__.py +0 -0
  132. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task/doc_taskoutput_test.py +0 -0
  133. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task/doc_test.py +0 -0
  134. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task/llm_connection_test.py +0 -0
  135. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task/task_test.py +0 -0
  136. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task_graph/__init__.py +0 -0
  137. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task_graph/doc_test.py +0 -0
  138. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/task_graph/task_graph_test.py +0 -0
  139. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/tool/__init__.py +0 -0
  140. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/tool/composio_test.py +0 -0
  141. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/tool/doc_test.py +0 -0
  142. {versionhq-1.2.1.18 → versionhq-1.2.1.20}/tests/tool/tool_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.2.1.18
3
+ Version: 1.2.1.20
4
4
  Summary: An agentic orchestration framework for building agent networks that handle task automation.
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.2.1.18"
18
+ version = "1.2.1.20"
19
19
  authors = [{ name = "Kuriko Iwai", email = "kuriko@versi0n.io" }]
20
20
  description = "An agentic orchestration framework for building agent networks that handle task automation."
21
21
  readme = "README.md"
@@ -31,7 +31,7 @@ from versionhq.agent_network.formation import form_agent_network
31
31
  from versionhq.task_graph.draft import workflow
32
32
 
33
33
 
34
- __version__ = "1.2.1.18"
34
+ __version__ = "1.2.1.20"
35
35
  __all__ = [
36
36
  "Agent",
37
37
 
@@ -44,6 +44,7 @@ class Logger(BaseModel):
44
44
 
45
45
  verbose: bool = Field(default=True)
46
46
  info_file_save: bool = Field(default=False, description="whether to save INFO logs")
47
+ filename: str = Field(default=None)
47
48
  _printer: Printer = PrivateAttr(default_factory=Printer)
48
49
 
49
50
 
@@ -52,7 +53,7 @@ class Logger(BaseModel):
52
53
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
53
54
  self._printer.print(f"\n{timestamp} - versionHQ [{level.upper()}]: {message}", color=color)
54
55
 
55
- self._save(level=level, message=message)
56
+ self._save(level=level, message=message, filename=self.filename)
56
57
 
57
58
 
58
59
  def _save(self, level: str, message: str, filename: str = None):
@@ -74,7 +75,7 @@ class Logger(BaseModel):
74
75
  cwd = Path.cwd()
75
76
  log_file_dir = f"{cwd}/.logs"
76
77
  os.makedirs(log_file_dir, exist_ok=True)
77
- filename = filename if filename else datetime.now().strftime('%H_%M_%S_%d_%m_%Y')
78
+ filename = filename if filename else self.filename if self.filename else datetime.now().strftime('%H_%M_%S_%d_%m_%Y')
78
79
  abs_dir = f"{log_file_dir}/{filename}.log"
79
80
 
80
81
  logging.basicConfig(filename=abs_dir, filemode='w', level=logging_level)
@@ -64,6 +64,7 @@ class Agent(BaseModel):
64
64
  _request_within_rpm_limit: Any = PrivateAttr(default=None)
65
65
  _token_process: TokenProcess = PrivateAttr(default_factory=TokenProcess)
66
66
  _times_executed: int = PrivateAttr(default=0)
67
+ _logger_config: Dict[str, Any] = PrivateAttr(default=dict(verbose=True, info_file_save=True))
67
68
  config: Optional[Dict[str, Any]] = Field(default=None, exclude=True, description="values to add to the Agent class")
68
69
 
69
70
  id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
@@ -172,7 +173,7 @@ class Agent(BaseModel):
172
173
  tool_list.append(item)
173
174
 
174
175
  else:
175
- Logger().log(level="error", message=f"Tool {str(item)} is missing a function.", color="red")
176
+ Logger(**self.loger_config, filename=self.key).log(level="error", message=f"Tool {str(item)} is missing a function.", color="red")
176
177
  raise PydanticCustomError("invalid_tool", f"The tool {str(item)} is missing a function.", {})
177
178
 
178
179
  self.tools = tool_list
@@ -222,7 +223,7 @@ class Agent(BaseModel):
222
223
 
223
224
  if self.knowledge_sources:
224
225
  try:
225
- collection_name = f"{self.role.replace(' ', '_')}"
226
+ collection_name = self.key
226
227
  knowledge_sources = []
227
228
  docling_fp, txt_fp, json_fp, excel_fp, csv_fp, pdf_fp = [], [], [], [], [], []
228
229
  str_cont = ""
@@ -256,7 +257,7 @@ class Agent(BaseModel):
256
257
  self._knowledge = Knowledge(sources=knowledge_sources, embedder_config=self.embedder_config, collection_name=collection_name)
257
258
 
258
259
  except:
259
- Logger().log(level="warning", message="We cannot find the format for the source. Add BaseKnowledgeSource objects instead.", color="yellow")
260
+ Logger(**self._logger_config, filename=self.key).log(level="warning", message="We cannot find the format for the source. Add BaseKnowledgeSource objects instead.", color="yellow")
260
261
 
261
262
  return self
262
263
 
@@ -375,7 +376,7 @@ class Agent(BaseModel):
375
376
  """
376
377
 
377
378
  if not llm and not llm_config:
378
- Logger().log(level="error", message="Missing llm or llm_config values to update", color="red")
379
+ Logger(**self._logger_config, filename=self.key).log(level="error", message="Missing llm or llm_config values to update", color="red")
379
380
  pass
380
381
 
381
382
  self.llm = llm
@@ -423,7 +424,7 @@ class Agent(BaseModel):
423
424
  if self._rpm_controller and self.max_rpm:
424
425
  self._rpm_controller.check_or_wait()
425
426
 
426
- Logger().log(level="info", message=f"Messages sent to the model: {messages}", color="blue")
427
+ Logger(**self._logger_config, filename=self.key).log(level="info", message=f"Messages sent to the model: {messages}", color="blue")
427
428
 
428
429
  if tool_res_as_final:
429
430
  raw_response = self.func_calling_llm.call(messages=messages, tools=tools, tool_res_as_final=True)
@@ -433,11 +434,11 @@ class Agent(BaseModel):
433
434
  task.tokens = self.llm._tokens
434
435
 
435
436
  task_execution_counter += 1
436
- Logger().log(level="info", message=f"Agent response: {raw_response}", color="green")
437
+ Logger(**self._logger_config, filename=self.key).log(level="info", message=f"Agent response: {raw_response}", color="green")
437
438
  return raw_response
438
439
 
439
440
  except Exception as e:
440
- Logger().log(level="error", message=f"An error occured. The agent will retry: {str(e)}", color="red")
441
+ Logger(**self._logger_config, filename=self.key).log(level="error", message=f"An error occured. The agent will retry: {str(e)}", color="red")
441
442
 
442
443
  while not raw_response and task_execution_counter <= self.max_retry_limit:
443
444
  while (not raw_response or raw_response == "" or raw_response is None) and iterations < self.maxit:
@@ -449,11 +450,11 @@ class Agent(BaseModel):
449
450
  iterations += 1
450
451
 
451
452
  task_execution_counter += 1
452
- Logger().log(level="info", message=f"Agent #{task_execution_counter} response: {raw_response}", color="green")
453
+ Logger(**self._logger_config, filename=self.key).log(level="info", message=f"Agent #{task_execution_counter} response: {raw_response}", color="green")
453
454
  return raw_response
454
455
 
455
456
  if not raw_response:
456
- Logger().log(level="error", message="Received None or empty response from the model", color="red")
457
+ Logger(**self._logger_config, filename=self.key).log(level="error", message="Received None or empty response from the model", color="red")
457
458
  raise ValueError("Invalid response from LLM call - None or empty.")
458
459
 
459
460
 
@@ -463,7 +464,7 @@ class Agent(BaseModel):
463
464
  """
464
465
 
465
466
  if not kwargs:
466
- Logger().log(level="error", message="Missing values to update", color="red")
467
+ Logger(**self._logger_config, filename=self.key).log(level="error", message="Missing values to update", color="red")
467
468
  return self
468
469
 
469
470
  for k, v in kwargs.items():
@@ -503,7 +504,7 @@ class Agent(BaseModel):
503
504
  try:
504
505
  setattr(self, k, v)
505
506
  except Exception as e:
506
- Logger().log(level="error", message=f"Failed to update the field: {k} We'll skip it. Error: {str(e)}", color="red")
507
+ Logger(**self._logger_config, filename=self.key).log(level="error", message=f"Failed to update the field: {k} We'll skip it. Error: {str(e)}", color="red")
507
508
  pass
508
509
 
509
510
  return self
@@ -584,11 +585,11 @@ class Agent(BaseModel):
584
585
 
585
586
  except Exception as e:
586
587
  self._times_executed += 1
587
- Logger().log(level="error", message=f"The agent failed to execute the task. Error: {str(e)}", color="red")
588
+ Logger(**self._logger_config, filename=self.key).log(level="error", message=f"The agent failed to execute the task. Error: {str(e)}", color="red")
588
589
  raw_response = self.execute_task(task, context, task_tools)
589
590
 
590
591
  if self._times_executed > self.max_retry_limit:
591
- Logger().log(level="error", message=f"Max retry limit has exceeded.", color="red")
592
+ Logger(**self._logger_config, filename=self.key).log(level="error", message=f"Max retry limit has exceeded.", color="red")
592
593
  raise e
593
594
 
594
595
  if self.max_rpm and self._rpm_controller:
@@ -597,6 +598,15 @@ class Agent(BaseModel):
597
598
  return raw_response
598
599
 
599
600
 
601
+ @property
602
+ def key(self):
603
+ """
604
+ A key to identify an agent. Used in storage, logging, and other recodings.
605
+ """
606
+ sanitized_role = self.role.lower().replace(" ", "-").replace("/", "").replace("{", "").replace("}", "").replace("\n", "")
607
+ return f"{str(self.id)}-{sanitized_role}"
608
+
609
+
600
610
  def __repr__(self):
601
611
  return f"Agent(role={self.role}, goal={self.goal}"
602
612
 
@@ -9,6 +9,9 @@ from versionhq.agent_network.model import AgentNetwork, Member, Formation
9
9
  from versionhq.agent.inhouse_agents import vhq_formation_planner
10
10
  from versionhq._utils import Logger
11
11
 
12
+ import chromadb
13
+ chromadb.api.client.SharedSystemClient.clear_system_cache()
14
+
12
15
 
13
16
  def form_agent_network(
14
17
  task: str,
@@ -85,7 +88,7 @@ def form_agent_network(
85
88
  members = []
86
89
  leader = str(res.pydantic.leader_agent) if res.pydantic else str(res.json_dict["leader_agent"])
87
90
 
88
- created_agents = [Agent(role=item, goal=item) for item in res.pydantic.agent_roles]
91
+ created_agents = [Agent(role=str(item), goal=str(item)) for item in res.pydantic.agent_roles]
89
92
  created_tasks = []
90
93
 
91
94
  if res.pydantic:
@@ -9,6 +9,7 @@ class Knowledge(BaseModel):
9
9
  """
10
10
  Knowlede class for collection of sources and setup for the vector store to query relevant context.
11
11
  """
12
+
12
13
  collection_name: Optional[str] = None
13
14
  sources: List[BaseKnowledgeSource] = Field(default_factory=list)
14
15
  storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
@@ -40,11 +40,11 @@ class Mem0Storage(Storage):
40
40
  self.memory = MemoryClient(api_key=mem0_api_key)
41
41
 
42
42
 
43
- def _sanitize_role(self, role: str) -> str:
44
- """
45
- Sanitizes agent roles to ensure valid directory names.
46
- """
47
- return role.replace("\n", "").replace(" ", "_").replace("/", "_")
43
+ # def _sanitize_role(self, role: str) -> str:
44
+ # """
45
+ # Sanitizes agent roles to ensure valid directory names.
46
+ # """
47
+ # return role.replace("\n", "").replace(" ", "_").replace("/", "_")
48
48
 
49
49
 
50
50
  def save(self, value: Dict[str, Any] | str, metadata: Dict[str, Any]) -> None:
@@ -104,6 +104,5 @@ class Mem0Storage(Storage):
104
104
 
105
105
  def _get_agent_name(self):
106
106
  agents = self.agents if self.agents else []
107
- agents = [self._sanitize_role(agent.role) for agent in agents]
108
- agents = "_".join(agents)
107
+ agents = "_".join([item.key for item in agents])
109
108
  return agents
@@ -52,15 +52,13 @@ class BaseRAGStorage(ABC):
52
52
 
53
53
  def _initialize_agents(self) -> str:
54
54
  if self.agents:
55
- return "_".join(
56
- [self._sanitize_role(agent.role) for agent in self.agents]
57
- )
55
+ return "_".join([agent.key for agent in self.agents])
58
56
  return ""
59
57
 
60
- @abstractmethod
61
- def _sanitize_role(self, role: str) -> str:
62
- """Sanitizes agent roles to ensure valid directory names."""
63
- pass
58
+ # @abstractmethod
59
+ # def _sanitize_role(self, role: str) -> str:
60
+ # """Sanitizes agent roles to ensure valid directory names."""
61
+ # pass
64
62
 
65
63
  @abstractmethod
66
64
  def save(self, value: Any, metadata: Dict[str, Any]) -> None:
@@ -108,7 +106,7 @@ class RAGStorage(BaseRAGStorage):
108
106
  def __init__(self, type, allow_reset=True, embedder_config=None, agents=list(), path=None):
109
107
  super().__init__(type, allow_reset, embedder_config, agents)
110
108
  agents = agents
111
- agents = [self._sanitize_role(agent.role) for agent in agents]
109
+ agents = [agent.key for agent in agents]
112
110
  agents = "_".join(agents)
113
111
 
114
112
  self.agents = agents
@@ -129,23 +127,23 @@ class RAGStorage(BaseRAGStorage):
129
127
  from chromadb.config import Settings
130
128
 
131
129
  self._set_embedder_config()
132
- chroma_client = chromadb.PersistentClient(
133
- path=self.path if self.path else self.storage_file_name,
134
- settings=Settings(allow_reset=self.allow_reset),
135
- )
136
- self.app = chroma_client
137
-
138
130
  try:
131
+ chroma_client = chromadb.PersistentClient(
132
+ path=self.path if self.path else self.storage_file_name,
133
+ settings=Settings(allow_reset=self.allow_reset),
134
+ )
135
+ self.app = chroma_client
139
136
  self.collection = self.app.get_collection(name=self.type, embedding_function=self.embedder_config)
140
137
  except Exception:
141
- self.collection = self.app.create_collection(name=self.type, embedding_function=self.embedder_config)
138
+ if self.app:
139
+ self.collection = self.app.create_collection(name=self.type, embedding_function=self.embedder_config)
142
140
 
143
141
 
144
- def _sanitize_role(self, role: str) -> str:
145
- """
146
- Sanitizes agent roles to ensure valid directory names.
147
- """
148
- return role.replace("\n", "").replace(" ", "_").replace("/", "_")
142
+ # def _sanitize_role(self, role: str) -> str:
143
+ # """
144
+ # Sanitizes agent roles to ensure valid directory names.
145
+ # """
146
+ # return role.replace("\n", "").replace(" ", "_").replace("/", "_")
149
147
 
150
148
 
151
149
  def _build_storage_file_name(self, type: str, file_name: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.2.1.18
3
+ Version: 1.2.1.20
4
4
  Summary: An agentic orchestration framework for building agent networks that handle task automation.
5
5
  Author-email: Kuriko Iwai <kuriko@versi0n.io>
6
6
  License: MIT License
@@ -244,10 +244,12 @@ def test_agent_with_knowledge_sources():
244
244
 
245
245
  agent = Agent(role="Information Agent", goal="Provide information based on knowledge sources", knowledge_sources=knowledge_sources)
246
246
 
247
- assert agent._knowledge.collection_name == f"{agent.role.replace(' ', '_')}"
247
+ assert agent._knowledge.collection_name == agent.key
248
248
  assert [isinstance(item, StringKnowledgeSource | DoclingSource) for item in agent.knowledge_sources]
249
249
  assert agent._knowledge.embedder_config == agent.embedder_config
250
- assert agent._knowledge.storage and agent._knowledge.storage.embedding_function and agent._knowledge.storage.app is not None and agent._knowledge.storage.collection_name is not None
250
+ assert agent._knowledge.storage and agent._knowledge.storage.embedding_function
251
+ assert agent._knowledge.storage.app is not None
252
+ assert agent._knowledge.storage.collection_name is not None
251
253
 
252
254
  task = Task(description="Answer the following question: What is Kuriko's favorite color?")
253
255
 
@@ -15,7 +15,7 @@ def test_minimum_inputs():
15
15
 
16
16
 
17
17
 
18
- def test_specific_formation():
18
+ def _test_specific_formation():
19
19
  import versionhq as vhq
20
20
 
21
21
  formations_to_test = [
@@ -52,6 +52,6 @@ def test_demo_agent_customization():
52
52
  )
53
53
 
54
54
  assert "gemini-2.0" in agent.llm.model
55
- assert agent.llm.temperature == 1 and agent.llm.top_p == 0.1 and agent.llm.n==1 and agent.llm.stop == "test"
55
+ assert agent.llm.temperature == 1 and agent.llm.top_p == 0.1 and agent.llm.n == 1 and agent.llm.stop == "test"
56
56
  assert agent.knowledge_sources == ['https://business.linkedin.com', f'{current_path}/demo.csv',]
57
57
  assert agent.with_memory == True
@@ -3982,7 +3982,7 @@ wheels = [
3982
3982
 
3983
3983
  [[package]]
3984
3984
  name = "versionhq"
3985
- version = "1.2.1.17"
3985
+ version = "1.2.1.20"
3986
3986
  source = { editable = "." }
3987
3987
  dependencies = [
3988
3988
  { name = "appdirs" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes