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 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.2"
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
- default=None, description="region of client's main business operation"
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
- "may_not_set_field", "This field is not to be set by the user.", {}
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
- default=None, description="marketing url of the product if any"
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
- Any,
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
- *args: List[ScoreFormat],
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.args = args
58
-
59
- def result(self):
60
- aggregated_score = sum(
61
- self.brand_tone.aggregate,
62
- self.audience.aggregate,
63
- self.track_record.aggrigate,
64
- )
65
- denominator = sum(
66
- self.brand_tone.weight, self.audience.weight, self.track_record.weight
67
- )
68
- try:
69
- if self.args:
70
- for item in self.args:
71
- if isinstance(item, ScoreFormat):
72
- aggregate_score += item.rate * item.weight
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
- comps: List[MessagingComponent] = Field(
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
- max_length=256,
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
- "may_not_set_field", "This field is not to be set by the user.", {}
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
- def reassign_agent_or_team(
163
- self, agents: List[Agent] = None, team: Team = None
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
- """Execute the task asynchronously with context handling."""
403
- result = self._execute_core(agent, context)
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(self.output)
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
- UUID4,
12
- InstanceOf,
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
- self,
305
- futures: List[Tuple[Task, Future[TaskOutput], int]],
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.2
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
- For more details:
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
- [PyPi package](https://pypi.org/project/versionhq/)
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=ZRUf-j8kvlaLsgzQHU-EVzvct-p6Rrrm8X7wLmQcgrY,773
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=nJT3EOkFAEV70fcEeNS8ctkzztONK-HhwMkY39qtEzo,18359
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=GUe-ObklAK19gkD_SSQIBFIAVmCnSQqCyHBPjLL3BAk,2584
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=JMAyh1Yhr0ZCmgeB9QX4XLbtwv0we9YtOC0Xr-Xmbdk,5229
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=maWDeVm1CfqGw-re42a02-0SXtCmkjXsz_ociB1epfQ,17000
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=pMCt0ZCVgE_pRH2qXlWj-PEZrI77JoRVVzUOZWY1Rws,20140
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.2.dist-info/LICENSE,sha256=7CCXuMrAjPVsUvZrsBq9DsxI2rLDUSYXR_qj4yO_ZII,1077
36
- versionhq-1.1.7.2.dist-info/METADATA,sha256=6xxLMRkGhlbN1siAlvNsRQc1JWGTk0hIT4J5ziNMaZQ,14278
37
- versionhq-1.1.7.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
38
- versionhq-1.1.7.2.dist-info/top_level.txt,sha256=DClQwxDWqIUGeRJkA8vBlgeNsYZs4_nJWMonzFt5Wj0,10
39
- versionhq-1.1.7.2.dist-info/RECORD,,
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,,