versionhq 1.2.4.1__py3-none-any.whl → 1.2.4.3__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.
@@ -15,7 +15,14 @@ from pydantic_core import PydanticCustomError
15
15
 
16
16
  from versionhq.agent.model import Agent
17
17
  from versionhq.task.model import Task, TaskOutput, Evaluation
18
- from versionhq._utils.logger import Logger
18
+ from versionhq._utils import Logger, UsageMetrics, ErrorType
19
+
20
+
21
+ class ReformTriggerEvent(enum.Enum):
22
+ USER_INPUT = 1 # ask human
23
+ TEST_TIME_COMPUTATION = 2 # mismatch between actual responses and expected outcome
24
+ ERROR_DETECTION = 3 # response error
25
+
19
26
 
20
27
  class ConditionType(enum.Enum):
21
28
  AND = 1
@@ -46,7 +53,6 @@ class Condition(BaseModel):
46
53
  res = method(**args) if args else method()
47
54
  return res
48
55
 
49
-
50
56
  def condition_met(self) -> bool:
51
57
  if not self.methods:
52
58
  return True
@@ -54,7 +60,6 @@ class Condition(BaseModel):
54
60
  if len(self.methods) == 1:
55
61
  for k, v in self.methods.items():
56
62
  return self._execute_method(key=k, method=v)
57
-
58
63
  else:
59
64
  cond_list = []
60
65
  for k, v in self.methods.items():
@@ -96,8 +101,8 @@ class Node(BaseModel):
96
101
 
97
102
  id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
98
103
  task: InstanceOf[Task] = Field(default=None)
99
- in_degree_nodes: List[Any] = Field(default_factory=list, description="list of Node objects")
100
- out_degree_nodes: List[Any] = Field(default_factory=list, description="list of Node objects")
104
+ in_degree_nodes: List["Node"] = Field(default_factory=list, description="list of Node objects")
105
+ out_degree_nodes: List["Node"] = Field(default_factory=list, description="list of Node objects")
101
106
  assigned_to: InstanceOf[Agent] = Field(default=None)
102
107
  status: TaskStatus = Field(default=TaskStatus.NOT_STARTED)
103
108
 
@@ -107,29 +112,31 @@ class Node(BaseModel):
107
112
  if v:
108
113
  raise PydanticCustomError("may_not_set_field", "This field is not to be set by client.", {})
109
114
 
110
-
111
115
  def is_independent(self) -> bool:
112
116
  return not self.in_degree_nodes and not self.out_degree_nodes
113
117
 
114
118
  def handle_task_execution(self, agent: Agent = None, context: str = None, response_format: Type[BaseModel] = None) -> TaskOutput | None:
115
119
  """Executes the task and updates its status"""
116
120
 
117
- self.status = TaskStatus.IN_PROGRESS
118
-
119
121
  if not self.task:
120
122
  Logger().log(level="error", message="Missing a task to execute. We'll return None.", color="red")
121
123
  self.status = TaskStatus.ERROR
122
124
  return None
123
125
 
124
- agent = agent if agent else self.assigned_to
125
- self.task.pydantic_output = self.task.pydantic_output if self.task.pydantic_output else response_format if type(response_format) == BaseModel else None
126
- res = self.task.execute(agent=agent, context=context)
126
+ if self.status == TaskStatus.COMPLETED:
127
+ return self.task.output
127
128
 
128
- if isinstance(res, Future): # activate async
129
- res = res.result()
129
+ else:
130
+ self.status = TaskStatus.IN_PROGRESS
131
+ agent = agent if agent else self.assigned_to
132
+ self.task.pydantic_output = self.task.pydantic_output if self.task.pydantic_output else response_format if type(response_format) == BaseModel else None
133
+ res = self.task.execute(agent=agent, context=context)
130
134
 
