grasp_agents 0.3.3__py3-none-any.whl → 0.3.6__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.
grasp_agents/cloud_llm.py CHANGED
@@ -127,21 +127,32 @@ class CloudLLM(LLM[SettingsT_co, ConvertT_co], Generic[SettingsT_co, ConvertT_co
127
127
  )
128
128
 
129
129
  self._model_name = model_name
130
+ model_name_parts = model_name.split(":", 1)
131
+
132
+ if len(model_name_parts) == 2 and model_name_parts[0] in PROVIDERS:
133
+ api_provider, api_model_name = model_name_parts
134
+ if api_provider not in PROVIDERS:
135
+ raise ValueError(
136
+ f"API provider '{api_provider}' is not supported. "
137
+ f"Supported providers are: {', '.join(PROVIDERS.keys())}"
138
+ )
130
139
 
131
- api_provider = model_name.split(":", 1)[0]
132
- api_model_name = model_name.split(":", 1)[-1]
133
- if api_provider not in PROVIDERS:
134
- raise ValueError(
135
- f"API provider '{api_provider}' is not supported. "
136
- f"Supported providers are: {', '.join(PROVIDERS.keys())}"
140
+ self._api_provider: APIProvider | None = api_provider
141
+ self._api_model_name: str = api_model_name
142
+ self._base_url: str | None = PROVIDERS[api_provider]["base_url"]
143
+ self._api_key: str | None = PROVIDERS[api_provider]["api_key"]
144
+ self._struct_outputs_support: bool = any(
145
+ fnmatch.fnmatch(self._model_name, pat)
146
+ for pat in PROVIDERS[api_provider]["struct_outputs_support"]
137
147
  )
138
- self._api_provider: APIProvider = api_provider
139
- self._api_model_name: str = api_model_name
140
148
 
141
- self._struct_outputs_support: bool = any(
142
- fnmatch.fnmatch(self._model_name, pat)
143
- for pat in PROVIDERS[api_provider]["struct_outputs_support"]
144
- )
149
+ else:
150
+ self._api_provider = None
151
+ self._api_model_name = model_name
152
+ self._base_url = None
153
+ self._api_key = None
154
+ self._struct_outputs_support = False
155
+
145
156
  if (
146
157
  self._llm_settings.get("use_struct_outputs")
147
158
  and not self._struct_outputs_support
@@ -161,9 +172,6 @@ class CloudLLM(LLM[SettingsT_co, ConvertT_co], Generic[SettingsT_co, ConvertT_co
161
172
  )
162
173
  )
163
174
  self.no_tqdm = no_tqdm
164
-
165
- self._base_url: str = PROVIDERS[api_provider]["base_url"]
166
- self._api_key: str | None = PROVIDERS[api_provider]["api_key"]
167
175
  self._client: Any
168
176
 
169
177
  self._async_http_client: httpx.AsyncClient | None = None
@@ -178,7 +186,7 @@ class CloudLLM(LLM[SettingsT_co, ConvertT_co], Generic[SettingsT_co, ConvertT_co
178
186
  self.num_generation_retries = num_generation_retries
179
187
 
180
188
  @property
181
- def api_provider(self) -> APIProvider:
189
+ def api_provider(self) -> APIProvider | None:
182
190
  return self._api_provider
183
191
 
184
192
  @property
grasp_agents/llm.py CHANGED
@@ -39,7 +39,7 @@ class LLM(ABC, Generic[SettingsT_co, ConvertT_co]):
39
39
  model_id: str | None = None,
40
40
  llm_settings: SettingsT_co | None = None,
41
41
  tools: list[BaseTool[BaseModel, Any, Any]] | None = None,
42
- response_format: type | Mapping[str, type] | None = None,
42
+ response_format: Any | Mapping[str, Any] | None = None,
43
43
  **kwargs: Any,
44
44
  ) -> None:
45
45
  super().__init__()
@@ -51,15 +51,19 @@ class LLM(ABC, Generic[SettingsT_co, ConvertT_co]):
51
51
  self._llm_settings: SettingsT_co = llm_settings or cast("SettingsT_co", {})
52
52
 
53
53
  self._response_format = response_format
54
- self._response_format_adapter: TypeAdapter[Any] | Mapping[str, TypeAdapter[Any]]
55
- if isinstance(response_format, type):
56
- self._response_format_adapter = TypeAdapter(response_format)
57
- elif isinstance(response_format, Mapping):
58
- self._response_format_adapter = {
59
- k: TypeAdapter(v) for k, v in response_format.items()
60
- }
61
- else:
62
- self._response_format_adapter = TypeAdapter(Any)
54
+ self._response_format_adapter: (
55
+ TypeAdapter[Any] | Mapping[str, TypeAdapter[Any]]
56
+ ) = self._get_response_format_adapter(response_format=response_format)
57
+
58
+ @staticmethod
59
+ def _get_response_format_adapter(
60
+ response_format: Any | Mapping[str, Any] | None = None,
61
+ ) -> TypeAdapter[Any] | Mapping[str, TypeAdapter[Any]]:
62
+ if response_format is None:
63
+ return TypeAdapter(Any)
64
+ if isinstance(response_format, Mapping):
65
+ return {k: TypeAdapter(v) for k, v in response_format.items()} # type: ignore[return-value]
66
+ return TypeAdapter(response_format)
63
67
 
64
68
  @property
65
69
  def model_id(self) -> str:
@@ -74,23 +78,24 @@ class LLM(ABC, Generic[SettingsT_co, ConvertT_co]):
74
78
  return self._llm_settings
75
79
 
76
80
  @property
77
- def tools(self) -> dict[str, BaseTool[BaseModel, Any, Any]] | None:
78
- return self._tools
81
+ def response_format(self) -> Any | Mapping[str, Any] | None:
82
+ return self._response_format
83
+
84
+ @response_format.setter
85
+ def response_format(self, response_format: Any | Mapping[str, Any] | None) -> None:
86
+ self._response_format = response_format
87
+ self._response_format_adapter = self._get_response_format_adapter(
88
+ response_format
89
+ )
79
90
 
80
91
  @property
81
- def response_format(self) -> type | Mapping[str, type] | None:
82
- return self._response_format
92
+ def tools(self) -> dict[str, BaseTool[BaseModel, Any, Any]] | None:
93
+ return self._tools
83
94
 
84
95
  @tools.setter
85
96
  def tools(self, tools: list[BaseTool[BaseModel, Any, Any]] | None) -> None:
86
97
  self._tools = {t.name: t for t in tools} if tools else None
87
98
 
88
- @response_format.setter
89
- def response_format(
90
- self, response_format: type | Mapping[str, type] | None
91
- ) -> None:
92
- self._response_format = response_format
93
-
94
99
  def __repr__(self) -> str:
95
100
  return (
96
101
  f"{type(self).__name__}(model_id={self.model_id}; "
@@ -101,9 +106,7 @@ class LLM(ABC, Generic[SettingsT_co, ConvertT_co]):
101
106
  for message in completion.messages:
102
107
  if not message.tool_calls:
103
108
  validate_obj_from_json_or_py_string(
104
- message.content or "",
105
- adapter=self._response_format_adapter,
106
- from_substring=True,
109
+ message.content or "", adapter=self._response_format_adapter
107
110
  )
108
111
 
109
112
  def _validate_tool_calls(self, completion: Completion) -> None:
grasp_agents/llm_agent.py CHANGED
@@ -63,9 +63,9 @@ class LLMAgent(
63
63
  sys_prompt: LLMPrompt | None = None,
64
64
  sys_prompt_path: str | Path | None = None,
65
65
  # System args (static args provided via RunContext)
66
- sys_args_schema: type[LLMPromptArgs] = LLMPromptArgs,
66
+ sys_args_schema: type[LLMPromptArgs] | None = None,
67
67
  # User args (static args provided via RunContext)
68
- usr_args_schema: type[LLMPromptArgs] = LLMPromptArgs,
68
+ usr_args_schema: type[LLMPromptArgs] | None = None,
69
69
  # Agent loop settings
70
70
  max_turns: int = 100,
71
71
  react_mode: bool = False,
@@ -82,14 +82,13 @@ class LLMAgent(
82
82
 
83
83
  self._memory: LLMAgentMemory = LLMAgentMemory()
84
84
  self._reset_memory_on_run = reset_memory_on_run
85
- self._set_memory_impl: SetMemoryHandler | None = None
86
85
 
87
86
  # LLM policy executor
88
87
 
89
- self._using_default_llm_response_format: bool = False
88
+ self._used_default_llm_response_format: bool = False
90
89
  if llm.response_format is None and tools is None:
91
90
  llm.response_format = self.out_type
92
- self._using_default_llm_response_format = True
91
+ self._used_default_llm_response_format = True
93
92
 
94
93
  self._policy_executor: LLMPolicyExecutor[OutT_co, CtxT] = LLMPolicyExecutor[
95
94
  self.out_type, CtxT
@@ -118,6 +117,10 @@ class LLMAgent(
118
117
 
119
118
  self.no_tqdm = getattr(llm, "no_tqdm", False)
120
119
 
120
+ self._set_memory_impl: SetMemoryHandler | None = None
121
+ self._parse_output_impl: (
122
+ ParseOutputHandler[InT_contra, OutT_co, CtxT] | None
123
+ ) = None
121
124
  self._register_overridden_handlers()
122
125
 
123
126
  @property
@@ -148,32 +151,6 @@ class LLMAgent(
148
151
  def in_prompt(self) -> LLMPrompt | None:
149
152
  return self._prompt_builder.in_prompt_template
150
153
 
151
- def _parse_output(
152
- self,
153
- conversation: Messages,
154
- *,
155
- in_args: InT_contra | None = None,
156
- batch_idx: int = 0,
157
- ctx: RunContext[CtxT] | None = None,
158
- ) -> OutT_co:
159
- if self._parse_output_impl:
160
- if self._using_default_llm_response_format:
161
- # When using custom output parsing, the required LLM response format
162
- # can differ from the final agent output type ->
163
- # set it back to None unless it was specified explicitly at init.
164
- self._policy_executor.llm.response_format = None
165
- # self._using_default_llm_response_format = False
166
-
167
- return self._parse_output_impl(
168
- conversation=conversation, in_args=in_args, batch_idx=batch_idx, ctx=ctx
169
- )
170
-
171
- return validate_obj_from_json_or_py_string(
172
- str(conversation[-1].content or ""),
173
- adapter=self._out_type_adapter,
174
- from_substring=True,
175
- )
176
-
177
154
  def _memorize_inputs(
178
155
  self,
179
156
  chat_inputs: LLMPrompt | Sequence[str | ImageData] | None = None,
@@ -251,6 +228,25 @@ class LLMAgent(
251
228
 
252
229
  return outputs
253
230
 
231
+ def _parse_output(
232
+ self,
233
+ conversation: Messages,
234
+ *,
235
+ in_args: InT_contra | None = None,
236
+ batch_idx: int = 0,
237
+ ctx: RunContext[CtxT] | None = None,
238
+ ) -> OutT_co:
239
+ if self._parse_output_impl:
240
+ return self._parse_output_impl(
241
+ conversation=conversation, in_args=in_args, batch_idx=batch_idx, ctx=ctx
242
+ )
243
+
244
+ return validate_obj_from_json_or_py_string(
245
+ str(conversation[-1].content or ""),
246
+ adapter=self._out_type_adapter,
247
+ from_substring=True,
248
+ )
249
+
254
250
  async def _process(
255
251
  self,
256
252
  chat_inputs: LLMPrompt | Sequence[str | ImageData] | None = None,
@@ -330,6 +326,8 @@ class LLMAgent(
330
326
  def parse_output(
331
327
  self, func: ParseOutputHandler[InT_contra, OutT_co, CtxT]
332
328
  ) -> ParseOutputHandler[InT_contra, OutT_co, CtxT]:
329
+ if self._used_default_llm_response_format:
330
+ self._policy_executor.llm.response_format = None
333
331
  self._parse_output_impl = func
334
332
 
335
333
  return func
@@ -376,9 +374,11 @@ class LLMAgent(
376
374
  ):
377
375
  self._policy_executor.exit_tool_call_loop_impl = self._exit_tool_call_loop
378
376
 
379
- self._parse_output_impl: (
380
- ParseOutputHandler[InT_contra, OutT_co, CtxT] | None
381
- ) = None
377
+ if (
378
+ cur_cls._parse_output is not base_cls._parse_output # noqa: SLF001
379
+ and self._used_default_llm_response_format
380
+ ):
381
+ self._policy_executor.llm.response_format = None
382
382
 
383
383
  def _make_system_prompt(
384
384
  self, sys_args: LLMPromptArgs | None, *, ctx: RunContext[CtxT] | None = None
@@ -80,6 +80,7 @@ class OpenAILLM(CloudLLM[OpenAILLMSettings, OpenAIConverters]):
80
80
  dict[str, Any] | AsyncHTTPClientParams | None
81
81
  ) = None,
82
82
  async_openai_client_params: dict[str, Any] | None = None,
83
+ client: AsyncOpenAI | None = None,
83
84
  # Rate limiting
84
85
  rate_limiter: (RateLimiterC[Messages, AssistantMessage] | None) = None,
85
86
  rate_limiter_rpm: float | None = None,
@@ -117,11 +118,14 @@ class OpenAILLM(CloudLLM[OpenAILLMSettings, OpenAIConverters]):
117
118
  _async_openai_client_params["http_client"] = self._async_http_client
118
119
 
119
120
  # TODO: context manager for async client
120
- self._client: AsyncOpenAI = AsyncOpenAI(
121
- base_url=self._base_url,
122
- api_key=self._api_key,
123
- **_async_openai_client_params,
124
- )
121
+ if client:
122
+ self._client = client
123
+ else:
124
+ self._client: AsyncOpenAI = AsyncOpenAI(
125
+ base_url=self._base_url,
126
+ api_key=self._api_key,
127
+ **_async_openai_client_params,
128
+ )
125
129
 
126
130
  async def _get_completion(
127
131
  self,
grasp_agents/printer.py CHANGED
@@ -135,7 +135,7 @@ class Printer:
135
135
  elif self.color_by == "role":
136
136
  tool_color = self.get_role_color(role=Role.TOOL)
137
137
  logger.debug(
138
- f"\n[TOOL_CALL]<{agent_name}>\n{tool_call.tool_name} "
138
+ f"\n<{agent_name}>[TOOL_CALL]\n{tool_call.tool_name} "
139
139
  f"| {tool_call.id}\n{tool_call.tool_arguments}",
140
140
  extra={"color": tool_color}, # type: ignore
141
141
  )
@@ -79,9 +79,7 @@ class PromptBuilder(AutoInstanceAttributesMixin, Generic[InT_contra, CtxT]):
79
79
  if self.make_system_prompt_impl:
80
80
  return self.make_system_prompt_impl(sys_args=val_sys_args, ctx=ctx)
81
81
 
82
- sys_args_dict = (
83
- val_sys_args.model_dump(exclude_unset=True) if val_sys_args else {}
84
- )
82
+ sys_args_dict = val_sys_args.model_dump() if val_sys_args else {}
85
83
 
86
84
  return self.sys_prompt_template.format(**sys_args_dict)
87
85
 
@@ -208,10 +206,7 @@ class PromptBuilder(AutoInstanceAttributesMixin, Generic[InT_contra, CtxT]):
208
206
  return formatted_args, contains_image_data
209
207
 
210
208
  def _combine_args(
211
- self,
212
- *,
213
- in_args: InT_contra | None,
214
- usr_args: LLMPromptArgs | None,
209
+ self, *, in_args: InT_contra | None, usr_args: LLMPromptArgs | None
215
210
  ) -> Mapping[str, PromptArgumentType] | str:
216
211
  fmt_usr_args, _ = (
217
212
  self._format_pydantic_prompt_args(usr_args) if usr_args else ({}, False)
@@ -13,8 +13,8 @@ from .usage_tracker import UsageTracker
13
13
 
14
14
 
15
15
  class RunArgs(BaseModel):
16
- sys: LLMPromptArgs = Field(default_factory=LLMPromptArgs)
17
- usr: LLMPromptArgs = Field(default_factory=LLMPromptArgs)
16
+ sys: LLMPromptArgs | None = None
17
+ usr: LLMPromptArgs | None = None
18
18
 
19
19
  model_config = ConfigDict(extra="forbid")
20
20
 
grasp_agents/utils.py CHANGED
@@ -6,7 +6,7 @@ from collections.abc import Coroutine, Mapping
6
6
  from datetime import UTC, datetime
7
7
  from logging import getLogger
8
8
  from pathlib import Path
9
- from typing import Any, TypeVar, overload
9
+ from typing import Any, TypeVar, get_args, overload
10
10
 
11
11
  from pydantic import TypeAdapter, ValidationError
12
12
  from tqdm.autonotebook import tqdm
@@ -88,21 +88,24 @@ def validate_obj_from_json_or_py_string(
88
88
  else:
89
89
  _selected_adapter = adapter
90
90
 
91
- if _selected_adapter._type is str: # type: ignore[arg-type]
92
- return s
91
+ _type = _selected_adapter._type # type: ignore[attr-defined]
92
+ type_args = get_args(_type)
93
+ is_str_type = (_type is str) or (len(type_args) == 1 and type_args[0] is str)
93
94
 
94
95
  try:
95
- if from_substring:
96
- parsed = parse_json_or_py_substring(s, return_none_on_failure=True)
96
+ if not is_str_type:
97
+ if from_substring:
98
+ parsed = parse_json_or_py_substring(s, return_none_on_failure=True)
99
+ else:
100
+ parsed = parse_json_or_py_string(s, return_none_on_failure=True)
101
+ if parsed is None:
102
+ parsed = s
97
103
  else:
98
- parsed = parse_json_or_py_string(s, return_none_on_failure=True)
99
- if parsed is None:
100
104
  parsed = s
101
105
  return _selected_adapter.validate_python(parsed)
102
106
  except (json.JSONDecodeError, ValidationError) as exc:
103
107
  raise ValueError(
104
- f"Invalid JSON or Python string:\n{s}\n"
105
- f"Expected type: {_selected_adapter._type}", # type: ignore[arg-type]
108
+ f"Invalid JSON or Python string:\n{s}\nExpected type: {_type}"
106
109
  ) from exc
107
110
 
108
111
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: grasp_agents
3
- Version: 0.3.3
3
+ Version: 0.3.6
4
4
  Summary: Grasp Agents Library
5
5
  License-File: LICENSE.md
6
6
  Requires-Python: <4,>=3.11.4
@@ -1,31 +1,31 @@
1
1
  grasp_agents/__init__.py,sha256=CIsyUasb9HBC3M4olg6ATAwKXtVNmmtpyGJrt7hpZW4,947
2
- grasp_agents/cloud_llm.py,sha256=Psta1FH0YpBUxLnQJ55KUS5o7-eMR-uxrAP_AEUbupk,13427
2
+ grasp_agents/cloud_llm.py,sha256=S3yl-bKhAyThs5drHS_hmkmWa_mTlaC-guTX84v6KXM,13798
3
3
  grasp_agents/comm_processor.py,sha256=YzvvHgrSrgn1oXEpkGXNrAtogFyq6gpS0UrVMBO7LBY,6722
4
4
  grasp_agents/costs_dict.yaml,sha256=2MFNWtkv5W5WSCcv1Cj13B1iQLVv5Ot9pS_KW2Gu2DA,2510
5
5
  grasp_agents/generics_utils.py,sha256=5Pw3I9dlnKC2VGqYKC4ZZUO3Z_vTNT-NPFovNfPkl6I,6542
6
6
  grasp_agents/grasp_logging.py,sha256=H1GYhXdQvVkmauFDZ-KDwvVmPQHZUUm9sRqX_ObK2xI,1111
7
7
  grasp_agents/http_client.py,sha256=KZva2MjJjuI5ohUeU8RdTAImUnQYaqBrV2jDH8smbJw,738
8
- grasp_agents/llm.py,sha256=5Yn4jkBPSbGVMf1sEuYXX6YrJlYZiH7oqKLY0yQIn-U,5192
9
- grasp_agents/llm_agent.py,sha256=a9TCUpQJwpC5Y0dnTqh5bhRLNsQt8pQOjp9d_7QGRVY,14791
8
+ grasp_agents/llm.py,sha256=vVjELab9l0mK9bjO-IJebmmXUyUiws2fNjbXVQQNRvs,5392
9
+ grasp_agents/llm_agent.py,sha256=_Fb3PAfw5okbsybz-BsUkd4kN8K9D5Sjw3HCbDHJFGk,14697
10
10
  grasp_agents/llm_agent_memory.py,sha256=kD_UIF8xVgbSgW6xN87TzkdQcbTWLB-C5ZQu1_2HLx8,1770
11
11
  grasp_agents/llm_policy_executor.py,sha256=PVNuAejt3S-aSGsT7HvgYHyX_cZQSvrt1aUGPdkXtE4,17847
12
12
  grasp_agents/memory.py,sha256=gPkVIIF6dI_xXzarIAw9kSEnSJcfW_teUsWA2JAih94,671
13
13
  grasp_agents/message_history.py,sha256=-ZNy3C1z0yQeahjqR0oIoWDMySJ7vPS19jdutibW7OE,5408
14
14
  grasp_agents/packet.py,sha256=PZ1EpclniAoLk7z4ieZbWzgYH3JSRgnlTe_WfbJYG_4,707
15
15
  grasp_agents/packet_pool.py,sha256=9umHbi5FwuUYYhhodSR-Z-fRR6OYiZyYEzq5d4nZFK4,3036
16
- grasp_agents/printer.py,sha256=eVpSZMVk4ZLkV78Sgfg1euzkaS3XBCb30yJcwLMqI0w,5464
16
+ grasp_agents/printer.py,sha256=M-gkLrZMg0ll9T1MRmKOQbp65niFB5ZiZbm-tUT_EYw,5464
17
17
  grasp_agents/processor.py,sha256=Atd_iTQNd3Nudb4mHqt3a5AQ31QUgpbrt1Fhn1sgpSk,6708
18
- grasp_agents/prompt_builder.py,sha256=CGs7ADlGGmRyDqgFte36cYXKsB3C7SjzqSbkRaWlLN8,8481
19
- grasp_agents/run_context.py,sha256=0y1JDbz3hJbGiqd3EjUYagkMbEK8YlCzdErp3R2MCr0,1647
18
+ grasp_agents/prompt_builder.py,sha256=1o7eMO4FxqRrrXFCj7aQKIajty6jZbBVaUZv7qOMIoY,8414
19
+ grasp_agents/run_context.py,sha256=9CidWWCKJ8umlhkRGtg_P3JQsRpH0K3_vhUjgVon4Wk,1597
20
20
  grasp_agents/usage_tracker.py,sha256=SPwv6RpdoHRuMIKE2hCAWAvDbtR3uXuhr2jpHQuKWhI,3438
21
- grasp_agents/utils.py,sha256=GyJNHkMHnQM3WOUGWD05GpY-iWSd9TtZxfUnFUw9Im0,4605
21
+ grasp_agents/utils.py,sha256=WNA5b0IkAsth0XKHEjgTY3PIHdw5L3vEsYPkyDGw8Mw,4741
22
22
  grasp_agents/openai/__init__.py,sha256=wpTeew6EjhM6esHCKrEKUpwq0kygMN2QQDxYtmbRG8Y,4201
23
23
  grasp_agents/openai/completion_chunk_converters.py,sha256=i-1SvIWhRKtL0K8p5pb3jjACSnyHuJHTCoZovEERpxs,2628
24
24
  grasp_agents/openai/completion_converters.py,sha256=vzPEkUOX4l2hobKxZjEk_dyWfzeYesO0DlvWvNVb-Sg,2656
25
25
  grasp_agents/openai/content_converters.py,sha256=r1D5uci5x7sbDyl0XN27y-l_jVigCauJruvSdZSnZcc,2510
26
26
  grasp_agents/openai/converters.py,sha256=ncscVyPnPMMbyxAfFX3U73lnr_BZU-I89HA5Ld8BuxI,4691
27
27
  grasp_agents/openai/message_converters.py,sha256=_fG4vI42rBzoajuC5iYgnUBalg8cQ1ckSt8xFBOuWVY,4111
28
- grasp_agents/openai/openai_llm.py,sha256=sd1nE5eLUMA8NBqUkSwo_BTfyEBmp9j7Gpuf_s0abw4,7961
28
+ grasp_agents/openai/openai_llm.py,sha256=Hm2S2yyrR3cRvH20YHRegoTEYaetbx_USxI8CXIhfro,8091
29
29
  grasp_agents/openai/tool_converters.py,sha256=d_7edJbnUhfSs2-F4J20D71UjVJWIslsXwMyac7-v2Q,1246
30
30
  grasp_agents/rate_limiting/__init__.py,sha256=KRgtF_E7R3YfA2cpYcFcZ7wycV0pWVJ0xRQC7YhiIEQ,158
31
31
  grasp_agents/rate_limiting/rate_limiter_chunked.py,sha256=BPgkUXvhmZhTpZs2T6uujNFuxH_kYHiISuf6_-eNhUc,5544
@@ -45,7 +45,7 @@ grasp_agents/workflow/looped_workflow.py,sha256=QqXclXYxsW6C8Rxkf3dRaMHi-DfCvCbj
45
45
  grasp_agents/workflow/parallel_processor.py,sha256=Xyzs2UR_mRe2GFgzzadHOhqgMu3rFjd3GUjvmZimt_k,3505
46
46
  grasp_agents/workflow/sequential_workflow.py,sha256=Pl7jl9ZVDu-rC5UMfympEaQN8iG3kZurVF5eIPG62XA,2130
47
47
  grasp_agents/workflow/workflow_processor.py,sha256=2-iaDIlgNXgj-ClGbiE3fYfSv-N_qRC49Gf_dF6M_40,2640
48
- grasp_agents-0.3.3.dist-info/METADATA,sha256=bV-dofgYSNMv1JHo7kxOZKD6DFDKAb4pHL5yeApC2aA,6806
49
- grasp_agents-0.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
- grasp_agents-0.3.3.dist-info/licenses/LICENSE.md,sha256=-nNNdWqGB8gJ2O-peFQ2Irshv5tW5pHKyTcYkwvH7CE,1201
51
- grasp_agents-0.3.3.dist-info/RECORD,,
48
+ grasp_agents-0.3.6.dist-info/METADATA,sha256=kwdiPSqyVZ1B3kjjQFbyDDzdm0eokb6k0krwHqZWQ0s,6806
49
+ grasp_agents-0.3.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
+ grasp_agents-0.3.6.dist-info/licenses/LICENSE.md,sha256=-nNNdWqGB8gJ2O-peFQ2Irshv5tW5pHKyTcYkwvH7CE,1201
51
+ grasp_agents-0.3.6.dist-info/RECORD,,