versionhq 1.1.11.5__py3-none-any.whl → 1.1.11.7__py3-none-any.whl

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.
versionhq/__init__.py CHANGED
@@ -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.5"
20
+ __version__ = "1.1.11.7"
21
21
  __all__ = [
22
22
  "Agent",
23
23
  "Customer",
versionhq/agent/model.py CHANGED
@@ -99,7 +99,7 @@ class Agent(BaseModel):
99
99
  tools: Optional[List[InstanceOf[Tool | ToolSet] | Type[Tool] | Any]] = Field(default_factory=list)
100
100
 
101
101
  # knowledge
102
- knowledge_sources: Optional[List[BaseKnowledgeSource]] = Field(default=None)
102
+ knowledge_sources: Optional[List[BaseKnowledgeSource | Any]] = Field(default=None)
103
103
  _knowledge: Optional[Knowledge] = PrivateAttr(default=None)
104
104
 
105
105
  # memory
@@ -344,14 +344,46 @@ class Agent(BaseModel):
344
344
 
345
345
  @model_validator(mode="after")
346
346
  def set_up_knowledge(self) -> Self:
347
- if self.knowledge_sources:
348
- collection_name = f"{self.role.replace(' ', '_')}"
347
+ from versionhq.knowledge.source import BaseKnowledgeSource, StringKnowledgeSource, TextFileKnowledgeSource, CSVKnowledgeSource, ExcelKnowledgeSource, JSONKnowledgeSource
348
+ from versionhq.knowledge.source_docling import DoclingSource
349
349
 
350
- self._knowledge = Knowledge(
351
- sources=self.knowledge_sources,
352
- embedder_config=self.embedder_config,
353
- collection_name=collection_name,
354
- )
350
+ if self.knowledge_sources:
351
+ try:
352
+ collection_name = f"{self.role.replace(' ', '_')}"
353
+ knowledge_sources = []
354
+ docling_fp, txt_fp, json_fp, excel_fp, csv_fp, pdf_fp = [], [], [], [], [], []
355
+ str_cont = ""
356
+
357
+ for item in self.knowledge_sources:
358
+ if isinstance(item, BaseKnowledgeSource):
359
+ knowledge_sources.append(item)
360
+
361
+ elif isinstance(item, str) and "http" in item:
362
+ docling_fp.append(item)
363
+
364
+ elif isinstance(item, str):
365
+ match os.path.splitext(item)[1]:
366
+ case ".txt": txt_fp.append(item)
367
+ case ".json": json_fp.append(item)
368
+ case ".xls" | ".xlsx": excel_fp.append(item)
369
+ case ".pdf": pdf_fp.append(item)
370
+ case ".csv": csv_fp.append(item)
371
+ case _: str_cont += str(item)
372
+
373
+ else:
374
+ str_cont += str(item)
375
+
376
+ if docling_fp: knowledge_sources.append(DoclingSource(file_paths=docling_fp))
377
+ if str_cont: knowledge_sources.append(StringKnowledgeSource(content=str_cont))
378
+ if txt_fp: knowledge_sources.append(TextFileKnowledgeSource(file_paths=txt_fp))
379
+ if csv_fp: knowledge_sources.append(CSVKnowledgeSource(file_path=csv_fp))
380
+ if excel_fp: knowledge_sources.append(ExcelKnowledgeSource(file_path=excel_fp))
381
+ if json_fp: knowledge_sources.append(JSONKnowledgeSource(file_paths=json_fp))
382
+
383
+ self._knowledge = Knowledge(sources=knowledge_sources, embedder_config=self.embedder_config, collection_name=collection_name)
384
+
385
+ except:
386
+ self._logger.log(level="warning", message="We cannot find the format for the source. Add BaseKnowledgeSource objects instead.", color="yellow")
355
387
 
356
388
  return self
357
389
 
@@ -414,7 +446,7 @@ class Agent(BaseModel):
414
446
  self._logger.log(level="info", message=f"Messages sent to the model: {messages}", color="blue")
415
447
 
416
448
  if tool_res_as_final:
417
- func_llm = self.function_calling_llm if self.function_calling_llm and self.function_calling_llm._supports_function_calling() else LLM(model=DEFAULT_MODEL_NAME)
449
+ func_llm = self.function_calling_llm if self.function_calling_llm and self.function_calling_llm._supports_function_calling() else self.llm if self.llm and self.llm._supports_function_calling() else LLM(model=DEFAULT_MODEL_NAME)
418
450
  raw_response = func_llm.call(messages=messages, tools=tools, tool_res_as_final=True)
419
451
  task.tokens = func_llm._tokens
420
452
  else:
@@ -458,7 +490,7 @@ class Agent(BaseModel):
458
490
  from versionhq.knowledge._utils import extract_knowledge_context
459
491
 
460
492
  task: InstanceOf[Task] = task
461
- tools: Optional[List[InstanceOf[Tool]| InstanceOf[ToolSet] | Type[Tool]]] = task_tools + self.tools if task.can_use_agent_tools else task_tools
493
+ tools: Optional[List[InstanceOf[Tool | ToolSet] | Type[Tool]]] = task_tools + self.tools if task.can_use_agent_tools else task_tools
462
494
 
463
495
  if self.max_rpm and self._rpm_controller:
464
496
  self._rpm_controller._reset_request_count()
@@ -474,7 +506,6 @@ class Agent(BaseModel):
474
506
  if agent_knowledge_context:
475
507
  task_prompt += agent_knowledge_context
476
508
 
477
-
478
509
  if self.use_memory == True:
479
510
  contextual_memory = ContextualMemory(
480
511
  memory_config=self.memory_config, stm=self.short_term_memory, ltm=self.long_term_memory, um=self.user_memory
@@ -3,7 +3,6 @@ from typing import Iterator, List, Optional
3
3
  from urllib.parse import urlparse
4
4
 
5
5
  try:
6
- import docling
7
6
  from docling.datamodel.base_models import InputFormat
8
7
  from docling.document_converter import DocumentConverter
9
8
  from docling.exceptions import ConversionError
@@ -12,9 +11,8 @@ try:
12
11
  DOCLING_AVAILABLE = True
13
12
  except ImportError:
14
13
  import envoy
15
- r = envoy.run("uv add docling --optional docling")
14
+ envoy.run("uv add docling --optional docling")
16
15
 
17
- import docling
18
16
  from docling.datamodel.base_models import InputFormat
19
17
  from docling.document_converter import DocumentConverter
20
18
  from docling.exceptions import ConversionError
@@ -73,11 +73,21 @@ class KnowledgeStorage(BaseKnowledgeStorage):
73
73
 
74
74
 
75
75
  def __init__(self, embedder_config: Optional[Dict[str, Any]] = None, collection_name: Optional[str] = None):
76
- self.collection_name = collection_name if collection_name else "knowledge"
76
+ self.collection_name = self._validate_collection_name(collection_name) if collection_name else "knowledge"
77
77
  self.embedder_config = embedder_config
78
78
  self.initialize_knowledge_storage()
79
79
 
80
80
 
81
+ def _validate_collection_name(self, collection_name: str = None) -> str:
82
+ """
83
+ Return a valid collection name from the given collection name.
84
+ Expected collection name (1) contains 3-63 characters, (2) starts and ends with an alphanumeric character, (3) otherwise contains only alphanumeric characters, underscores or hyphens (-), (4) contains no two consecutive periods (..) and (5) is not a valid IPv4 address.
85
+ """
86
+ collection_name = collection_name if collection_name else self.collection_name
87
+ valid_collection_name = collection_name.replace(' ', "-").replace("(", "-").replace(")", "").replace("..", "")
88
+ return valid_collection_name
89
+
90
+
81
91
  def _create_default_embedding_function(self) -> Any:
82
92
  from chromadb.utils.embedding_functions.openai_embedding_function import OpenAIEmbeddingFunction
83
93
 
@@ -101,6 +111,7 @@ class KnowledgeStorage(BaseKnowledgeStorage):
101
111
  chroma_client = chromadb.PersistentClient(path=base_path, settings=Settings(allow_reset=True))
102
112
  self.app = chroma_client
103
113
  self._set_embedding_function(embedder_config=self.embedder_config)
114
+ self.collection_name = self.collection_name if self.collection_name else "knowledge"
104
115
 
105
116
  try:
106
117
  if self.app:
versionhq/llm/llm_vars.py CHANGED
@@ -3,6 +3,20 @@ from typing import Type
3
3
 
4
4
  JSON_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
5
5
 
6
+ PROVIDERS = [
7
+ "openai",
8
+ "gemini",
9
+ "sagemaker",
10
+
11
+ "anthropic",
12
+ "ollama",
13
+ "watson",
14
+ "bedrock",
15
+ "azure",
16
+ "cerebras",
17
+ "llama",
18
+ ]
19
+
6
20
 
7
21
  """
8
22
  List of models available on the framework.
@@ -16,7 +30,6 @@ litellm.pick_cheapest_chat_models_from_llm_provider(custom_llm_provider: str, n=
16
30
 
17
31
  MODELS = {
18
32
  "openai": [
19
- # "gpt-3.5-turbo",
20
33
  "gpt-4",
21
34
  "gpt-4o",
22
35
  "gpt-4o-mini",
@@ -27,11 +40,7 @@ MODELS = {
27
40
  "gemini/gemini-1.5-flash",
28
41
  "gemini/gemini-1.5-pro",
29
42
  "gemini/gemini-2.0-flash-exp",
30
- # "gemini/gemini-gemma-2-9b-it",
31
- # "gemini/gemini-gemma-2-27b-it",
32
43
  ],
33
- # "vetrex_ai": [
34
- # ],
35
44
  "anthropic": [
36
45
  "claude-3-5-sonnet-20241022",
37
46
  "claude-3-5-sonnet-20240620",
@@ -39,10 +48,26 @@ MODELS = {
39
48
  "claude-3-opus-20240229",
40
49
  "claude-3-haiku-20240307",
41
50
  ],
42
- # "ollama": [
43
- # "ollama/llama3.1",
44
- # "ollama/mixtral",
45
- # ],
51
+ # "sagemaker": [
52
+ # "sagemaker/huggingface-text2text-flan-t5-base",
53
+ # "sagemaker/huggingface-llm-gemma-7b",
54
+ # "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-13b",
55
+ # "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-70b",
56
+ # "sagemaker/jumpstart-dft-meta-textgeneration-llama-3-8b",
57
+ # "sagemaker/jumpstart-dft-meta-textgeneration-llama-3-70b",
58
+ # "sagemaker/huggingface-llm-mistral-7b"
59
+ # ], #https://docs.aws.amazon.com/sagemaker/latest/dg/jumpstart-foundation-models-latest.html
60
+ "ollama": [
61
+ "ollama/llama3.1",
62
+ "ollama/mixtral",
63
+ "ollama/mixtral-8x22B-Instruct-v0.1",
64
+
65
+ ],
66
+ "deepseek": [
67
+ "deepseek/deepseek-reasoner",
68
+
69
+ ],
70
+
46
71
  # "watson": [
47
72
  # "watsonx/meta-llama/llama-3-1-70b-instruct",
48
73
  # "watsonx/meta-llama/llama-3-1-8b-instruct",
@@ -53,44 +78,48 @@ MODELS = {
53
78
  # "watsonx/mistral/mistral-large",
54
79
  # "watsonx/ibm/granite-3-8b-instruct",
55
80
  # ],
56
- # "bedrock": [
57
- # "bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0",
58
- # "bedrock/anthropic.claude-3-sonnet-20240229-v1:0",
59
- # "bedrock/anthropic.claude-3-haiku-20240307-v1:0",
60
- # "bedrock/anthropic.claude-3-opus-20240229-v1:0",
61
- # "bedrock/anthropic.claude-v2:1",
62
- # "bedrock/anthropic.claude-v2",
63
- # "bedrock/anthropic.claude-instant-v1",
64
- # "bedrock/meta.llama3-1-405b-instruct-v1:0",
65
- # "bedrock/meta.llama3-1-70b-instruct-v1:0",
66
- # "bedrock/meta.llama3-1-8b-instruct-v1:0",
67
- # "bedrock/meta.llama3-70b-instruct-v1:0",
68
- # "bedrock/meta.llama3-8b-instruct-v1:0",
69
- # "bedrock/amazon.titan-text-lite-v1",
70
- # "bedrock/amazon.titan-text-express-v1",
71
- # "bedrock/cohere.command-text-v14",
72
- # "bedrock/ai21.j2-mid-v1",
73
- # "bedrock/ai21.j2-ultra-v1",
74
- # "bedrock/ai21.jamba-instruct-v1:0",
75
- # "bedrock/meta.llama2-13b-chat-v1",
76
- # "bedrock/meta.llama2-70b-chat-v1",
77
- # "bedrock/mistral.mistral-7b-instruct-v0:2",
78
- # "bedrock/mistral.mixtral-8x7b-instruct-v0:1",
79
- # ],
81
+ "bedrock": [
82
+ "bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0",
83
+ "bedrock/anthropic.claude-3-sonnet-20240229-v1:0",
84
+ "bedrock/anthropic.claude-3-haiku-20240307-v1:0",
85
+ "bedrock/anthropic.claude-3-opus-20240229-v1:0",
86
+ # "bedrock/anthropic.claude-v2:1",
87
+ "bedrock/anthropic.claude-v2",
88
+ "bedrock/anthropic.claude-instant-v1",
89
+ "bedrock/meta.llama3-1-405b-instruct-v1:0",
90
+ "bedrock/meta.llama3-1-70b-instruct-v1:0",
91
+ "bedrock/meta.llama3-1-8b-instruct-v1:0",
92
+ "bedrock/meta.llama3-70b-instruct-v1:0",
93
+ "bedrock/meta.llama3-8b-instruct-v1:0",
94
+ "bedrock/amazon.titan-text-lite-v1",
95
+ "bedrock/amazon.titan-text-express-v1",
96
+ "bedrock/cohere.command-text-v14",
97
+ "bedrock/ai21.j2-mid-v1",
98
+ "bedrock/ai21.j2-ultra-v1",
99
+ "bedrock/ai21.jamba-instruct-v1:0",
100
+ "bedrock/meta.llama2-13b-chat-v1",
101
+ "bedrock/meta.llama2-70b-chat-v1",
102
+ "bedrock/mistral.mistral-7b-instruct-v0:2",
103
+ "bedrock/mistral.mixtral-8x7b-instruct-v0:1",
104
+ ],
80
105
  }
81
106
 
82
107
 
83
- PROVIDERS = [
84
- "openai",
85
- "anthropic",
86
- "gemini",
87
- "ollama",
88
- "watson",
89
- "bedrock",
90
- "azure",
91
- "cerebras",
92
- "llama",
93
- ]
108
+
109
+ KEYS = {
110
+ "openai": ["OPENAI_API_KEY"],
111
+ "gemini": ["GEMINI_API_KEY"],
112
+ "sagemaker": ["AWS_ACCESS_KEY_ID", "ADW_SECURET_ACCESS_KEY", "AWS_REGION_NAME"],
113
+ "anthropic": ["ANTHROPIC_API_KEY"],
114
+ }
115
+
116
+
117
+ """
118
+ Use base_url to specify
119
+ """
120
+ BASE_URLS = {
121
+ "deepseek": "https://api.deepseek.com"
122
+ }
94
123
 
95
124
 
96
125
  """
@@ -118,6 +147,8 @@ LLM_CONTEXT_WINDOW_SIZES = {
118
147
  "claude-3-haiku-20240307": 200000,
119
148
 
120
149
  "deepseek-chat": 128000,
150
+ "deepseek/deepseek-reasoner": 8192,
151
+
121
152
  "gemma2-9b-it": 8192,
122
153
  "gemma-7b-it": 8192,
123
154
  "llama3-groq-70b-8192-tool-use-preview": 8192,
@@ -135,11 +166,7 @@ LLM_CONTEXT_WINDOW_SIZES = {
135
166
  }
136
167
 
137
168
 
138
- LLM_API_KEY_NAMES = {
139
- "openai": "OPENAI_API_KEY",
140
- "anthropic": "ANTHROPIC_API_KEY",
141
- "gemini": "GEMINI_API_KEY",
142
- }
169
+
143
170
 
144
171
  LLM_BASE_URL_KEY_NAMES = {
145
172
  "openai": "OPENAI_API_BASE",
@@ -262,14 +289,8 @@ PARAMS = {
262
289
  ],
263
290
  "openai": [
264
291
  "timeout",
265
- # "temperature",
266
- # "top_p",
267
- # "n",
268
- # "stream",
269
292
  "stream_options",
270
- # "stop",
271
293
  "max_compl,etion_tokens",
272
- # "max_tokens",
273
294
  "modalities",
274
295
  "prediction",
275
296
  "audio",
@@ -277,10 +298,7 @@ PARAMS = {
277
298
  "frequency_penalty",
278
299
  "logit_bias",
279
300
  "user",
280
- # "response_format",
281
301
  "seed",
282
- # "tools",
283
- # "tool_choice",
284
302
  "logprobs",
285
303
  "top_logprobs",
286
304
  "parallel_tool_calls",
versionhq/llm/model.py CHANGED
@@ -4,23 +4,16 @@ import os
4
4
  import sys
5
5
  import threading
6
6
  import warnings
7
- import litellm
8
- from litellm import JSONSchemaValidationError
9
- from abc import ABC
10
7
  from dotenv import load_dotenv
11
- from litellm import get_supported_openai_params
8
+ import litellm
9
+ from litellm import get_supported_openai_params, JSONSchemaValidationError
12
10
  from contextlib import contextmanager
13
- from typing import Any, Dict, List, Optional, Type
11
+ from typing import Any, Dict, List, Optional
14
12
  from typing_extensions import Self
15
-
16
13
  from pydantic import UUID4, BaseModel, Field, PrivateAttr, field_validator, model_validator, create_model, InstanceOf, ConfigDict
17
14
  from pydantic_core import PydanticCustomError
18
15
 
19
- from openai import OpenAI
20
-
21
- from versionhq.llm.llm_vars import LLM_CONTEXT_WINDOW_SIZES, LLM_API_KEY_NAMES, LLM_BASE_URL_KEY_NAMES, MODELS, PARAMS, SchemaType
22
- from versionhq.task import TaskOutputFormat
23
- from versionhq.task.model import ResponseField, Task
16
+ from versionhq.llm.llm_vars import LLM_CONTEXT_WINDOW_SIZES, MODELS, PARAMS
24
17
  from versionhq.tool.model import Tool, ToolSet
25
18
  from versionhq._utils.logger import Logger
26
19
 
@@ -31,8 +24,8 @@ LITELLM_API_BASE = os.environ.get("LITELLM_API_BASE")
31
24
  DEFAULT_CONTEXT_WINDOW_SIZE = int(8192 * 0.75)
32
25
  DEFAULT_MODEL_NAME = os.environ.get("DEFAULT_MODEL_NAME")
33
26
 
34
- proxy_openai_client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"), organization="versionhq", base_url=LITELLM_API_BASE)
35
- openai_client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
27
+ # proxy_openai_client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"), organization="versionhq", base_url=LITELLM_API_BASE)
28
+ # openai_client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
36
29
 
37
30
 
38
31
  class FilteredStream:
@@ -179,6 +172,7 @@ class LLM(BaseModel):
179
172
  if api_key_name:
180
173
  self.api_key = os.environ.get(api_key_name, None)
181
174
 
175
+
182
176
  base_url_key_name = self.provider.upper() + "_API_BASE" if self.provider else None
183
177
  if base_url_key_name:
184
178
  self.base_url = os.environ.get(base_url_key_name)
@@ -236,51 +230,51 @@ class LLM(BaseModel):
236
230
  else:
237
231
  self.tools = [item.tool.properties if isinstance(item, ToolSet) else item.properties for item in tools]
238
232
 
239
- if provider == "openai":
240
- params = self._create_valid_params(config=config, provider=provider)
241
- res = openai_client.chat.completions.create(messages=messages, model=self.model, tools=self.tools)
242
- tool_calls = res.choices[0].message.tool_calls
243
- tool_res = ""
244
-
245
- for item in tool_calls:
246
- func_name = item.function.name
247
- func_args = item.function.arguments
233
+ # if provider == "openai":
234
+ params = self._create_valid_params(config=config, provider=provider)
235
+ res = litellm.completion(messages=messages, model=self.model, tools=self.tools)
236
+ tool_calls = res.choices[0].message.tool_calls
237
+ tool_res = ""
238
+
239
+ for item in tool_calls:
240
+ func_name = item.function.name
241
+ func_args = item.function.arguments
242
+
243
+ if not isinstance(func_args, dict):
244
+ try:
245
+ func_args = json.loads(json.dumps(eval(str(func_args))))
246
+ except:
247
+ pass
248
+
249
+ for tool in tools:
250
+ if isinstance(tool, ToolSet) and (tool.tool.name == func_name or tool.tool.func.__name__ == func_name or func_name == "random_func"):
251
+ tool_instance = tool.tool
252
+ args = tool.kwargs
253
+ tool_res_to_add = tool_instance.run(params=args)
254
+
255
+ if tool_res_as_final:
256
+ tool_res += str(tool_res_to_add)
257
+ else:
258
+ messages.append(res.choices[0].message)
259
+ messages.append({ "role": "tool", "tool_call_id": item.id, "content": str(tool_res_to_add) })
248
260
 
249
- if not isinstance(func_args, dict):
261
+ else:
250
262
  try:
251
- func_args = json.loads(json.dumps(eval(str(func_args))))
252
- except:
253
- pass
254
-
255
- for tool in tools:
256
- if isinstance(tool, ToolSet) and (tool.tool.name == func_name or tool.tool.func.__name__ == func_name or func_name == "random_func"):
257
- tool_instance = tool.tool
258
- args = tool.kwargs
259
- tool_res_to_add = tool_instance.run(params=args)
260
-
263
+ tool_res_to_add = tool.run(params=func_args)
261
264
  if tool_res_as_final:
262
265
  tool_res += str(tool_res_to_add)
263
266
  else:
264
267
  messages.append(res.choices[0].message)
265
268
  messages.append({ "role": "tool", "tool_call_id": item.id, "content": str(tool_res_to_add) })
269
+ except:
270
+ pass
266
271
 
267
- else:
268
- try:
269
- tool_res_to_add = tool.run(params=func_args)
270
- if tool_res_as_final:
271
- tool_res += str(tool_res_to_add)
272
- else:
273
- messages.append(res.choices[0].message)
274
- messages.append({ "role": "tool", "tool_call_id": item.id, "content": str(tool_res_to_add) })
275
- except:
276
- pass
277
-
278
- if tool_res_as_final:
279
- return tool_res
280
- else:
281
- res = openai_client.chat.completions.create(messages=messages, model=self.model, tools=self.tools)
282
- self._tokens += int(res["usage"]["total_tokens"])
283
- return res.choices[0].message.content
272
+ if tool_res_as_final:
273
+ return tool_res
274
+ else:
275
+ res = litellm.completione(messages=messages, model=self.model, tools=self.tools)
276
+ self._tokens += int(res["usage"]["total_tokens"])
277
+ return res.choices[0].message.content
284
278
 
285
279
  except JSONSchemaValidationError as e:
286
280
  self._logger.log(level="error", message="Raw Response: {}".format(e.raw_response), color="red")
versionhq/task/model.py CHANGED
@@ -412,6 +412,8 @@ Ref. Output image: {output_formats_to_follow}
412
412
 
413
413
  response_format: Dict[str, Any] = None
414
414
 
415
+ # match model_provider:
416
+ # case "openai":
415
417
  if self.response_fields:
416
418
  properties, required_fields = {}, []
417
419
  for i, item in enumerate(self.response_fields):
@@ -439,6 +441,7 @@ Ref. Output image: {output_formats_to_follow}
439
441
  elif self.pydantic_output:
440
442
  response_format = StructuredOutput(response_format=self.pydantic_output)._format()
441
443
 
444
+ # case "gemini":
442
445
  return response_format
443
446
 
444
447
 
@@ -636,7 +639,7 @@ Ref. Output image: {output_formats_to_follow}
636
639
 
637
640
  if self.tool_res_as_final == True:
638
641
  tool_output = agent.execute_task(task=self, context=context, task_tools=task_tools)
639
- task_output = TaskOutput(task_id=self.id, tool_output=tool_output)
642
+ task_output = TaskOutput(task_id=self.id, tool_output=tool_output, raw=tool_output)
640
643
 
641
644
  else:
642
645
  raw_output = agent.execute_task(task=self, context=context, task_tools=task_tools)
@@ -82,12 +82,13 @@ class StructuredList:
82
82
 
83
83
  if nested_object_type == dict:
84
84
  props.update({
85
- "nest": {
85
+ # "nest": {
86
86
  "type": "object",
87
87
  "properties": { "item": { "type": "string"} }, #! REFINEME - field title <>`item`
88
88
  "required": ["item",],
89
89
  "additionalProperties": False
90
- }})
90
+ # }
91
+ })
91
92
 
92
93
  elif nested_object_type == list:
93
94
  props.update({
@@ -110,7 +111,7 @@ class StructuredList:
110
111
 
111
112
 
112
113
  class StructuredOutput(BaseModel):
113
- response_format: Any = None
114
+ response_format: Any = None # pydantic base model
114
115
  provider: str = "openai"
115
116
  applicable_models: List[InstanceOf[LLM] | str] = list()
116
117
  name: str = ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.1.11.5
3
+ Version: 1.1.11.7
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
@@ -319,8 +319,10 @@ src/
319
319
  pyenv install 3.12.8
320
320
  pyenv global 3.12.8 (optional: `pyenv global system` to get back to the system default ver.)
321
321
  uv python pin 3.12.8
322
+ echo 3.12.8 > .python-version
322
323
  ```
323
324
 
325
+
324
326
  3. Set up environment variables:
325
327
  Create a `.env` file in the project root and add the following:
326
328
  ```
@@ -1,4 +1,4 @@
1
- versionhq/__init__.py,sha256=2Zt2x3RvXctSU64Bv3Omw9EFjs5WQ3xKOijkiHNt4tU,863
1
+ versionhq/__init__.py,sha256=P2XOAcL21Bc7HXFQRtWWRJG5a1XB3GZSv86y7GHlZfc,863
2
2
  versionhq/_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  versionhq/_utils/i18n.py,sha256=TwA_PnYfDLA6VqlUDPuybdV9lgi3Frh_ASsb_X8jJo8,1483
4
4
  versionhq/_utils/logger.py,sha256=U-MpeGueA6YS8Ptfy0VnU_ePsZP-8Pvkvi0tZ4s_UMg,1438
@@ -7,7 +7,7 @@ versionhq/_utils/usage_metrics.py,sha256=hhq1OCW8Z4V93vwW2O2j528EyjOlF8wlTsX5IL-
7
7
  versionhq/_utils/vars.py,sha256=bZ5Dx_bFKlt3hi4-NNGXqdk7B23If_WaTIju2fiTyPQ,57
8
8
  versionhq/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  versionhq/agent/default_agents.py,sha256=Sea3xDswxxMccer1vVDhp1E5etXW3ddf2n20JTMHgqs,503
10
- versionhq/agent/model.py,sha256=kL949N0MELAZz58XB_vlQfE1YQU_o4iHggNDn_h_7yo,22758
10
+ versionhq/agent/model.py,sha256=AL0t_knk_PX-mLO8a9PKxt12MavSraBHNLynI4ezpq8,24779
11
11
  versionhq/agent/parser.py,sha256=riG0dkdQCxH7uJ0AbdVdg7WvL0BXhUgJht0VtQvxJBc,4082
12
12
  versionhq/agent/rpm_controller.py,sha256=7AKIEPbWBq_ESOZCaiKVOGjfSPHd2qwg6-wbBlhqC0g,2367
13
13
  versionhq/agent/TEMPLATES/Backstory.py,sha256=IAhGnnt6VUMe3wO6IzeyZPDNu7XE7Uiu3VEXUreOcKs,532
@@ -25,11 +25,11 @@ versionhq/knowledge/_utils.py,sha256=YWRF8U533cfZes_gZqUvdj-K24MD2ri1R0gjc_aPYyc
25
25
  versionhq/knowledge/embedding.py,sha256=KfHc__1THxb5jrg1EMrF-v944RDuIr2hE0l-MtM3Bp0,6826
26
26
  versionhq/knowledge/model.py,sha256=n7kU4jQ24BUIxwosSVRK8tYhAFYhgc4yf7e4Q-bq4bk,1832
27
27
  versionhq/knowledge/source.py,sha256=WOARChmm_cNtBD-xGo4RoYmcuodzdalctXI-gDBCW6k,13610
28
- versionhq/knowledge/source_docling.py,sha256=Lv7PDE97pwV5_3SPcIgTzEu3H4obRbPfY3NALvfkgX8,5364
29
- versionhq/knowledge/storage.py,sha256=uesUF6zFhXcgadrgzPVzLf9kBgvb3jMjWJIJzBlnhFk,7350
28
+ versionhq/knowledge/source_docling.py,sha256=uj7mX1VjUr3cucAjZCuRcrKNQdae38I8Y7KyXrcqaS8,5322
29
+ versionhq/knowledge/storage.py,sha256=7oxCg3W9mFjYH1YmuH9kFtTbNxquzYFjuUjd_TlsB9E,8170
30
30
  versionhq/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- versionhq/llm/llm_vars.py,sha256=PO__b-h5e-6oQ-uoIgXx3lPSAUPUwXYfdVRW73fvX14,8761
32
- versionhq/llm/model.py,sha256=1uaBxT10GIlUl-BtE8Mfux-ZRcScp4HUIas_fD_cdWQ,14471
31
+ versionhq/llm/llm_vars.py,sha256=f8kPWKYLt5pPDqXQ4-McoUySM15J4N7a3tHMoMaxNzs,9264
32
+ versionhq/llm/model.py,sha256=FACbUOPmhyatO34sXj7KI4HlHUmjujc-7KX8MfInpLc,14064
33
33
  versionhq/memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  versionhq/memory/contextual_memory.py,sha256=tCsOOAUnfrOL7YiakqGoi3uShzzS870TmGnlGd3z_A4,3556
35
35
  versionhq/memory/model.py,sha256=6Sy-cnrhHNIx3ZN38uNO7d8YywIl_uo_OvDVzVM-w14,5755
@@ -44,8 +44,8 @@ versionhq/task/__init__.py,sha256=l2r_g01i91JAGlOoHZP_Gh2WCk6mo9D19lcqt7sKMpQ,18
44
44
  versionhq/task/evaluate.py,sha256=RCaFa9N4IibAYLWKUlTn6lWiQoI7t4f_XZVUvecjTxs,3486
45
45
  versionhq/task/formatter.py,sha256=N8Kmk9vtrMtBdgJ8J7RmlKNMdZWSmV8O1bDexmCWgU0,643
46
46
  versionhq/task/log_handler.py,sha256=KJRrcNZgFSKhlNzvtYFnvtp6xukaF1s7ifX9u4zWrN8,1683
47
- versionhq/task/model.py,sha256=Uxs5LaGb1O9CdnhWh36sSbgdKPfDYDCi2V4BNdvAMPc,30027
48
- versionhq/task/structured_response.py,sha256=h5GbbkCNJ27f4AbHcriGctQLFSp4qlmq2REDEfSd8xU,4786
47
+ versionhq/task/model.py,sha256=ACHtRG2xtcSKin70wSp4GHg_B3wnPguaoVekESbG8VU,30134
48
+ versionhq/task/structured_response.py,sha256=YxuWcDMHcZLzdxI1ihW99Y-i6nl8yXBQ5Q_dFQac8jw,4837
49
49
  versionhq/task/TEMPLATES/Description.py,sha256=bChflSWGGQo9JpnO6QX6Ng9pnONiTf-zwQ3ke4xQgSQ,357
50
50
  versionhq/team/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  versionhq/team/model.py,sha256=NzcRXWwP0adWL9vsnsmI-A5dOcE3199FGmGgemUB2VA,20043
@@ -57,8 +57,8 @@ versionhq/tool/composio_tool_vars.py,sha256=FvBuEXsOQUYnN7RTFxT20kAkiEYkxWKkiVtg
57
57
  versionhq/tool/decorator.py,sha256=C4ZM7Xi2gwtEMaSeRo-geo_g_MAkY77WkSLkAuY0AyI,1205
58
58
  versionhq/tool/model.py,sha256=7ccEnje_8LuxLVeog6pL38nToArXQXk4KY7A9hfprDo,12239
59
59
  versionhq/tool/tool_handler.py,sha256=2m41K8qo5bGCCbwMFferEjT-XZ-mE9F0mDUOBkgivOI,1416
60
- versionhq-1.1.11.5.dist-info/LICENSE,sha256=7CCXuMrAjPVsUvZrsBq9DsxI2rLDUSYXR_qj4yO_ZII,1077
61
- versionhq-1.1.11.5.dist-info/METADATA,sha256=kqMA6vNrLp3wgffnEfUJjPT2Jr3eylK-guAj8g4QXt8,18638
62
- versionhq-1.1.11.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
63
- versionhq-1.1.11.5.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
64
- versionhq-1.1.11.5.dist-info/RECORD,,
60
+ versionhq-1.1.11.7.dist-info/LICENSE,sha256=7CCXuMrAjPVsUvZrsBq9DsxI2rLDUSYXR_qj4yO_ZII,1077
61
+ versionhq-1.1.11.7.dist-info/METADATA,sha256=Rra00hIoAMSKGzNfYAW0MfaXZ1g2bffT37D0yCutvao,18672
62
+ versionhq-1.1.11.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
63
+ versionhq-1.1.11.7.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
64
+ versionhq-1.1.11.7.dist-info/RECORD,,