131
- self.status = TaskStatus.COMPLETED if res else TaskStatus.ERROR
132
- return res
135
+ if isinstance(res, Future): # activate async
136
+ res = res.result()
137
+
138
+ self.status = TaskStatus.COMPLETED if res else TaskStatus.ERROR
139
+ return res
133
140
 
134
141
  @property
135
142
  def in_degrees(self) -> int:
@@ -238,7 +245,6 @@ class Edge(BaseModel):
238
245
  """
239
246
  Activates the edge to initiate task execution of the target node.
240
247
  """
241
-
242
248
  if not self.source or not self.target:
243
249
  Logger(verbose=True).log(level="warning", message="Cannot find source or target nodes. We'll return None.", color="yellow")
244
250
  return None
@@ -251,10 +257,11 @@ class Edge(BaseModel):
251
257
  import time
252
258
  time.sleep(self.lag)
253
259
 
254
- context = self.source.task.output.raw if self.data_transfer else None
260
+ context = self.source.task.output._to_context_prompt() if self.data_transfer else None
255
261
  res = self.target.handle_task_execution(context=context, response_format=response_format)
256
262
  return res
257
263
 
264
+
258
265
  @property
259
266
  def label(self):
260
267
  """Human friendly label for visualization."""
@@ -283,6 +290,14 @@ class Graph(ABC, BaseModel):
283
290
  else:
284
291
  return None
285
292
 
293
+ def _format_Graph(self) -> None:
294
+ """Formats dxGraph using edges and nodes."""
295
+ edges, nodes = [k for k in self.edges.keys()], [k for k in self.nodes.keys()]
296
+ if self.graph:
297
+ self.graph.update(edges=edges, nodes=nodes)
298
+ else:
299
+ self.graph = nx.Graph(directed=self.directed, edges=edges, nodes=nodes)
300
+
286
301
  def add_node(self, node: Node) -> None:
287
302
  if node.identifier in self.nodes.keys():
288
303
  return
@@ -333,13 +348,14 @@ class Graph(ABC, BaseModel):
333
348
  critical_edge = max(edges, key=lambda item: item['weight']) if edges else None
334
349
  return critical_edge.target if critical_edge else None
335
350
 
336
- def find_path(self, source: Optional[str] | None, target: str, weight: Optional[Any] | None) -> Any:
351
+ def find_path(self, target: str, source: Optional[str] = None, weight: Optional[Any] = None) -> Any:
337
352
  try:
353
+ self._format_Graph()
338
354
  return nx.shortest_path(self.graph, source=source, target=target, weight=weight)
339
- except nx.NetworkXNoPath:
355
+ except:
340
356
  return None
341
357
 
342
- def find_all_paths(self, source: str, target: str) -> List[Any]:
358
+ def find_all_paths(self, source: str, target: str) -> List[Any]:
343
359
  return list(nx.all_simple_paths(self.graph, source=source, target=target))
344
360
 
345
361
  def find_critical_path(self) -> tuple[List[Any], int, Dict[str, int]]:
@@ -377,8 +393,11 @@ class Graph(ABC, BaseModel):
377
393
 
378
394
 
379
395
  class TaskGraph(Graph):
396
+ _usage: Optional[UsageMetrics] = None
397
+
380
398
  id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
381
- should_reform: bool = Field(default=False)
399
+ should_reform: bool = False
400
+ reform_trigger_event: Optional[ReformTriggerEvent] = None
382
401
  outputs: Dict[str, TaskOutput] = Field(default_factory=dict, description="stores node identifier and TaskOutput")
383
402
  concl_template: Optional[Dict[str, Any] | Type[BaseModel]] = Field(default=None, description="stores final response format in Pydantic class or JSON dict")
384
403
  concl: Optional[TaskOutput] = Field(default=None, description="stores the final or latest conclusion of the entire task graph")
@@ -401,6 +420,40 @@ class TaskGraph(Graph):
401
420
  Logger().log(level="error", message=f"Failed to save the graph {str(self.id)}: {str(e)}", color="red")
402
421
 
403
422
 
