goose-py 0.4.2__tar.gz → 0.5.1__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.4.2
3
+ Version: 0.5.1
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,4 +1,3 @@
1
- import base64
2
1
  import json
3
2
  import logging
4
3
  from datetime import datetime
@@ -59,12 +58,12 @@ class TextMessagePart(BaseModel):
59
58
 
60
59
  class MediaMessagePart(BaseModel):
61
60
  content_type: UserMediaContentType
62
- content: bytes
61
+ content: str
63
62
 
64
63
  def render(self) -> LLMMediaMessagePart:
65
64
  return {
66
65
  "type": "image_url",
67
- "image_url": f"data:{self.content_type};base64,{base64.b64encode(self.content).decode()}",
66
+ "image_url": f"data:{self.content_type};base64,{self.content}",
68
67
  }
69
68
 
70
69
 
@@ -18,13 +18,14 @@ from pydantic import BaseModel
18
18
  from goose.agent import (
19
19
  Agent,
20
20
  AssistantMessage,
21
+ GeminiModel,
21
22
  IAgentLogger,
22
23
  LLMMessage,
23
24
  SystemMessage,
24
25
  UserMessage,
25
26
  )
26
27
  from goose.errors import Honk
27
- from goose.result import Result
28
+ from goose.result import Result, TextResult
28
29
  from goose.store import IFlowRunStore, InMemoryFlowRunStore
29
30
 
30
31
  SerializedFlowRun = NewType("SerializedFlowRun", str)
@@ -309,10 +310,12 @@ class Task[**P, R: Result]:
309
310
  /,
310
311
  *,
311
312
  retries: int = 0,
313
+ adapter_model: GeminiModel = GeminiModel.FLASH,
312
314
  ) -> None:
313
315
  self._generator = generator
314
- self._adapter: IAdapter[R] | None = None
315
316
  self._retries = retries
317
+ self._adapter_model = adapter_model
318
+ self._adapter_model = adapter_model
316
319
 
317
320
  @property
318
321
  def result_type(self) -> type[R]:
@@ -325,10 +328,6 @@ class Task[**P, R: Result]:
325
328
  def name(self) -> str:
326
329
  return self._generator.__name__
327
330
 
328
- def adapter(self, adapter: IAdapter[R]) -> Self:
329
- self._adapter = adapter
330
- return self
331
-
332
331
  async def generate(
333
332
  self, state: NodeState[R], *args: P.args, **kwargs: P.kwargs
334
333
  ) -> R:
@@ -349,14 +348,12 @@ class Task[**P, R: Result]:
349
348
  ) -> R:
350
349
  flow_run = self.__get_current_flow_run()
351
350
  node_state = flow_run.get(task=self, index=index)
352
- if self._adapter is None:
353
- raise Honk("No adapter provided for Task")
354
351
 
355
352
  if context is not None:
356
353
  node_state.set_context(context=context)
357
354
  node_state.add_user_message(message=user_message)
358
355
 
359
- result = await self._adapter(
356
+ result = await self.__adapt(
360
357
  conversation=node_state.conversation, agent=flow_run.agent
361
358
  )
362
359
  node_state.add_result(result=result)
@@ -371,15 +368,34 @@ class Task[**P, R: Result]:
371
368
  flow_run.add_node_state(node_state)
372
369
  return result
373
370
 
371
+ async def __adapt(self, *, conversation: Conversation[R], agent: Agent) -> R:
372
+ messages: list[UserMessage | AssistantMessage] = []
373
+ for message_index in range(len(conversation.user_messages)):
374
+ user_message = conversation.user_messages[message_index]
375
+ result = conversation.result_messages[message_index]
376
+
377
+ if isinstance(result, TextResult):
378
+ assistant_text = result.text
379
+ else:
380
+ assistant_text = result.model_dump_json()
381
+ assistant_message = AssistantMessage(text=assistant_text)
382
+ messages.append(assistant_message)
383
+ messages.append(user_message)
384
+
385
+ return await agent(
386
+ messages=messages,
387
+ model=self._adapter_model,
388
+ task_name=f"adapt--{self.name}",
389
+ system=conversation.context,
390
+ response_model=self.result_type,
391
+ )
392
+
374
393
  def __hash_task_call(self, *args: P.args, **kwargs: P.kwargs) -> int:
375
394
  try:
376
395
  to_hash = str(
377
396
  tuple(args)
378
397
  + tuple(kwargs.values())
379
- + (
380
- self._generator.__code__,
381
- self._adapter.__code__ if self._adapter is not None else None,
382
- )
398
+ + (self._generator.__code__, self._adapter_model)
383
399
  )
384
400
  return hash(to_hash)
385
401
  except TypeError:
@@ -396,22 +412,23 @@ class Task[**P, R: Result]:
396
412
  def task[**P, R: Result](generator: Callable[P, Awaitable[R]], /) -> Task[P, R]: ...
397
413
  @overload
398
414
  def task[**P, R: Result](
399
- *, retries: int = 0
415
+ *, retries: int = 0, adapter_model: GeminiModel = GeminiModel.FLASH
400
416
  ) -> Callable[[Callable[P, Awaitable[R]]], Task[P, R]]: ...
401
417
  def task[**P, R: Result](
402
418
  generator: Callable[P, Awaitable[R]] | None = None,
403
419
  /,
404
420
  *,
405
421
  retries: int = 0,
422
+ adapter_model: GeminiModel = GeminiModel.FLASH,
406
423
  ) -> Task[P, R] | Callable[[Callable[P, Awaitable[R]]], Task[P, R]]:
407
424
  if generator is None:
408
425
 
409
426
  def decorator(fn: Callable[P, Awaitable[R]]) -> Task[P, R]:
410
- return Task(fn, retries=retries)
427
+ return Task(fn, retries=retries, adapter_model=adapter_model)
411
428
 
412
429
  return decorator
413
430
 
414
- return Task(generator, retries=retries)
431
+ return Task(generator, retries=retries, adapter_model=adapter_model)
415
432
 
416
433
 
417
434
  @overload
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "goose-py"
3
- version = "0.4.2"
3
+ version = "0.5.1"
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>",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes