versionhq 1.1.7.2__py3-none-any.whl → 1.1.7.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.
- versionhq/__init__.py +5 -2
- versionhq/agent/model.py +2 -2
- versionhq/clients/product/model.py +11 -36
- versionhq/clients/workflow/model.py +62 -78
- versionhq/task/model.py +26 -12
- versionhq/team/model.py +8 -18
- {versionhq-1.1.7.2.dist-info → versionhq-1.1.7.3.dist-info}/METADATA +9 -10
- {versionhq-1.1.7.2.dist-info → versionhq-1.1.7.3.dist-info}/RECORD +11 -11
- {versionhq-1.1.7.2.dist-info → versionhq-1.1.7.3.dist-info}/LICENSE +0 -0
- {versionhq-1.1.7.2.dist-info → versionhq-1.1.7.3.dist-info}/WHEEL +0 -0
- {versionhq-1.1.7.2.dist-info → versionhq-1.1.7.3.dist-info}/top_level.txt +0 -0
versionhq/__init__.py
CHANGED
@@ -10,20 +10,23 @@ warnings.filterwarnings(
|
|
10
10
|
from versionhq.agent.model import Agent
|
11
11
|
from versionhq.clients.customer.model import Customer
|
12
12
|
from versionhq.clients.product.model import Product, ProductProvider
|
13
|
-
from versionhq.clients.workflow.model import MessagingWorkflow
|
13
|
+
from versionhq.clients.workflow.model import MessagingWorkflow, MessagingComponent, Score, ScoreFormat
|
14
14
|
from versionhq.llm.model import LLM
|
15
15
|
from versionhq.task.model import Task, TaskOutput
|
16
16
|
from versionhq.team.model import Team, TeamOutput
|
17
17
|
from versionhq.tool.model import Tool
|
18
18
|
|
19
19
|
|
20
|
-
__version__ = "1.1.7.
|
20
|
+
__version__ = "1.1.7.3"
|
21
21
|
__all__ = [
|
22
22
|
"Agent",
|
23
23
|
"Customer",
|
24
24
|
"Product",
|
25
25
|
"ProductProvider",
|
26
26
|
"MessagingWorkflow",
|
27
|
+
"MessagingComponent",
|
28
|
+
"Score",
|
29
|
+
"ScoreFormat",
|
27
30
|
"LLM",
|
28
31
|
"Task",
|
29
32
|
"TaskOutput",
|
versionhq/agent/model.py
CHANGED
@@ -95,7 +95,7 @@ class Agent(ABC, BaseModel):
|
|
95
95
|
role: str = Field(description="role of the agent - used in summary and logs")
|
96
96
|
goal: str = Field(description="concise goal of the agent (details are set in the Task instance)")
|
97
97
|
backstory: Optional[str] = Field(default=None, description="system context passed to the LLM")
|
98
|
-
knowledge: Optional[str] = Field(default=None)
|
98
|
+
knowledge: Optional[str] = Field(default=None, description="external knowledge fed to the agent")
|
99
99
|
skillsets: Optional[List[str]] = Field(default_factory=list)
|
100
100
|
|
101
101
|
# tools
|
@@ -358,7 +358,7 @@ class Agent(ABC, BaseModel):
|
|
358
358
|
return {"output": response.output if hasattr(response, "output") else response}
|
359
359
|
|
360
360
|
|
361
|
-
def execute_task(self, task, context: Optional[str] = None) -> str:
|
361
|
+
def execute_task(self, task, context: Optional[str] = None, tools: Optional[str] = None) -> str:
|
362
362
|
"""
|
363
363
|
Execute the task and return the output in string.
|
364
364
|
To simplify, the tools are cascaded from the `tools_called` under the `task` Task instance if any.
|
@@ -1,15 +1,6 @@
|
|
1
1
|
import uuid
|
2
2
|
from typing import Any, Dict, List, Callable, Type, Optional, get_args, get_origin
|
3
|
-
from pydantic import
|
4
|
-
UUID4,
|
5
|
-
InstanceOf,
|
6
|
-
BaseModel,
|
7
|
-
ConfigDict,
|
8
|
-
Field,
|
9
|
-
create_model,
|
10
|
-
field_validator,
|
11
|
-
model_validator,
|
12
|
-
)
|
3
|
+
from pydantic import UUID4, InstanceOf, BaseModel, ConfigDict, Field, create_model, field_validator, model_validator
|
13
4
|
from pydantic_core import PydanticCustomError
|
14
5
|
|
15
6
|
|
@@ -23,24 +14,16 @@ class ProductProvider(BaseModel):
|
|
23
14
|
|
24
15
|
id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
|
25
16
|
name: Optional[str] = Field(default=None, description="client name")
|
26
|
-
region: Optional[str] = Field(
|
27
|
-
|
28
|
-
)
|
29
|
-
data_pipeline: Optional[List[str]] = Field(
|
30
|
-
default=None, description="store the data pipelines that the client is using"
|
31
|
-
)
|
32
|
-
destinations: Optional[List[str]] = Field(
|
33
|
-
default=None,
|
34
|
-
description="store the destination services that the client is using",
|
35
|
-
)
|
17
|
+
region: Optional[str] = Field(default=None, description="region of client's main business operation")
|
18
|
+
data_pipeline: Optional[List[str]] = Field(default=None, description="store the data pipelines that the client is using")
|
19
|
+
destinations: Optional[List[str]] = Field(default=None,description="store the destination services that the client is using")
|
36
20
|
|
37
21
|
@field_validator("id", mode="before")
|
38
22
|
@classmethod
|
39
23
|
def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
|
40
24
|
if v:
|
41
|
-
raise PydanticCustomError(
|
42
|
-
|
43
|
-
)
|
25
|
+
raise PydanticCustomError("may_not_set_field", "This field is not to be set by the user.", {})
|
26
|
+
|
44
27
|
|
45
28
|
|
46
29
|
class Product(BaseModel):
|
@@ -51,24 +34,16 @@ class Product(BaseModel):
|
|
51
34
|
id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
|
52
35
|
name: Optional[str] = Field(default=None, description="product name")
|
53
36
|
description: Optional[str] = Field(
|
54
|
-
default=None,
|
55
|
-
max_length=256,
|
56
|
-
description="product description scraped from landing url or client input. cascade to the agent",
|
57
|
-
)
|
37
|
+
default=None,max_length=256,description="product description scraped from landing url or client input. cascade to the agent")
|
58
38
|
provider: Optional[ProductProvider] = Field(default=None)
|
59
39
|
audience: Optional[str] = Field(default=None, description="target audience")
|
60
40
|
usp: Optional[str] = Field(default=None)
|
61
|
-
landing_url: Optional[str] = Field(
|
62
|
-
|
63
|
-
|
64
|
-
cohort_timeframe: Optional[int] = Field(
|
65
|
-
default=30, description="ideal cohort timeframe of the product in days"
|
66
|
-
)
|
41
|
+
landing_url: Optional[str] = Field(default=None, description="marketing url of the product if any")
|
42
|
+
cohort_timeframe: Optional[int] = Field(default=30, description="ideal cohort timeframe of the product in days")
|
43
|
+
|
67
44
|
|
68
45
|
@field_validator("id", mode="before")
|
69
46
|
@classmethod
|
70
47
|
def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
|
71
48
|
if v:
|
72
|
-
raise PydanticCustomError(
|
73
|
-
"may_not_set_field", "This field is not to be set by the user.", {}
|
74
|
-
)
|
49
|
+
raise PydanticCustomError("may_not_set_field", "This field is not to be set by the user.", {})
|
@@ -1,27 +1,8 @@
|
|
1
1
|
import uuid
|
2
2
|
from abc import ABC
|
3
3
|
from datetime import date, datetime, time, timedelta
|
4
|
-
from typing import
|
5
|
-
|
6
|
-
Dict,
|
7
|
-
List,
|
8
|
-
Union,
|
9
|
-
Callable,
|
10
|
-
Type,
|
11
|
-
Optional,
|
12
|
-
get_args,
|
13
|
-
get_origin,
|
14
|
-
)
|
15
|
-
from pydantic import (
|
16
|
-
UUID4,
|
17
|
-
InstanceOf,
|
18
|
-
BaseModel,
|
19
|
-
ConfigDict,
|
20
|
-
Field,
|
21
|
-
create_model,
|
22
|
-
field_validator,
|
23
|
-
model_validator,
|
24
|
-
)
|
4
|
+
from typing import Any, Dict, List, Union, Callable, Type, Optional, get_args, get_origin
|
5
|
+
from pydantic import UUID4, InstanceOf, BaseModel, ConfigDict, Field, create_model, field_validator, model_validator
|
25
6
|
from pydantic_core import PydanticCustomError
|
26
7
|
|
27
8
|
from versionhq.clients.product.model import Product
|
@@ -31,7 +12,7 @@ from versionhq.team.model import Team
|
|
31
12
|
|
32
13
|
|
33
14
|
class ScoreFormat:
|
34
|
-
def __init__(self, rate: float, weight: int = 1):
|
15
|
+
def __init__(self, rate: Union[float, int] = 0, weight: int = 1):
|
35
16
|
self.rate = rate
|
36
17
|
self.weight = weight
|
37
18
|
self.aggregate = rate * weight
|
@@ -46,48 +27,65 @@ class Score:
|
|
46
27
|
|
47
28
|
def __init__(
|
48
29
|
self,
|
49
|
-
brand_tone: ScoreFormat,
|
50
|
-
audience: ScoreFormat,
|
51
|
-
track_record: ScoreFormat,
|
52
|
-
|
30
|
+
brand_tone: ScoreFormat = ScoreFormat(0, 0),
|
31
|
+
audience: ScoreFormat = ScoreFormat(0, 0),
|
32
|
+
track_record: ScoreFormat = ScoreFormat(0, 0),
|
33
|
+
**kwargs: Optional[Dict[str, ScoreFormat]],
|
53
34
|
):
|
54
35
|
self.brand_tone = brand_tone
|
55
36
|
self.audience = audience
|
56
37
|
self.track_record = track_record
|
57
|
-
self.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
denominator += item.weight
|
74
|
-
except:
|
75
|
-
pass
|
76
|
-
return round(aggregated_score / denominator, 2)
|
38
|
+
self.kwargs = kwargs
|
39
|
+
|
40
|
+
|
41
|
+
def result(self) -> int:
|
42
|
+
aggregate_score = self.brand_tone.aggregate + self.audience.aggregate + self.track_record.aggregate
|
43
|
+
denominator = self.brand_tone.weight + self.audience.weight + self.track_record.weight
|
44
|
+
|
45
|
+
for k, v in self.kwargs.items():
|
46
|
+
aggregate_score += v.aggregate
|
47
|
+
denominator += v.weight
|
48
|
+
|
49
|
+
if denominator == 0:
|
50
|
+
return 0
|
51
|
+
|
52
|
+
return round(aggregate_score / denominator, 2)
|
53
|
+
|
77
54
|
|
78
55
|
|
79
56
|
class MessagingComponent(ABC, BaseModel):
|
80
57
|
layer_id: int = Field(default=0, description="add id of the layer: 0, 1, 2")
|
81
|
-
message: str = Field(
|
82
|
-
default=None, max_length=1024, description="text message content to be sent"
|
83
|
-
)
|
58
|
+
message: str = Field(default=None, max_length=1024, description="text message content to be sent")
|
84
59
|
interval: Optional[str] = Field(
|
85
|
-
default=None,
|
86
|
-
description="interval to move on to the next layer. if this is the last layer, set as `None`",
|
87
|
-
)
|
60
|
+
default=None,description="interval to move on to the next layer. if this is the last layer, set as `None`")
|
88
61
|
score: Union[float, InstanceOf[Score]] = Field(default=None)
|
89
62
|
|
90
63
|
|
64
|
+
def store_scoring_result(self, scoring_subject: str, score: Union[int, Score, ScoreFormat] = None):
|
65
|
+
"""
|
66
|
+
Set up the `score` field
|
67
|
+
"""
|
68
|
+
|
69
|
+
if isinstance(score, Score):
|
70
|
+
setattr(self, "score", score)
|
71
|
+
|
72
|
+
elif isinstance(score, ScoreFormat):
|
73
|
+
score_instance = Score()
|
74
|
+
setattr(score_instance, scoring_subject, score)
|
75
|
+
setattr(self, "score", score_instance)
|
76
|
+
|
77
|
+
elif isinstance(score, int) or isinstance(score, float):
|
78
|
+
score_instance, score_format_instance = Score(), ScoreFormat(rate=score, weight=1)
|
79
|
+
setattr(score_instance, "kwargs", { scoring_subject: score_format_instance })
|
80
|
+
setattr(self, "score", score_instance)
|
81
|
+
|
82
|
+
else:
|
83
|
+
pass
|
84
|
+
|
85
|
+
return self
|
86
|
+
|
87
|
+
|
88
|
+
|
91
89
|
class MessagingWorkflow(ABC, BaseModel):
|
92
90
|
"""
|
93
91
|
Store 3 layers of messaging workflow sent to `customer` on the `product`
|
@@ -99,49 +97,36 @@ class MessagingWorkflow(ABC, BaseModel):
|
|
99
97
|
model_config = ConfigDict()
|
100
98
|
|
101
99
|
id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
|
102
|
-
|
103
|
-
default=list, description="store at least 3 messaging components"
|
104
|
-
)
|
100
|
+
components: List[MessagingComponent] = Field(default_factory=list, description="store messaging components in the workflow")
|
105
101
|
|
106
102
|
# responsible tean or agents
|
107
|
-
team: Optional[Team] = Field(
|
108
|
-
default=None,
|
109
|
-
description="store `Team` instance responsibile for autopiloting this workflow",
|
110
|
-
)
|
103
|
+
team: Optional[Team] = Field(default=None, description="store `Team` instance responsibile for autopiloting this workflow")
|
111
104
|
agents: Optional[List[Agent]] = Field(
|
112
|
-
default=None,
|
113
|
-
description="store `Agent` instances responsible for autopiloting this workflow. if the team exsits, this field remains as `None`",
|
114
|
-
)
|
105
|
+
default=None, description="store `Agent` instances responsible for autopiloting this workflow. if the team exsits, this field remains as `None`")
|
115
106
|
|
116
107
|
# metrics
|
117
|
-
destination: Optional[str] = Field(
|
118
|
-
default=None, description="destination service to launch this workflow"
|
119
|
-
)
|
108
|
+
destination: Optional[str] = Field( default=None, description="destination service to launch this workflow")
|
120
109
|
product: InstanceOf[Product] = Field(default=None)
|
121
110
|
customer: InstanceOf[Customer] = Field(default=None)
|
122
111
|
|
123
112
|
metrics: Union[List[Dict[str, Any]], List[str]] = Field(
|
124
|
-
default=None,
|
125
|
-
|
126
|
-
description="store metrics that used to predict and track the performance of this workflow.",
|
127
|
-
)
|
113
|
+
default=None, max_length=256, description="store metrics that used to predict and track the performance of this workflow.")
|
114
|
+
|
128
115
|
|
129
116
|
@property
|
130
117
|
def name(self):
|
131
118
|
if self.customer.id:
|
132
|
-
return
|
133
|
-
f"Workflow ID: {self.id} - on {self.product.id} for {self.customer.id}"
|
134
|
-
)
|
119
|
+
return f"Workflow ID: {self.id} - on {self.product.id} for {self.customer.id}"
|
135
120
|
else:
|
136
121
|
return f"Workflow ID: {self.id} - on {self.product.id}"
|
137
122
|
|
123
|
+
|
138
124
|
@field_validator("id", mode="before")
|
139
125
|
@classmethod
|
140
126
|
def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
|
141
127
|
if v:
|
142
|
-
raise PydanticCustomError(
|
143
|
-
|
144
|
-
)
|
128
|
+
raise PydanticCustomError("may_not_set_field", "This field is not to be set by the user.", {})
|
129
|
+
|
145
130
|
|
146
131
|
@model_validator(mode="after")
|
147
132
|
def set_up_destination(self):
|
@@ -159,9 +144,8 @@ class MessagingWorkflow(ABC, BaseModel):
|
|
159
144
|
self.destination = destination_list[0]
|
160
145
|
return self
|
161
146
|
|
162
|
-
|
163
|
-
|
164
|
-
) -> None:
|
147
|
+
|
148
|
+
def reassign_agent_or_team(self, agents: List[Agent] = None, team: Team = None) -> None:
|
165
149
|
"""
|
166
150
|
Fire unresponsible agents/team and assign new one.
|
167
151
|
"""
|
versionhq/task/model.py
CHANGED
@@ -151,7 +151,8 @@ class Task(BaseModel):
|
|
151
151
|
# task setup
|
152
152
|
context: Optional[List["Task"]] = Field(default=None, description="other tasks whose outputs should be used as context")
|
153
153
|
tools_called: Optional[List[ToolCalled]] = Field(default_factory=list, description="tools that the agent can use for this task")
|
154
|
-
take_tool_res_as_final: bool = Field(default=False,description="when set True, tools res will be stored in the `TaskOutput`")
|
154
|
+
take_tool_res_as_final: bool = Field(default=False, description="when set True, tools res will be stored in the `TaskOutput`")
|
155
|
+
allow_delegation: bool = Field(default=False, description="ask other agents for help and run the task instead")
|
155
156
|
|
156
157
|
prompt_context: Optional[str] = Field(default=None)
|
157
158
|
async_execution: bool = Field(default=False,description="whether the task should be executed asynchronously or not")
|
@@ -370,7 +371,7 @@ Your outputs MUST adhere to the following format and should NOT include any irre
|
|
370
371
|
|
371
372
|
|
372
373
|
# task execution
|
373
|
-
def execute_sync(self, agent, context: Optional[str] = None) -> TaskOutput:
|
374
|
+
def execute_sync(self, agent, context: Optional[str] = None, callback_kwargs: Dict[str, Any] = None) -> TaskOutput:
|
374
375
|
"""
|
375
376
|
Execute the task synchronously.
|
376
377
|
When the task has context, make sure we have executed all the tasks in the context first.
|
@@ -379,12 +380,12 @@ Your outputs MUST adhere to the following format and should NOT include any irre
|
|
379
380
|
if self.context:
|
380
381
|
for task in self.context:
|
381
382
|
if task.output is None:
|
382
|
-
task._execute_core(agent, context)
|
383
|
+
task._execute_core(agent, context, callback_kwargs)
|
383
384
|
|
384
385
|
return self._execute_core(agent, context)
|
385
386
|
|
386
387
|
|
387
|
-
def execute_async(self, agent, context: Optional[str] = None) -> Future[TaskOutput]:
|
388
|
+
def execute_async(self, agent, context: Optional[str] = None, callback_kwargs: Dict[str, Any] = None) -> Future[TaskOutput]:
|
388
389
|
"""
|
389
390
|
Execute the task asynchronously.
|
390
391
|
"""
|
@@ -393,26 +394,36 @@ Your outputs MUST adhere to the following format and should NOT include any irre
|
|
393
394
|
threading.Thread(
|
394
395
|
daemon=True,
|
395
396
|
target=self._execute_task_async,
|
396
|
-
args=(agent, context, future),
|
397
|
+
args=(agent, context, callback_kwargs, future),
|
397
398
|
).start()
|
398
399
|
return future
|
399
400
|
|
400
401
|
|
401
|
-
def _execute_task_async(self, agent, context: Optional[str], future: Future[TaskOutput]) -> None:
|
402
|
-
"""
|
403
|
-
|
402
|
+
def _execute_task_async(self, agent, context: Optional[str], callback_kwargs: Dict[str, Any], future: Future[TaskOutput]) -> None:
|
403
|
+
"""
|
404
|
+
Execute the task asynchronously with context handling.
|
405
|
+
"""
|
406
|
+
|
407
|
+
result = self._execute_core(agent, context, callback_kwargs)
|
404
408
|
future.set_result(result)
|
405
409
|
|
406
410
|
|
407
|
-
def _execute_core(self, agent, context: Optional[str]) -> TaskOutput:
|
411
|
+
def _execute_core(self, agent, context: Optional[str], callback_kwargs: Optional[Dict[str, Any]] = None) -> TaskOutput:
|
408
412
|
"""
|
409
413
|
Run the core execution logic of the task.
|
414
|
+
To speed up the process, when the format is not expected to return, we will skip the conversion process.
|
410
415
|
"""
|
416
|
+
from versionhq.agent.model import Agent
|
411
417
|
|
412
418
|
self.prompt_context = context
|
419
|
+
|
420
|
+
if self.allow_delegation:
|
421
|
+
agent = Agent(role="delegated_agent", goal=agent.goal, llm=agent.llm) #! REFINEME - logic to pick up the high performer
|
422
|
+
self.delegations += 1
|
423
|
+
|
413
424
|
output_raw = agent.execute_task(task=self, context=context)
|
414
|
-
output_json_dict = self.create_json_output(raw_result=output_raw)
|
415
|
-
output_pydantic = self.create_pydantic_output(output_json_dict=output_json_dict)
|
425
|
+
output_json_dict = self.create_json_output(raw_result=output_raw) if self.expected_output_json is True else None
|
426
|
+
output_pydantic = self.create_pydantic_output(output_json_dict=output_json_dict) if self.expected_output_pydantic else None
|
416
427
|
task_output = TaskOutput(
|
417
428
|
task_id=self.id,
|
418
429
|
raw=output_raw,
|
@@ -425,7 +436,10 @@ Your outputs MUST adhere to the following format and should NOT include any irre
|
|
425
436
|
# self._set_end_execution_time(start_time)
|
426
437
|
|
427
438
|
if self.callback:
|
428
|
-
self.callback
|
439
|
+
if isinstance(self.callback, Callable):
|
440
|
+
self.callback(**callback_kwargs)
|
441
|
+
else:
|
442
|
+
self.callback(self.output)
|
429
443
|
|
430
444
|
# if self._execution_span:
|
431
445
|
# # self._telemetry.task_ended(self._execution_span, self, agent.team)
|
versionhq/team/model.py
CHANGED
@@ -7,17 +7,9 @@ from dotenv import load_dotenv
|
|
7
7
|
from concurrent.futures import Future
|
8
8
|
from hashlib import md5
|
9
9
|
from typing import Any, Dict, List, TYPE_CHECKING, Callable, Optional, Tuple, Union
|
10
|
-
from pydantic import
|
11
|
-
|
12
|
-
|
13
|
-
Json,
|
14
|
-
BaseModel,
|
15
|
-
Field,
|
16
|
-
PrivateAttr,
|
17
|
-
field_validator,
|
18
|
-
model_validator,
|
19
|
-
)
|
20
|
-
from pydantic_core import PydanticCustomError
|
10
|
+
from pydantic import UUID4, InstanceOf, Json, BaseModel, Field, PrivateAttr, field_validator, model_validator
|
11
|
+
from pydantic._internal._generate_schema import GenerateSchema
|
12
|
+
from pydantic_core import PydanticCustomError, core_schema
|
21
13
|
|
22
14
|
from versionhq.agent.model import Agent
|
23
15
|
from versionhq.task.model import Task, TaskOutput, ConditionalTask, TaskOutputFormat
|
@@ -27,9 +19,6 @@ from versionhq._utils.logger import Logger
|
|
27
19
|
from versionhq._utils.usage_metrics import UsageMetrics
|
28
20
|
|
29
21
|
|
30
|
-
from pydantic._internal._generate_schema import GenerateSchema
|
31
|
-
from pydantic_core import core_schema
|
32
|
-
|
33
22
|
initial_match_type = GenerateSchema.match_type
|
34
23
|
|
35
24
|
|
@@ -301,10 +290,8 @@ class Team(BaseModel):
|
|
301
290
|
|
302
291
|
# task execution
|
303
292
|
def _process_async_tasks(
|
304
|
-
|
305
|
-
|
306
|
-
was_replayed: bool = False,
|
307
|
-
) -> List[TaskOutput]:
|
293
|
+
self, futures: List[Tuple[Task, Future[TaskOutput], int]], was_replayed: bool = False
|
294
|
+
) -> List[TaskOutput]:
|
308
295
|
task_outputs: List[TaskOutput] = []
|
309
296
|
for future_task, future, task_index in futures:
|
310
297
|
task_output = future.result()
|
@@ -315,6 +302,7 @@ class Team(BaseModel):
|
|
315
302
|
)
|
316
303
|
return task_outputs
|
317
304
|
|
305
|
+
|
318
306
|
def _handle_conditional_task(
|
319
307
|
self,
|
320
308
|
task: ConditionalTask,
|
@@ -323,6 +311,7 @@ class Team(BaseModel):
|
|
323
311
|
task_index: int,
|
324
312
|
was_replayed: bool,
|
325
313
|
) -> Optional[TaskOutput]:
|
314
|
+
|
326
315
|
if futures:
|
327
316
|
task_outputs = self._process_async_tasks(futures, was_replayed)
|
328
317
|
futures.clear()
|
@@ -347,6 +336,7 @@ class Team(BaseModel):
|
|
347
336
|
Take the output of the first task or the lead task output as the team output `raw` value.
|
348
337
|
Note that `tasks` are already sorted by the importance.
|
349
338
|
"""
|
339
|
+
|
350
340
|
if len(task_outputs) < 1:
|
351
341
|
raise ValueError("Something went wrong. Kickoff should return only one task output.")
|
352
342
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: versionhq
|
3
|
-
Version: 1.1.7.
|
3
|
+
Version: 1.1.7.3
|
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
|
@@ -142,7 +142,7 @@ Multiple `agents` can form a `team` to complete complex tasks together.
|
|
142
142
|
role="demo",
|
143
143
|
goal="amazing project goal",
|
144
144
|
skillsets=["skill_1", "skill_2", ],
|
145
|
-
llm="llm-of-choice"
|
145
|
+
llm="llm-of-your-choice"
|
146
146
|
)
|
147
147
|
|
148
148
|
task = Task(
|
@@ -153,20 +153,19 @@ Multiple `agents` can form a `team` to complete complex tasks together.
|
|
153
153
|
ResponseField(title="test1", type=str, required=True),
|
154
154
|
ResponseField(title="test2", type=list, required=True),
|
155
155
|
],
|
156
|
-
context=["amazing context",],
|
157
|
-
tools=["amazing tool"],
|
158
156
|
callback=None,
|
159
157
|
)
|
160
|
-
|
161
|
-
res = task.execute_sync(agent=agent)
|
162
|
-
|
158
|
+
res = task.execute_sync(agent=agent, context="amazing context to consider.")
|
163
159
|
return res.to_dict()
|
164
|
-
|
165
160
|
```
|
166
161
|
|
167
|
-
|
162
|
+
This will return a dictionary with keys defined in the `ResponseField`.
|
163
|
+
|
164
|
+
```
|
165
|
+
{ test1: "answer1", "test2": ["answer2-1", "answer2-2", "answer2-3",] }
|
166
|
+
```
|
168
167
|
|
169
|
-
[
|
168
|
+
For more info: [PyPI package](https://pypi.org/project/versionhq/)
|
170
169
|
|
171
170
|
<hr />
|
172
171
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
versionhq/__init__.py,sha256=
|
1
|
+
versionhq/__init__.py,sha256=EToQMoZAxs1MXIIOAOuj-McBRRO8WmAkCj4JJMKdgS0,871
|
2
2
|
versionhq/_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
versionhq/_utils/cache_handler.py,sha256=zDQKzIn7vp-M2-uepHFxgJstjfftZS5mzXKL_-4uVvI,370
|
4
4
|
versionhq/_utils/i18n.py,sha256=TwA_PnYfDLA6VqlUDPuybdV9lgi3Frh_ASsb_X8jJo8,1483
|
@@ -7,7 +7,7 @@ versionhq/_utils/process_config.py,sha256=ogrhovLbwe0ocQlcohRgBBRtww7C3pk9hikjvg
|
|
7
7
|
versionhq/_utils/rpm_controller.py,sha256=T7waIGeblu5K58erY4lqVLcPsWM7W9UFdU3DG9Dsk0w,2214
|
8
8
|
versionhq/_utils/usage_metrics.py,sha256=c33a_28y8ECUgflsKN3mkNm0fNkWgZmXwybMwIqoKXA,1098
|
9
9
|
versionhq/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
versionhq/agent/model.py,sha256=
|
10
|
+
versionhq/agent/model.py,sha256=h9QHB-Hi_71JinPlfL_83kaB-Ks8npzIqE7BVHwn1Aw,18439
|
11
11
|
versionhq/agent/parser.py,sha256=GhoNQo4WloVM3vGnAmt9lnEOTARX7nWMhJE55rF_5Rs,5500
|
12
12
|
versionhq/agent/TEMPLATES/Backstory.py,sha256=cdngBx1GEv7nroR46FEhnysnBJ9mEVL763_9np6Skkc,395
|
13
13
|
versionhq/agent/TEMPLATES/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -16,24 +16,24 @@ versionhq/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
16
16
|
versionhq/clients/customer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
versionhq/clients/customer/model.py,sha256=rQnCv_wdCdrYAsUjyB6X6ULiuWfqcBBoarXcQT5kj88,1762
|
18
18
|
versionhq/clients/product/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
-
versionhq/clients/product/model.py,sha256=
|
19
|
+
versionhq/clients/product/model.py,sha256=Us3UnzYlub6ipBislMN-JrvxZx0ocl9PtQJINJ8XtBA,2385
|
20
20
|
versionhq/clients/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
versionhq/clients/workflow/model.py,sha256=
|
21
|
+
versionhq/clients/workflow/model.py,sha256=8EbrUdS0vUhutx3_8M8A0Dw1BXpCqp5AFWbg4SGHj9M,5695
|
22
22
|
versionhq/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
versionhq/llm/llm_vars.py,sha256=YZoXqFBW7XpclUZ14_AAz7WOjoyCXnGcI959GSpX2q0,5343
|
24
24
|
versionhq/llm/model.py,sha256=PdwisrlrsDqd6gXwXCyGbGTRTeGZ8SXpt_gfua8qunk,8266
|
25
25
|
versionhq/task/__init__.py,sha256=g4mCATnn1mUXxsfQ5p6IpPawr8O421wVIT8kMKEcxQw,180
|
26
26
|
versionhq/task/formatter.py,sha256=N8Kmk9vtrMtBdgJ8J7RmlKNMdZWSmV8O1bDexmCWgU0,643
|
27
|
-
versionhq/task/model.py,sha256=
|
27
|
+
versionhq/task/model.py,sha256=wbDXLfGBSGfFafRrj_EQkJRDz99bcHTRmBtlhTFt3-4,17926
|
28
28
|
versionhq/team/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
|
-
versionhq/team/model.py,sha256=
|
29
|
+
versionhq/team/model.py,sha256=JlbQRp3oBDj1xhjcjqW7pNmqpvYCC-ojZJ1RmJsnSWM,20071
|
30
30
|
versionhq/team/team_planner.py,sha256=B1UOn_DYVVterUn2CAd80jfO4sViJCCXPJA3abSSugg,2143
|
31
31
|
versionhq/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
32
|
versionhq/tool/decorator.py,sha256=Y-j4jkoujD5LUvpe8uf3p5Zagk2XVaRKC9rkIE-2geo,1189
|
33
33
|
versionhq/tool/model.py,sha256=JZOEcZRIEfcrjL8DgrFYDt4YNgMF8rXS26RK6D2x9mc,6906
|
34
34
|
versionhq/tool/tool_handler.py,sha256=e-2VfG9zFpfPG_oMoPXye93GDovs7FuUASWQwUTLrJ0,1498
|
35
|
-
versionhq-1.1.7.
|
36
|
-
versionhq-1.1.7.
|
37
|
-
versionhq-1.1.7.
|
38
|
-
versionhq-1.1.7.
|
39
|
-
versionhq-1.1.7.
|
35
|
+
versionhq-1.1.7.3.dist-info/LICENSE,sha256=7CCXuMrAjPVsUvZrsBq9DsxI2rLDUSYXR_qj4yO_ZII,1077
|
36
|
+
versionhq-1.1.7.3.dist-info/METADATA,sha256=SWavJEaaRBeuOexx0gHwsTvgqZirMXDmAVxVImrVraQ,14413
|
37
|
+
versionhq-1.1.7.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
38
|
+
versionhq-1.1.7.3.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
|
39
|
+
versionhq-1.1.7.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|