423
+ def _handle_usage(self) -> None:
424
+ """Returns total tokens and latency spended for the graph execution."""
425
+ if not self.nodes:
426
+ return None
427
+
428
+ self._usage = self._usage if self._usage else UsageMetrics(id=self.id)
429
+
430
+ for node in self.nodes.values():
431
+ if node.task and node.task._usage:
432
+ self._usage.aggregate(metrics=node.task._usage)
433
+
434
+
435
+ def _handle_human_input(self) -> str | None:
436
+ """Handles input from human."""
437
+ request = None
438
+
439
+ print('Proceed? Y/n:')
440
+ x = input()
441
+
442
+ if x.lower() == "y":
443
+ Logger().log(message="Ok, proceeding to the next graph execution.", level="info", color="blue")
444
+
445
+ else:
446
+ request = input("Request?")
447
+ if request:
448
+ Logger().log(message=f"Ok. regenerating the graph based on your input: ', {request}", level="info", color="blue")
449
+ else:
450
+ Logger().log(message="Cannot recognize your request.", level="error", color="red")
451
+ self._usage = self._usage if self._usage else UsageMetrics(id=self.id)
452
+ self._usage.record_errors(type=ErrorType.HUMAN_INTERACTION)
453
+
454
+ return request
455
+
456
+
404
457
  def add_task(self, task: Node | Task) -> Node:
405
458
  """Convert `task` to a Node object and add it to G"""
406
459
 
@@ -432,10 +485,8 @@ class TaskGraph(Graph):
432
485
  """
433
486
  Add an edge that connect task 1 (source) and task 2 (target) using task_node.name as an identifier
434
487
  """
435
-
436
- if not edge_attributes:
437
- Logger().log(level="error", message="Edge attributes are missing.", color="red")
438
-
488
+ # if not edge_attributes:
489
+ # Logger().log(level="error", message="Edge attributes are missing.", color="red")
439
490
  edge = Edge()
440
491
  for k in Edge.model_fields.keys():
441
492
  v = edge_attributes.get(k, None)
@@ -443,7 +494,6 @@ class TaskGraph(Graph):
443
494
  setattr(edge, k, v)
444
495
  else:
445
496
  pass
446
-
447
497
  self.add_edge(source, target, edge)
448
498
 
449
499
 
@@ -554,15 +604,10 @@ class TaskGraph(Graph):
554
604
 
555
605
  # find a shortest path to each in-degree node of the node and see if dependency met.
556
606
  node = self._return_node_object(target)
557
- sources = node.in_degrees
558
- edge_status = []
607
+ edges = [v for k, v in self.edges.items() if v.target.identifier == node.identifier]
559
608
  res = None
560
609
 
561
- for item in sources:
562
- edge = self.find_path(source=item, target=target)
563
- edge_status.append(dict(edge=edge if edge else None, dep_met=edge.dependency_met() if edge else False))
564
-
565
- if len([item for item in edge_status if item["dep_met"] == True]) == len(sources):
610
+ if not edges or len([item for item in edges if item.dependency_met()]) == len(edges):
566
611
  res = node.handle_task_execution()
567
612
  self.outputs.update({ target: res })
568
613
 
@@ -598,7 +643,7 @@ class TaskGraph(Graph):
598
643
  res = node.handle_task_execution()
599
644
  self.outputs.update({ node.identifier: res })
600
645
  else:
601
- for k, edge in self.edges.items():
646
+ for edge in self.edges.values():
602
647
  res = edge.activate()
603
648
  node_identifier = edge.target.identifier
604
649
  self.outputs.update({ node_identifier: res })
@@ -614,9 +659,19 @@ class TaskGraph(Graph):
614
659
  node_identifier = edge.target.identifier
615
660
  self.outputs.update({ node_identifier: res })
616
661
 
