versionhq 1.2.3.8__py3-none-any.whl → 1.2.4.2__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 +3 -2
- versionhq/_prompt/auto_feedback.py +103 -0
- versionhq/_prompt/constants.py +30 -0
- versionhq/_prompt/model.py +218 -0
- versionhq/_utils/__init__.py +1 -0
- versionhq/_utils/is_valid_url.py +15 -0
- versionhq/agent/model.py +33 -67
- versionhq/agent_network/formation.py +18 -10
- versionhq/agent_network/model.py +2 -6
- versionhq/knowledge/source_docling.py +3 -19
- versionhq/llm/model.py +8 -12
- versionhq/task/evaluation.py +1 -1
- versionhq/task/model.py +142 -142
- versionhq/task/structured_response.py +3 -1
- versionhq/task_graph/draft.py +11 -19
- versionhq/task_graph/model.py +90 -34
- {versionhq-1.2.3.8.dist-info → versionhq-1.2.4.2.dist-info}/METADATA +11 -16
- {versionhq-1.2.3.8.dist-info → versionhq-1.2.4.2.dist-info}/RECORD +21 -17
- {versionhq-1.2.3.8.dist-info → versionhq-1.2.4.2.dist-info}/WHEEL +1 -1
- {versionhq-1.2.3.8.dist-info → versionhq-1.2.4.2.dist-info}/LICENSE +0 -0
- {versionhq-1.2.3.8.dist-info → versionhq-1.2.4.2.dist-info}/top_level.txt +0 -0
@@ -38,7 +38,9 @@ class StructuredObject:
|
|
38
38
|
description = self.field.description if hasattr(self.field, "description") and self.field.description is not None else ""
|
39
39
|
field_name = self.field.__name__ if hasattr(self.field, "__name__") and self.field.__name__ else self.title
|
40
40
|
self.properties.update({ field_name : { "type": SchemaType(self.field.annotation.__args__).convert() }})
|
41
|
-
|
41
|
+
|
42
|
+
if field_name not in self.required:
|
43
|
+
self.required.append(field_name)
|
42
44
|
|
43
45
|
return {
|
44
46
|
self.title: {
|
versionhq/task_graph/draft.py
CHANGED
@@ -10,7 +10,7 @@ sys.modules['pydantic.main'].ModelMetaclass = ModelMetaclass
|
|
10
10
|
|
11
11
|
from versionhq.agent.model import Agent
|
12
12
|
from versionhq.task.model import ResponseField
|
13
|
-
from versionhq.task_graph.model import TaskGraph, Task, DependencyType, Node
|
13
|
+
from versionhq.task_graph.model import TaskGraph, Task, DependencyType, Node, ReformTriggerEvent
|
14
14
|
from versionhq._utils.logger import Logger
|
15
15
|
|
16
16
|
|
@@ -33,12 +33,11 @@ def workflow(final_output: Type[BaseModel], context: Any = None, human: bool = F
|
|
33
33
|
|
34
34
|
dep_type_prompt = ", ".join([k for k in DependencyType._member_map_.keys()])
|
35
35
|
|
36
|
-
|
37
|
-
role="vhq-
|
36
|
+
vhq_graph_expert = Agent(
|
37
|
+
role="vhq-Graph Expert",
|
38
38
|
goal="design the most resource-efficient workflow graph to achieve the given goal",
|
39
39
|
knowledge_sources=[
|
40
40
|
"https://en.wikipedia.org/wiki/Graph_theory",
|
41
|
-
# "https://www.geeksforgeeks.org/graph-data-structure-and-algorithms/?ref=lbp",
|
42
41
|
"https://www.geeksforgeeks.org/graph-and-its-representations/",
|
43
42
|
", ".join([k for k in DependencyType._member_map_.keys()]),
|
44
43
|
],
|
@@ -60,12 +59,16 @@ def workflow(final_output: Type[BaseModel], context: Any = None, human: bool = F
|
|
60
59
|
])
|
61
60
|
]
|
62
61
|
)
|
63
|
-
res = task.execute(agent=
|
62
|
+
res = task.execute(agent=vhq_graph_expert, context=[context_prompt, context])
|
64
63
|
|
65
64
|
if not res:
|
66
65
|
return None
|
67
66
|
|
68
|
-
task_items = res.json_dict["tasks"]
|
67
|
+
task_items = res.json_dict["tasks"] if "tasks" in res.json_dict else []
|
68
|
+
|
69
|
+
if not task_items:
|
70
|
+
return None
|
71
|
+
|
69
72
|
tasks, nodes = [], []
|
70
73
|
|
71
74
|
for item in task_items:
|
@@ -78,7 +81,8 @@ def workflow(final_output: Type[BaseModel], context: Any = None, human: bool = F
|
|
78
81
|
nodes={node.identifier: node for node in nodes},
|
79
82
|
concl_format=final_output,
|
80
83
|
concl=None,
|
81
|
-
should_reform=
|
84
|
+
should_reform=human,
|
85
|
+
reform_trigger_event=ReformTriggerEvent.USER_INPUT if human else None,
|
82
86
|
)
|
83
87
|
|
84
88
|
for res in task_items:
|
@@ -92,18 +96,6 @@ def workflow(final_output: Type[BaseModel], context: Any = None, human: bool = F
|
|
92
96
|
task_graph.add_dependency(
|
93
97
|
source=source.identifier, target=target.identifier, dependency_type=dependency_type)
|
94
98
|
|
95
|
-
|
96
99
|
task_graph.visualize()
|
97
100
|
|
98
|
-
if human:
|
99
|
-
print('Proceed? Y/n:')
|
100
|
-
x = input()
|
101
|
-
|
102
|
-
if x.lower() == "y":
|
103
|
-
print("ok. generating agent network")
|
104
|
-
|
105
|
-
else:
|
106
|
-
request = input("request?")
|
107
|
-
print('ok. regenerating the graph based on your input: ', request)
|
108
|
-
|
109
101
|
return task_graph
|
versionhq/task_graph/model.py
CHANGED
@@ -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
|
18
|
+
from versionhq._utils import Logger
|
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[
|
100
|
-
out_degree_nodes: List[
|
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
|
-
|
125
|
-
|
126
|
-
res = self.task.execute(agent=agent, context=context)
|
126
|
+
if self.status == TaskStatus.COMPLETED:
|
127
|
+
return self.task.output
|
127
128
|
|
128
|
-
|
129
|
-
|
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
|
-
|
132
|
-
|
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.
|
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]
|
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
|
355
|
+
except:
|
340
356
|
return None
|
341
357
|
|
342
|
-
def find_all_paths(self,
|
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]]:
|
@@ -378,7 +394,8 @@ class Graph(ABC, BaseModel):
|
|
378
394
|
|
379
395
|
class TaskGraph(Graph):
|
380
396
|
id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
|
381
|
-
should_reform: bool =
|
397
|
+
should_reform: bool = False
|
398
|
+
reform_trigger_event: Optional[ReformTriggerEvent] = None
|
382
399
|
outputs: Dict[str, TaskOutput] = Field(default_factory=dict, description="stores node identifier and TaskOutput")
|
383
400
|
concl_template: Optional[Dict[str, Any] | Type[BaseModel]] = Field(default=None, description="stores final response format in Pydantic class or JSON dict")
|
384
401
|
concl: Optional[TaskOutput] = Field(default=None, description="stores the final or latest conclusion of the entire task graph")
|
@@ -432,10 +449,8 @@ class TaskGraph(Graph):
|
|
432
449
|
"""
|
433
450
|
Add an edge that connect task 1 (source) and task 2 (target) using task_node.name as an identifier
|
434
451
|
"""
|
435
|
-
|
436
|
-
|
437
|
-
Logger().log(level="error", message="Edge attributes are missing.", color="red")
|
438
|
-
|
452
|
+
# if not edge_attributes:
|
453
|
+
# Logger().log(level="error", message="Edge attributes are missing.", color="red")
|
439
454
|
edge = Edge()
|
440
455
|
for k in Edge.model_fields.keys():
|
441
456
|
v = edge_attributes.get(k, None)
|
@@ -443,7 +458,6 @@ class TaskGraph(Graph):
|
|
443
458
|
setattr(edge, k, v)
|
444
459
|
else:
|
445
460
|
pass
|
446
|
-
|
447
461
|
self.add_edge(source, target, edge)
|
448
462
|
|
449
463
|
|
@@ -554,15 +568,10 @@ class TaskGraph(Graph):
|
|
554
568
|
|
555
569
|
# find a shortest path to each in-degree node of the node and see if dependency met.
|
556
570
|
node = self._return_node_object(target)
|
557
|
-
|
558
|
-
edge_status = []
|
571
|
+
edges = [v for k, v in self.edges.items() if v.target.identifier == node.identifier]
|
559
572
|
res = None
|
560
573
|
|
561
|
-
for item in
|
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):
|
574
|
+
if not edges or len([item for item in edges if item.dependency_met()]) == len(edges):
|
566
575
|
res = node.handle_task_execution()
|
567
576
|
self.outputs.update({ target: res })
|
568
577
|
|
@@ -598,7 +607,7 @@ class TaskGraph(Graph):
|
|
598
607
|
res = node.handle_task_execution()
|
599
608
|
self.outputs.update({ node.identifier: res })
|
600
609
|
else:
|
601
|
-
for
|
610
|
+
for edge in self.edges.values():
|
602
611
|
res = edge.activate()
|
603
612
|
node_identifier = edge.target.identifier
|
604
613
|
self.outputs.update({ node_identifier: res })
|
@@ -614,6 +623,15 @@ class TaskGraph(Graph):
|
|
614
623
|
node_identifier = edge.target.identifier
|
615
624
|
self.outputs.update({ node_identifier: res })
|
616
625
|
|
626
|
+
|
627
|
+
if self.should_reform:
|
628
|
+
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
|
629
|
+
|
630
|
+
if not target:
|
631
|
+
pass
|
632
|
+
else:
|
633
|
+
res, _ = self.handle_reform(target=target)
|
634
|
+
|
617
635
|
self.concl = res
|
618
636
|
self.concl_template = self.concl_template if self.concl_template else res.pydantic.__class__ if res.pydantic else None
|
619
637
|
# 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
|
@@ -639,6 +657,44 @@ class TaskGraph(Graph):
|
|
639
657
|
return eval
|
640
658
|
|
641
659
|
|
660
|
+
def _handle_human_input(self) -> str | None:
|
661
|
+
"""Handles input from human."""
|
662
|
+
request = None
|
663
|
+
|
664
|
+
print('Proceed? Y/n:')
|
665
|
+
x = input()
|
666
|
+
|
667
|
+
if x.lower() == "y":
|
668
|
+
Logger().log(message="Ok, proceeding to the next graph execution.", level="info", color="blue")
|
669
|
+
|
670
|
+
else:
|
671
|
+
request = input("Request?")
|
672
|
+
|
673
|
+
if request:
|
674
|
+
Logger().log(message=f"Ok. regenerating the graph based on your input: ', {request}", level="info", color="blue")
|
675
|
+
else:
|
676
|
+
Logger().log(message="Cannot recognize your request.", level="error", color="red")
|
677
|
+
|
678
|
+
return request
|
679
|
+
|
680
|
+
|
681
|
+
def handle_reform(self, target: str = None) -> Self:
|
682
|
+
task_description = "Improve the given output: "
|
683
|
+
if target:
|
684
|
+
output = self.outputs[target].raw if self.outputs and target in self.outputs else None
|
685
|
+
if output:
|
686
|
+
task_description += str(output)
|
687
|
+
|
688
|
+
if self.reform_trigger_event == ReformTriggerEvent.USER_INPUT:
|
689
|
+
request = self._handle_human_input()
|
690
|
+
task_description += f"You MUST follow the instruction: {request}"
|
691
|
+
|
692
|
+
new_node = Node(task=Task(description=task_description))
|
693
|
+
self.add_node(node=new_node)
|
694
|
+
self.add_dependency(source=target, target=new_node.identifier)
|
695
|
+
return self.activate(target=new_node.identifier)
|
696
|
+
|
697
|
+
|
642
698
|
@property
|
643
699
|
def usage(self) -> Tuple[int, float]:
|
644
700
|
"""Returns aggregate number of consumed tokens and job latency in ms during the activation"""
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: versionhq
|
3
|
-
Version: 1.2.
|
4
|
-
Summary:
|
3
|
+
Version: 1.2.4.2
|
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:
|
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
|
@@ -88,15 +83,15 @@ Requires-Dist: torchvision>=0.21.0; extra == "torch"
|
|
88
83
|
|
89
84
|
# Overview
|
90
85
|
|
91
|
-
[](https://clickpy.clickhouse.com/dashboard/versionhq)
|
92
87
|

|
93
88
|
[](https://github.com/versionHQ/multi-agent-system/actions/workflows/publish.yml)
|
94
|
-

|
95
90
|

|
96
91
|

|
97
92
|
|
98
93
|
|
99
|
-
|
94
|
+
A Python framework for autonomous agent networks that handle task automation with multi-step reasoning.
|
100
95
|
|
101
96
|
**Visit:**
|
102
97
|
|
@@ -154,11 +149,11 @@ Agents adapt their formation based on task complexity.
|
|
154
149
|
You can specify a desired formation or allow the agents to determine it autonomously (default).
|
155
150
|
|
156
151
|
|
157
|
-
|
|
158
|
-
| :---
|
159
|
-
| **Formation**
|
160
|
-
| **Usage**
|
161
|
-
| **Use case**
|
152
|
+
| | **Solo Agent** | **Supervising** | **Squad** | **Random** |
|
153
|
+
| :--- | :--- | :--- | :--- | :--- |
|
154
|
+
| **Formation** | <img src="https://res.cloudinary.com/dfeirxlea/image/upload/v1738818211/pj_m_agents/rbgxttfoeqqis1ettlfz.png" alt="solo" width="200"> | <img src="https://res.cloudinary.com/dfeirxlea/image/upload/v1738818211/pj_m_agents/zhungor3elxzer5dum10.png" alt="solo" width="200"> | <img src="https://res.cloudinary.com/dfeirxlea/image/upload/v1738818211/pj_m_agents/dnusl7iy7kiwkxwlpmg8.png" alt="solo" width="200"> | <img src="https://res.cloudinary.com/dfeirxlea/image/upload/v1738818211/pj_m_agents/sndpczatfzbrosxz9ama.png" alt="solo" width="200"> |
|
155
|
+
| **Usage** | <ul><li>A single agent with tools, knowledge, and memory.</li><li>When self-learning mode is on - it will turn into **Random** formation.</li></ul> | <ul><li>Leader agent gives directions, while sharing its knowledge and memory.</li><li>Subordinates can be solo agents or networks.</li></ul> | <ul><li>Share tasks, knowledge, and memory among network members.</li></ul> | <ul><li>A single agent handles tasks, asking help from other agents without sharing its memory or knowledge.</li></ul> |
|
156
|
+
| **Use case** | An email agent drafts promo message for the given audience. | The leader agent strategizes an outbound campaign plan and assigns components such as media mix or message creation to subordinate agents. | An email agent and social media agent share the product knowledge and deploy multi-channel outbound campaign. | 1. An email agent drafts promo message for the given audience, asking insights on tones from other email agents which oversee other clusters. 2. An agent calls the external agent to deploy the campaign. |
|
162
157
|
|
163
158
|
<hr />
|
164
159
|
|
@@ -1,6 +1,10 @@
|
|
1
|
-
versionhq/__init__.py,sha256
|
2
|
-
versionhq/
|
1
|
+
versionhq/__init__.py,sha256=m36KgpiM94kUCZJm-JA7gPWjb7gNgMHHXUAbxzKlIOs,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=llXOcGFlR9YF5iMI5uFb4twvM9wo-vmoMw8y1KzQVVc,233
|
3
6
|
versionhq/_utils/i18n.py,sha256=TwA_PnYfDLA6VqlUDPuybdV9lgi3Frh_ASsb_X8jJo8,1483
|
7
|
+
versionhq/_utils/is_valid_url.py,sha256=m8Mswvb-90FJtx1Heq6hPFDbwGgrv_R3wSbZQmEPM9Q,379
|
4
8
|
versionhq/_utils/llm_as_a_judge.py,sha256=RM0oYfoeanuUyUL3Ewl6_8Xn1F5Axd285UMH46kxG1I,2378
|
5
9
|
versionhq/_utils/logger.py,sha256=iHxGjm3BvUo5dHKLU88_pc0Z45wzSHOjyJGQkb7OADk,3255
|
6
10
|
versionhq/_utils/process_config.py,sha256=YTGY_erW335RfceQfzS18YAqq-AAb-iSvKSjN7noD2E,782
|
@@ -8,14 +12,14 @@ versionhq/_utils/usage_metrics.py,sha256=xgYGRW3OTuK9EJyi3QYJeYcJl7dL27olcWaLo_7
|
|
8
12
|
versionhq/_utils/vars.py,sha256=bZ5Dx_bFKlt3hi4-NNGXqdk7B23If_WaTIju2fiTyPQ,57
|
9
13
|
versionhq/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
14
|
versionhq/agent/inhouse_agents.py,sha256=BPkvEyMH8VnZWsMeCwsGplDT_kLwlIejeRcr-6ItGqQ,2637
|
11
|
-
versionhq/agent/model.py,sha256=
|
15
|
+
versionhq/agent/model.py,sha256=Zom5G0ubq4TWGWF6PK631-6puCjcdHYKj0R355GS9T8,24480
|
12
16
|
versionhq/agent/parser.py,sha256=riG0dkdQCxH7uJ0AbdVdg7WvL0BXhUgJht0VtQvxJBc,4082
|
13
17
|
versionhq/agent/rpm_controller.py,sha256=grezIxyBci_lDlwAlgWFRyR5KOocXeOhYkgN02dNFNE,2360
|
14
18
|
versionhq/agent/TEMPLATES/Backstory.py,sha256=dkfuATUQ2g2WoUKkmgAIch-RB--bektGoQaUlsDOn0g,529
|
15
19
|
versionhq/agent/TEMPLATES/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
20
|
versionhq/agent_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
versionhq/agent_network/formation.py,sha256=
|
18
|
-
versionhq/agent_network/model.py,sha256
|
21
|
+
versionhq/agent_network/formation.py,sha256=WkAbmE2-Oqw8KWDcqqHU_s98QzGJWNQ_YCAls6ZuQbg,8260
|
22
|
+
versionhq/agent_network/model.py,sha256=-vLBqPCtfLxTf17toJkE7Gkxg1SwlrA-Frf2Pc_uB50,16021
|
19
23
|
versionhq/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
24
|
versionhq/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
25
|
versionhq/clients/customer/__init__.py,sha256=-YXh1FQfvpfLacK8SUC7bD7Wx_eIEi4yrkCC_cUasFg,217
|
@@ -29,11 +33,11 @@ versionhq/knowledge/_utils.py,sha256=YWRF8U533cfZes_gZqUvdj-K24MD2ri1R0gjc_aPYyc
|
|
29
33
|
versionhq/knowledge/embedding.py,sha256=KfHc__1THxb5jrg1EMrF-v944RDuIr2hE0l-MtM3Bp0,6826
|
30
34
|
versionhq/knowledge/model.py,sha256=ixH8n5kLtJEp1nPAFYA0piYm-n0nnFDtWFp0r9YEVAs,1787
|
31
35
|
versionhq/knowledge/source.py,sha256=-hEUPtJUHHMx4rUKtiHl19J8xAMw-WVBw34zwa2jZ08,13630
|
32
|
-
versionhq/knowledge/source_docling.py,sha256=
|
36
|
+
versionhq/knowledge/source_docling.py,sha256=XpavmLvh4dLcuTikj8MCE9KG52oQMafy7_wBneliMK0,4994
|
33
37
|
versionhq/knowledge/storage.py,sha256=Kd-4r6aWM5EDaoXrzKXbgi1hY6tysSQARPGXM95qMmU,8266
|
34
38
|
versionhq/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
39
|
versionhq/llm/llm_vars.py,sha256=qSG-_pYeWksdMmwASXpjQqf97fMovsY4lNTSCHQF88k,5694
|
36
|
-
versionhq/llm/model.py,sha256=
|
40
|
+
versionhq/llm/model.py,sha256=P4J6ZU0vY5HU7XHLelz7oznPmeEElHPFsAo-2Vd8DQ0,17255
|
37
41
|
versionhq/memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
42
|
versionhq/memory/contextual_memory.py,sha256=QEMVvHuEXxY7M6-12S8HhyFKf108KfX8Zzt7paPW048,3882
|
39
43
|
versionhq/memory/model.py,sha256=VQR1229t7GQPMItlGAHLtJrb6LrZfSoRA1DRW4z0SOU,8234
|
@@ -45,15 +49,15 @@ versionhq/storage/rag_storage.py,sha256=bS2eE874obarYl-4hT6ZWYWTRsqtfuGpKgKzERmM
|
|
45
49
|
versionhq/storage/task_output_storage.py,sha256=M8vInLJ5idGAq17w1juHKXtyPyF-B-rK_P8UcqD-Px8,5357
|
46
50
|
versionhq/storage/utils.py,sha256=r5ghA_ktdR2IuzlzKqZYCjsNxztEMzyhWLneA4cFuWY,748
|
47
51
|
versionhq/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
-
versionhq/task/evaluation.py,sha256=
|
52
|
+
versionhq/task/evaluation.py,sha256=qQSA5ZWTWA3he54ystsYpTKXJWv68gBL6DCq8ZW1bl8,3813
|
49
53
|
versionhq/task/formatter.py,sha256=N8Kmk9vtrMtBdgJ8J7RmlKNMdZWSmV8O1bDexmCWgU0,643
|
50
|
-
versionhq/task/model.py,sha256=
|
51
|
-
versionhq/task/structured_response.py,sha256=
|
54
|
+
versionhq/task/model.py,sha256=YsuxbohcXLwE1qB8-lPnl_sFWQJ7CPqKDbYbf8CeZww,28879
|
55
|
+
versionhq/task/structured_response.py,sha256=tqOHpch8CVmMj0aZXjdDWtPNcVmBW8DVZnBvPBwS4PM,5053
|
52
56
|
versionhq/task/TEMPLATES/Description.py,sha256=hKhpbz0ztbkUMXz9KiL-P40fis9OB5ICOdL9jCtgAhU,864
|
53
57
|
versionhq/task_graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
58
|
versionhq/task_graph/colors.py,sha256=naJCx4Vho4iuJtbW8USUXb-M5uYvd5ds2p8qbjUfRus,669
|
55
|
-
versionhq/task_graph/draft.py,sha256=
|
56
|
-
versionhq/task_graph/model.py,sha256=
|
59
|
+
versionhq/task_graph/draft.py,sha256=0zDRx1-PXIwuB_RkdKQTHgqjm-5VrJHhljBIlYRX6EM,4919
|
60
|
+
versionhq/task_graph/model.py,sha256=T7-Rj05q9gKIXPNwPdr1cOjnxNQdNicEFg2WIApO9Og,28877
|
57
61
|
versionhq/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
62
|
versionhq/tool/cache_handler.py,sha256=iL8FH7X0G-cdT0uhJwzuhLDaadTXOdfybZcDy151-es,1085
|
59
63
|
versionhq/tool/composio_tool.py,sha256=IATfsEnF_1RPJyGtPBmAtEJh5XPcgDHpyG3SUR461Og,8572
|
@@ -62,8 +66,8 @@ versionhq/tool/decorator.py,sha256=C4ZM7Xi2gwtEMaSeRo-geo_g_MAkY77WkSLkAuY0AyI,1
|
|
62
66
|
versionhq/tool/model.py,sha256=ve9C4WyiRjQigOU0hRWVxtSUWAQNntlmeW-_DL0_lJY,12328
|
63
67
|
versionhq/tool/rag_tool.py,sha256=dW5o-83V4bMFFJEj3PUm7XjblwrYJGmZVBlCpPj6CeM,3852
|
64
68
|
versionhq/tool/tool_handler.py,sha256=2m41K8qo5bGCCbwMFferEjT-XZ-mE9F0mDUOBkgivOI,1416
|
65
|
-
versionhq-1.2.
|
66
|
-
versionhq-1.2.
|
67
|
-
versionhq-1.2.
|
68
|
-
versionhq-1.2.
|
69
|
-
versionhq-1.2.
|
69
|
+
versionhq-1.2.4.2.dist-info/LICENSE,sha256=cRoGGdM73IiDs6nDWKqPlgSv7aR4n-qBXYnJlCMHCeE,1082
|
70
|
+
versionhq-1.2.4.2.dist-info/METADATA,sha256=qQ2-yJwPEuN62-SfvREXpqf3dDJc3xkwMrACWx5JYm8,21146
|
71
|
+
versionhq-1.2.4.2.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
72
|
+
versionhq-1.2.4.2.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
|
73
|
+
versionhq-1.2.4.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|