goose-py 0.4.0__py3-none-any.whl → 0.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.
goose/agent.py CHANGED
@@ -7,6 +7,7 @@ from typing import Any, ClassVar, Literal, NotRequired, Protocol, TypedDict
7
7
 
8
8
  from litellm import acompletion
9
9
  from pydantic import BaseModel, computed_field
10
+ from goose.result import Result, TextResult
10
11
 
11
12
 
12
13
  class GeminiModel(StrEnum):
@@ -115,7 +116,7 @@ class AgentResponseDump(TypedDict):
115
116
  duration_ms: int
116
117
 
117
118
 
118
- class AgentResponse[R: BaseModel](BaseModel):
119
+ class AgentResponse[R: BaseModel | str](BaseModel):
119
120
  INPUT_CENTS_PER_MILLION_TOKENS: ClassVar[dict[GeminiModel, float]] = {
120
121
  GeminiModel.FLASH_8B: 30,
121
122
  GeminiModel.FLASH: 15,
@@ -186,6 +187,12 @@ class AgentResponse[R: BaseModel](BaseModel):
186
187
  json.dumps(message) for message in minimized_input_messages
187
188
  ]
188
189
 
190
+ output_message = (
191
+ self.response.model_dump_json()
192
+ if isinstance(self.response, BaseModel)
193
+ else self.response
194
+ )
195
+
189
196
  return {
190
197
  "run_id": self.run_id,
191
198
  "flow_name": self.flow_name,
@@ -193,7 +200,7 @@ class AgentResponse[R: BaseModel](BaseModel):
193
200
  "model": self.model.value,
194
201
  "system_message": minimized_system_message,
195
202
  "input_messages": minimized_input_messages,
196
- "output_message": self.response.model_dump_json(),
203
+ "output_message": output_message,
197
204
  "input_tokens": self.input_tokens,
198
205
  "output_tokens": self.output_tokens,
199
206
  "input_cost": self.input_cost,
@@ -221,13 +228,13 @@ class Agent:
221
228
  self.run_id = run_id
222
229
  self.logger = logger
223
230
 
224
- async def __call__[R: BaseModel](
231
+ async def __call__[R: Result](
225
232
  self,
226
233
  *,
227
234
  messages: list[UserMessage | AssistantMessage],
228
235
  model: GeminiModel,
229
- response_model: type[R],
230
236
  task_name: str,
237
+ response_model: type[R] = TextResult,
231
238
  system: SystemMessage | None = None,
232
239
  ) -> R:
233
240
  start_time = datetime.now()
@@ -235,22 +242,25 @@ class Agent:
235
242
  if system is not None:
236
243
  rendered_messages.insert(0, system.render())
237
244
 
238
- response = await acompletion(
239
- model=model.value,
240
- messages=rendered_messages,
241
- response_format={
242
- "type": "json_object",
243
- "response_schema": response_model.model_json_schema(),
244
- "enforce_validation": True,
245
- },
246
- )
247
-
248
- if len(response.choices) == 0:
249
- raise RuntimeError("No content returned from LLM call.")
245
+ if response_model is TextResult:
246
+ response = await acompletion(model=model.value, messages=rendered_messages)
247
+ parsed_response = response_model.model_validate(
248
+ {"text": response.choices[0].message.content}
249
+ )
250
+ else:
251
+ response = await acompletion(
252
+ model=model.value,
253
+ messages=rendered_messages,
254
+ response_format={
255
+ "type": "json_object",
256
+ "response_schema": response_model.model_json_schema(),
257
+ "enforce_validation": True,
258
+ },
259
+ )
260
+ parsed_response = response_model.model_validate_json(
261
+ response.choices[0].message.content
262
+ )
250
263
 
251
- parsed_response = response_model.model_validate_json(
252
- response.choices[0].message.content
253
- )
254
264
  end_time = datetime.now()
255
265
  agent_response = AgentResponse(
256
266
  response=parsed_response,
@@ -271,4 +281,4 @@ class Agent:
271
281
  else:
272
282
  logging.info(agent_response.model_dump())
273
283
 
274
- return agent_response.response
284
+ return parsed_response
goose/flow.py CHANGED
@@ -13,7 +13,7 @@ from typing import (
13
13
  overload,
14
14
  )
15
15
 
16
- from pydantic import BaseModel, ConfigDict
16
+ from pydantic import BaseModel
17
17
 
18
18
  from goose.agent import (
19
19
  Agent,
@@ -24,15 +24,12 @@ from goose.agent import (
24
24
  UserMessage,
25
25
  )
26
26
  from goose.errors import Honk
27
+ from goose.result import Result
27
28
  from goose.store import IFlowRunStore, InMemoryFlowRunStore
28
29
 
29
30
  SerializedFlowRun = NewType("SerializedFlowRun", str)
30
31
 
31
32
 
32
- class Result(BaseModel):
33
- model_config = ConfigDict(frozen=True)
34
-
35
-
36
33
  class Conversation[R: Result](BaseModel):
37
34
  user_messages: list[UserMessage]
38
35
  result_messages: list[R]
@@ -68,7 +65,9 @@ class Conversation[R: Result](BaseModel):
68
65
  class IAdapter[ResultT: Result](Protocol):
69
66
  __code__: CodeType
70
67
 
71
- async def __call__(self, *, conversation: Conversation[ResultT]) -> ResultT: ...
68
+ async def __call__(
69
+ self, *, conversation: Conversation[ResultT], agent: Agent
70
+ ) -> ResultT: ...
72
71
 
73
72
 
74
73
  class NodeState[ResultT: Result](BaseModel):
@@ -357,7 +356,9 @@ class Task[**P, R: Result]:
357
356
  node_state.set_context(context=context)
358
357
  node_state.add_user_message(message=user_message)
359
358
 
360
- result = await self._adapter(conversation=node_state.conversation)
359
+ result = await self._adapter(
360
+ conversation=node_state.conversation, agent=flow_run.agent
361
+ )
361
362
  node_state.add_result(result=result)
362
363
  flow_run.add_node_state(node_state)
363
364
 
goose/result.py ADDED
@@ -0,0 +1,9 @@
1
+ from pydantic import BaseModel, ConfigDict
2
+
3
+
4
+ class Result(BaseModel):
5
+ model_config = ConfigDict(frozen=True)
6
+
7
+
8
+ class TextResult(Result):
9
+ text: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: goose-py
3
- Version: 0.4.0
3
+ Version: 0.4.2
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
@@ -0,0 +1,10 @@
1
+ goose/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ goose/agent.py,sha256=S9nDhK7v4Rsk-ANuq5tIZfZ7TOmCdMEVid2VuK1EWCw,8106
3
+ goose/errors.py,sha256=-0OyZQJWYTRw5YgnCB2_uorVaUsL6Z0QYQO2FqzCiyg,32
4
+ goose/flow.py,sha256=9KF0OKa7k6YIJ7LqI5zpCfaIYoRRPgCQoFeiZ2QU_9M,13500
5
+ goose/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ goose/result.py,sha256=-eZJn-2sPo7rHZ38Sz6IAHXqiJ-Ss39esEoFGimJEBI,155
7
+ goose/store.py,sha256=4p2BBVAEUS1_Z0iBk5Qk_fPxRQeph64DRzXOFmjIT38,844
8
+ goose_py-0.4.2.dist-info/METADATA,sha256=tSSTAh-EKeEGEyR48MSVVUL--dK1iZ3EAW7G8WD6PlM,1106
9
+ goose_py-0.4.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
10
+ goose_py-0.4.2.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- goose/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- goose/agent.py,sha256=pZkKKW2weXEX43p9-pVIpEtwei5nylyQ_YrNZWYFQM0,7687
3
- goose/errors.py,sha256=-0OyZQJWYTRw5YgnCB2_uorVaUsL6Z0QYQO2FqzCiyg,32
4
- goose/flow.py,sha256=tzubasKLCOgB_X5-MgC-44OhbwqFZq_7gja3sSElCMI,13478
5
- goose/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- goose/store.py,sha256=4p2BBVAEUS1_Z0iBk5Qk_fPxRQeph64DRzXOFmjIT38,844
7
- goose_py-0.4.0.dist-info/METADATA,sha256=CJhAf8NiFEOq7pL4Ng4zQbuLMe9Gax-cO1UXJHnYpLY,1106
8
- goose_py-0.4.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
9
- goose_py-0.4.0.dist-info/RECORD,,