662
+
663
+ if self.should_reform:
664
+ target = [k for k in self.outputs.keys()][-1] if self.outputs else self.find_start_nodes()[0].identifier if self.find_start_nodes() else None
665
+
666
+ if not target:
667
+ pass
668
+ else:
669
+ res, _ = self.handle_reform(target=target)
670
+
617
671
  self.concl = res
618
672
  self.concl_template = self.concl_template if self.concl_template else res.pydantic.__class__ if res.pydantic else None
619
673
  # last_task_output = [v for v in self.outputs.values()][len([v for v in self.outputs.values()]) - 1] if [v for v in self.outputs.values()] else None
674
+ self._handle_usage()
620
675
  return res, self.outputs
621
676
 
622
677
 
@@ -639,13 +694,18 @@ class TaskGraph(Graph):
639
694
  return eval
640
695
 
641
696
 
642
- @property
643
- def usage(self) -> Tuple[int, float]:
644
- """Returns aggregate number of consumed tokens and job latency in ms during the activation"""
645
-
646
- tokens, latency = 0, 0
647
- for v in self.outputs.values():
648
- tokens += v._tokens
649
- latency += v.latency
650
-
651
- return tokens, latency
697
+ def handle_reform(self, target: str = None) -> Self:
698
+ task_description = "Improve the given output: "
699
+ if target:
700
+ output = self.outputs[target].raw if self.outputs and target in self.outputs else None
701
+ if output:
702
+ task_description += str(output)
703
+
704
+ if self.reform_trigger_event == ReformTriggerEvent.USER_INPUT:
705
+ request = self._handle_human_input()
706
+ task_description += f"You MUST follow the instruction: {request}"
707
+
708
+ new_node = Node(task=Task(description=task_description))
709
+ self.add_node(node=new_node)
710
+ self.add_dependency(source=target, target=new_node.identifier)
711
+ return self.activate(target=new_node.identifier)
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.2.4.1
4
- Summary: A Python framework for autonomous agent networks that handle task automation with multi-step reasoning.
3
+ Version: 1.2.4.3
4
+ Summary: Autonomous agent networks for task automation with multi-step reasoning.
5
5
  Author-email: Kuriko Iwai <kuriko@versi0n.io>
6
6
  License: MIT License
7
7
 
@@ -29,7 +29,7 @@ Project-URL: Homepage, https://versi0n.io
29
29
  Project-URL: Documentation, https://docs.versi0n.io
30
30
  Project-URL: Repository, https://github.com/versionHQ/multi-agent-system
31
31
  Project-URL: Issues, https://github.com/versionHQ/multi-agent-system/issues
32
- Keywords: orchestration framework,orchestration,ai agent,multi-agent system,RAG,agent,agentic orchestration,llm
32
+ Keywords: autonomic agent networks,deep agent,agentic orchestration framework
33
33
  Classifier: Programming Language :: Python
34
34
  Classifier: Programming Language :: Python :: 3
35
35
  Classifier: Programming Language :: Python :: 3.11
@@ -47,12 +47,9 @@ License-File: LICENSE
47
47
  Requires-Dist: regex==2024.11.6
48
48
  Requires-Dist: requests>=2.32.3
49
49
  Requires-Dist: pydantic>=2.10.6
50
- Requires-Dist: werkzeug>=3.1.3
51
50
  Requires-Dist: typing>=0.0.0
52
51
  Requires-Dist: json-repair>=0.0.0
53
52
  Requires-Dist: litellm>=1.55.8
54
- Requires-Dist: openai>=1.64.0
55
- Requires-Dist: composio-openai>=0.6.9
56
53
  Requires-Dist: composio>=0.1.0
57
54
  Requires-Dist: setuptools>=75.6.0
58
55
  Requires-Dist: wheel>=0.45.1
@@ -60,10 +57,8 @@ Requires-Dist: python-dotenv>=1.0.0
60
57
  Requires-Dist: appdirs>=1.4.4
61
58
  Requires-Dist: langchain>=0.3.14
62
59
  Requires-Dist: langchain-openai>=0.2.14
