goose-py 0.1.1__tar.gz → 0.1.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: goose-py
3
- Version: 0.1.1
3
+ Version: 0.1.4
4
4
  Summary: A tool for AI workflows based on human-computer collaboration and structured output.
5
5
  Home-page: https://github.com/chelle-ai/goose
6
6
  Keywords: ai,yaml,configuration,llm
@@ -1,5 +1,4 @@
1
1
  import logging
2
- import uuid
3
2
  from datetime import datetime
4
3
  from typing import Any, Callable
5
4
 
@@ -20,9 +19,11 @@ class Agent:
20
19
  self,
21
20
  *,
22
21
  flow_name: str,
22
+ run_id: str,
23
23
  logger: Callable[[AgentResponse[Any]], None] | None = None,
24
24
  ) -> None:
25
25
  self.flow_name = flow_name
26
+ self.run_id = run_id
26
27
  self.logger = logger or logging.info
27
28
 
28
29
  async def __call__[R: BaseModel](
@@ -58,7 +59,7 @@ class Agent:
58
59
  end_time = datetime.now()
59
60
  agent_response = AgentResponse(
60
61
  response=parsed_response,
61
- id=str(uuid.uuid4()),
62
+ id=self.run_id,
62
63
  flow_name=self.flow_name,
63
64
  task_name=task_name,
64
65
  model=model,
@@ -9,8 +9,8 @@ from graphlib import TopologicalSorter
9
9
  from pydantic import BaseModel
10
10
 
11
11
  from goose.agent import Agent
12
+ from goose.errors import Honk
12
13
  from goose.conversation import Conversation, ConversationState
13
- from goose.regenerator import default_regenerator
14
14
  from goose.types import AgentResponse, UserMessage
15
15
 
16
16
 
@@ -41,7 +41,7 @@ class Task[**P, R: BaseModel]:
41
41
  ) -> None:
42
42
  self.retries = retries
43
43
  self._generator = generator
44
- self._regenerator: IRegenerator[R] = default_regenerator
44
+ self._regenerator: IRegenerator[R] | None = None
45
45
  self._signature = inspect.signature(generator)
46
46
  self.__validate_fn()
47
47
 
@@ -49,7 +49,7 @@ class Task[**P, R: BaseModel]:
49
49
  def result_type(self) -> type[R]:
50
50
  return_type = self._generator.__annotations__.get("return")
51
51
  if return_type is None:
52
- raise TypeError("Task must have a return type annotation")
52
+ raise Honk("Task must have a return type annotation")
53
53
 
54
54
  return return_type
55
55
 
@@ -65,6 +65,9 @@ class Task[**P, R: BaseModel]:
65
65
  return await self._generator(*args, **kwargs)
66
66
 
67
67
  async def regenerate(self, *, result: R, conversation: Conversation[R]) -> R:
68
+ if self._regenerator is None:
69
+ raise Honk("Task does not have a regenerator implemented")
70
+
68
71
  return await self._regenerator(result=result, conversation=conversation)
69
72
 
70
73
  def __call__(self, *args: P.args, **kwargs: P.kwargs) -> "Node[R]":
@@ -76,7 +79,7 @@ class Task[**P, R: BaseModel]:
76
79
  param.kind == inspect.Parameter.POSITIONAL_ONLY
77
80
  for param in self._signature.parameters.values()
78
81
  ):
79
- raise ValueError("Positional-only parameters are not supported in Tasks")
82
+ raise Honk("Positional-only parameters are not supported in Tasks")
80
83
 
81
84
 
82
85
  class Node[R: BaseModel]:
@@ -97,7 +100,7 @@ class Node[R: BaseModel]:
97
100
  self._result: R | NoResult = NoResult()
98
101
  current_flow = Flow.get_current()
99
102
  if current_flow is None:
100
- raise RuntimeError("Cannot create a node without an active flow")
103
+ raise Honk("Cannot create a node without an active flow")
101
104
  self.id = current_flow.add_node(node=self)
102
105
 
103
106
  @property
@@ -107,7 +110,7 @@ class Node[R: BaseModel]:
107
110
  @property
108
111
  def result(self) -> R:
109
112
  if isinstance(self._result, NoResult):
110
- raise RuntimeError("Cannot access result of a node before it has run")
113
+ raise Honk("Cannot access result of a node before it has run")
111
114
  return self._result
112
115
 
113
116
  async def generate(self) -> None:
@@ -174,11 +177,12 @@ class Flow:
174
177
  self,
175
178
  *,
176
179
  name: str,
180
+ run_id: str,
177
181
  agent_logger: Callable[[AgentResponse[Any]], None] | None = None,
178
182
  ) -> None:
179
183
  self.name = name
180
184
  self._nodes: list[Node[BaseModel]] = []
181
- self._agent = Agent(flow_name=self.name, logger=agent_logger)
185
+ self._agent = Agent(flow_name=self.name, run_id=run_id, logger=agent_logger)
182
186
 
183
187
  @property
184
188
  def agent(self) -> Agent:
@@ -192,9 +196,7 @@ class Flow:
192
196
  for node_state in flow_state.nodes:
193
197
  matching_node = nodes_by_name.get(node_state.name)
194
198
  if matching_node is None:
195
- raise RuntimeError(
196
- f"Node {node_state.name} from state not found in flow"
197
- )
199
+ raise Honk(f"Node {node_state.name} from state not found in flow")
198
200
 
199
201
  matching_node.load_state(state=node_state)
200
202
 
@@ -215,7 +217,7 @@ class Flow:
215
217
 
216
218
  async def regenerate(self, *, target: Node[Any], message: UserMessage) -> None:
217
219
  if not target.has_result:
218
- raise RuntimeError("Cannot regenerate a node without a result")
220
+ raise Honk("Cannot regenerate a node without a result")
219
221
 
220
222
  await target.regenerate(message=message)
221
223
 
@@ -265,9 +267,7 @@ class Flow:
265
267
 
266
268
  def __enter__(self) -> Self:
267
269
  if self._current.get() is not None:
268
- raise RuntimeError(
269
- "Cannot enter a new flow while another flow is already active"
270
- )
270
+ raise Honk("Cannot enter a new flow while another flow is already active")
271
271
  self._current.set(self)
272
272
  return self
273
273
 
@@ -0,0 +1,2 @@
1
+ class Honk(Exception):
2
+ pass
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "goose-py"
3
- version = "0.1.1"
3
+ version = "0.1.4"
4
4
  description = "A tool for AI workflows based on human-computer collaboration and structured output."
5
5
  authors = [
6
6
  "Nash Taylor <nash@chelle.ai>",
@@ -1,5 +0,0 @@
1
- from goose.conversation import Conversation
2
-
3
-
4
- async def default_regenerator[R](*, result: R, conversation: Conversation[R]) -> R:
5
- return result
File without changes
File without changes
File without changes
File without changes
File without changes