63
- Requires-Dist: composio-langchain>=0.6.12
64
60
  Requires-Dist: chromadb>=0.6.3
65
61
  Requires-Dist: wheel>=0.45.1
66
- Requires-Dist: envoy>=0.0.3
67
62
  Requires-Dist: composio-core==0.7.0
68
63
  Requires-Dist: networkx>=3.4.2
69
64
  Requires-Dist: matplotlib>=3.10.0
@@ -1,23 +1,25 @@
1
- versionhq/__init__.py,sha256=8lc6ZRR-zxO1Bmqh3OsFM1GD_SDxufX0ebdyTsMrMsE,2980
2
- versionhq/_prompt/model.py,sha256=U2Uba84nVljMN4U6ALGGhVPr1aM4C9AUDTo-_WzTCYs,5205
3
- versionhq/_utils/__init__.py,sha256=llXOcGFlR9YF5iMI5uFb4twvM9wo-vmoMw8y1KzQVVc,233
1
+ versionhq/__init__.py,sha256=F0IUNu8UG7KfohEotN5MykEfCklxJjXe4c5kcaVIwlE,3026
2
+ versionhq/_prompt/auto_feedback.py,sha256=iIa3ReiFqs-JA2Q4Y_VnLV-DbXPelEVSMHTw3tICVTE,3892
3
+ versionhq/_prompt/constants.py,sha256=DOwUFnVVObEFqgnaMCDnW8fnw1oPMgS8JAqOiTuqleI,932
4
+ versionhq/_prompt/model.py,sha256=GQPaC_Vj1wQ69ZHlzXWdtdif8UeF6WK1jN3JrFEcCt0,8662
5
+ versionhq/_utils/__init__.py,sha256=UggL2r-idlWDh0cIPFLyJ7AvO17NLzhjheW4IBFLBj4,300
4
6
  versionhq/_utils/i18n.py,sha256=TwA_PnYfDLA6VqlUDPuybdV9lgi3Frh_ASsb_X8jJo8,1483
5
7
  versionhq/_utils/is_valid_url.py,sha256=m8Mswvb-90FJtx1Heq6hPFDbwGgrv_R3wSbZQmEPM9Q,379
6
8
  versionhq/_utils/llm_as_a_judge.py,sha256=RM0oYfoeanuUyUL3Ewl6_8Xn1F5Axd285UMH46kxG1I,2378
7
9
  versionhq/_utils/logger.py,sha256=iHxGjm3BvUo5dHKLU88_pc0Z45wzSHOjyJGQkb7OADk,3255
8
10
  versionhq/_utils/process_config.py,sha256=YTGY_erW335RfceQfzS18YAqq-AAb-iSvKSjN7noD2E,782
9
- versionhq/_utils/usage_metrics.py,sha256=xgYGRW3OTuK9EJyi3QYJeYcJl7dL27olcWaLo_7B3JE,2246
11
+ versionhq/_utils/usage_metrics.py,sha256=zaoH6xjWX69UrQJmViBiX3sEUpnwSoHaapCPfWU2oM8,2632
10
12
  versionhq/_utils/vars.py,sha256=bZ5Dx_bFKlt3hi4-NNGXqdk7B23If_WaTIju2fiTyPQ,57
11
13
  versionhq/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
14
  versionhq/agent/inhouse_agents.py,sha256=BPkvEyMH8VnZWsMeCwsGplDT_kLwlIejeRcr-6ItGqQ,2637
13
- versionhq/agent/model.py,sha256=mXc_sYbrH_-dbuMnlxMArCCjxmP36MMaSWM-1lS5rKI,26600
15
+ versionhq/agent/model.py,sha256=duB4qQDh3RIQZ6YyZovvBKUBdzMtgCFiel0qC0BGbzQ,24691
14
16
  versionhq/agent/parser.py,sha256=riG0dkdQCxH7uJ0AbdVdg7WvL0BXhUgJht0VtQvxJBc,4082
15
17
  versionhq/agent/rpm_controller.py,sha256=grezIxyBci_lDlwAlgWFRyR5KOocXeOhYkgN02dNFNE,2360
16
18
  versionhq/agent/TEMPLATES/Backstory.py,sha256=dkfuATUQ2g2WoUKkmgAIch-RB--bektGoQaUlsDOn0g,529
17
19
  versionhq/agent/TEMPLATES/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
20
  versionhq/agent_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- versionhq/agent_network/formation.py,sha256=8lFOxp9f9rG3UdXiyDbDbrtHG9nNO2lkAOLpUSQXjyo,8067
20
- versionhq/agent_network/model.py,sha256=-vLBqPCtfLxTf17toJkE7Gkxg1SwlrA-Frf2Pc_uB50,16021
21
+ versionhq/agent_network/formation.py,sha256=XiGyjqsquTcKqyq6r2JR506wEH0uuD8HyBvWNdvz1Fg,7505
22
+ versionhq/agent_network/model.py,sha256=65y4HTltfvgOuHnSUwDTydtt1qkq1xVk-AxF1ws1J9M,15899
21
23
  versionhq/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
24
  versionhq/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
25
  versionhq/clients/customer/__init__.py,sha256=-YXh1FQfvpfLacK8SUC7bD7Wx_eIEi4yrkCC_cUasFg,217
@@ -35,7 +37,7 @@ versionhq/knowledge/source_docling.py,sha256=XpavmLvh4dLcuTikj8MCE9KG52oQMafy7_w
35
37
  versionhq/knowledge/storage.py,sha256=Kd-4r6aWM5EDaoXrzKXbgi1hY6tysSQARPGXM95qMmU,8266
36
38
  versionhq/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
39
  versionhq/llm/llm_vars.py,sha256=qSG-_pYeWksdMmwASXpjQqf97fMovsY4lNTSCHQF88k,5694
38
- versionhq/llm/model.py,sha256=P4J6ZU0vY5HU7XHLelz7oznPmeEElHPFsAo-2Vd8DQ0,17255
40
+ versionhq/llm/model.py,sha256=Hc_fYYmhM_HuYs4dBtZlHwGqVtqnEC_rvGXD1o6RB4A,17186
39
41
  versionhq/memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
42
  versionhq/memory/contextual_memory.py,sha256=QEMVvHuEXxY7M6-12S8HhyFKf108KfX8Zzt7paPW048,3882
41
43
  versionhq/memory/model.py,sha256=VQR1229t7GQPMItlGAHLtJrb6LrZfSoRA1DRW4z0SOU,8234
@@ -44,18 +46,18 @@ versionhq/storage/base.py,sha256=p-Jas0fXQan_qotnRD6seQxrT2lj-uw9-SmHQhdppcs,355
44
46
  versionhq/storage/ltm_sqlite_storage.py,sha256=LeJE4ZPUWjyY1E5nNCHoKujTHFDR2BO_LAMvAOX-WHg,3957
45
47
  versionhq/storage/mem0_storage.py,sha256=ZY8MELBWaINRv9YuRW5MxH7dj2cII-L0i3xSD6o1-2M,3781
46
48
  versionhq/storage/rag_storage.py,sha256=bS2eE874obarYl-4hT6ZWYWTRsqtfuGpKgKzERmM6Uo,7433
47
- versionhq/storage/task_output_storage.py,sha256=M8vInLJ5idGAq17w1juHKXtyPyF-B-rK_P8UcqD-Px8,5357
49
+ versionhq/storage/task_output_storage.py,sha256=nkBNmBbrQeEgds3lAyKl4ugDWLtWRoCQUO6KiOmCIMU,5362
48
50
  versionhq/storage/utils.py,sha256=r5ghA_ktdR2IuzlzKqZYCjsNxztEMzyhWLneA4cFuWY,748
49
51
  versionhq/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
52
  versionhq/task/evaluation.py,sha256=qQSA5ZWTWA3he54ystsYpTKXJWv68gBL6DCq8ZW1bl8,3813
51
53
  versionhq/task/formatter.py,sha256=N8Kmk9vtrMtBdgJ8J7RmlKNMdZWSmV8O1bDexmCWgU0,643
52
- versionhq/task/model.py,sha256=YawjfqUwmOynoFlO_3L7qVbK8PmF-V6dUA-Ox_55kpU,31415
54
+ versionhq/task/model.py,sha256=ODcyS_lTT0NoVRA3MSuczbOVp03gpwmb5i48nVOe8jo,29069
53
55
  versionhq/task/structured_response.py,sha256=tqOHpch8CVmMj0aZXjdDWtPNcVmBW8DVZnBvPBwS4PM,5053
54
56
  versionhq/task/TEMPLATES/Description.py,sha256=hKhpbz0ztbkUMXz9KiL-P40fis9OB5ICOdL9jCtgAhU,864
55
57
  versionhq/task_graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
58
  versionhq/task_graph/colors.py,sha256=naJCx4Vho4iuJtbW8USUXb-M5uYvd5ds2p8qbjUfRus,669
57
- versionhq/task_graph/draft.py,sha256=K14J90Heii2JiCOsQsz1uE0NWout-lr8wpJbk-KEYfI,5099
58
- versionhq/task_graph/model.py,sha256=3DzZXP4SSJP3xdgZfkJDgFXUjQ05CSYFoisShfmSdcs,26582
59
+ versionhq/task_graph/draft.py,sha256=l8nRV39Rh5lLLQ_hHgbHyVLpoBqAzWk9QIXNaGiEbeE,4921
60
+ versionhq/task_graph/model.py,sha256=bUptIXKe8fR9hbZRo81ns_nUMWYklWgTBgtW_4PS4bU,29214
59
61
  versionhq/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
62
  versionhq/tool/cache_handler.py,sha256=iL8FH7X0G-cdT0uhJwzuhLDaadTXOdfybZcDy151-es,1085
61
63
  versionhq/tool/composio_tool.py,sha256=IATfsEnF_1RPJyGtPBmAtEJh5XPcgDHpyG3SUR461Og,8572
@@ -64,8 +66,8 @@ versionhq/tool/decorator.py,sha256=C4ZM7Xi2gwtEMaSeRo-geo_g_MAkY77WkSLkAuY0AyI,1
64
66
  versionhq/tool/model.py,sha256=ve9C4WyiRjQigOU0hRWVxtSUWAQNntlmeW-_DL0_lJY,12328
65
67
  versionhq/tool/rag_tool.py,sha256=dW5o-83V4bMFFJEj3PUm7XjblwrYJGmZVBlCpPj6CeM,3852
66
68
  versionhq/tool/tool_handler.py,sha256=2m41K8qo5bGCCbwMFferEjT-XZ-mE9F0mDUOBkgivOI,1416
67
- versionhq-1.2.4.1.dist-info/LICENSE,sha256=cRoGGdM73IiDs6nDWKqPlgSv7aR4n-qBXYnJlCMHCeE,1082
68
- versionhq-1.2.4.1.dist-info/METADATA,sha256=v3Va4NIWCPW_pdVWCSljRqCaDcmXjg_xV3mwybmszrA,21380
69
- versionhq-1.2.4.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
70
- versionhq-1.2.4.1.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
71
- versionhq-1.2.4.1.dist-info/RECORD,,
69
+ versionhq-1.2.4.3.dist-info/LICENSE,sha256=cRoGGdM73IiDs6nDWKqPlgSv7aR4n-qBXYnJlCMHCeE,1082
70
+ versionhq-1.2.4.3.dist-info/METADATA,sha256=4q8mpXgq7TcaXjvX26JIE0FsQ78hgJuuEPBhefJiknI,21146
71
+ versionhq-1.2.4.3.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
72
+ versionhq-1.2.4.3.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
73
+ versionhq-1.2.4.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5