waldiez 0.5.8__py3-none-any.whl → 0.5.10__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.

Potentially problematic release.


This version of waldiez might be problematic. Click here for more details.

Files changed (88) hide show
  1. waldiez/_version.py +1 -1
  2. waldiez/cli.py +112 -24
  3. waldiez/exporting/agent/exporter.py +3 -0
  4. waldiez/exporting/agent/extras/captain_agent_extras.py +44 -7
  5. waldiez/exporting/agent/extras/handoffs/condition.py +3 -1
  6. waldiez/exporting/chats/utils/common.py +25 -23
  7. waldiez/exporting/core/__init__.py +0 -2
  8. waldiez/exporting/core/context.py +13 -13
  9. waldiez/exporting/core/protocols.py +0 -141
  10. waldiez/exporting/core/result.py +5 -5
  11. waldiez/exporting/flow/merger.py +2 -2
  12. waldiez/exporting/flow/orchestrator.py +1 -0
  13. waldiez/exporting/flow/utils/common.py +2 -2
  14. waldiez/exporting/flow/utils/importing.py +1 -0
  15. waldiez/exporting/flow/utils/logging.py +6 -7
  16. waldiez/exporting/tools/exporter.py +5 -0
  17. waldiez/exporting/tools/factory.py +4 -0
  18. waldiez/exporting/tools/processor.py +5 -1
  19. waldiez/io/_ws.py +13 -5
  20. waldiez/io/models/content/image.py +1 -0
  21. waldiez/io/models/user_input.py +4 -4
  22. waldiez/io/models/user_response.py +1 -0
  23. waldiez/io/mqtt.py +1 -1
  24. waldiez/io/structured.py +17 -17
  25. waldiez/io/utils.py +1 -1
  26. waldiez/io/ws.py +9 -11
  27. waldiez/logger.py +180 -63
  28. waldiez/models/agents/agent/update_system_message.py +0 -2
  29. waldiez/models/agents/doc_agent/doc_agent.py +8 -1
  30. waldiez/models/common/dict_utils.py +169 -40
  31. waldiez/models/flow/flow.py +6 -6
  32. waldiez/models/flow/info.py +5 -1
  33. waldiez/models/model/_llm.py +28 -14
  34. waldiez/models/model/model.py +4 -1
  35. waldiez/models/model/model_data.py +18 -5
  36. waldiez/models/tool/predefined/_config.py +5 -1
  37. waldiez/models/tool/predefined/_duckduckgo.py +4 -0
  38. waldiez/models/tool/predefined/_email.py +474 -0
  39. waldiez/models/tool/predefined/_google.py +8 -6
  40. waldiez/models/tool/predefined/_perplexity.py +3 -0
  41. waldiez/models/tool/predefined/_searxng.py +3 -0
  42. waldiez/models/tool/predefined/_tavily.py +4 -1
  43. waldiez/models/tool/predefined/_wikipedia.py +4 -1
  44. waldiez/models/tool/predefined/_youtube.py +4 -1
  45. waldiez/models/tool/predefined/protocol.py +3 -0
  46. waldiez/models/tool/tool.py +22 -4
  47. waldiez/models/waldiez.py +12 -0
  48. waldiez/runner.py +37 -54
  49. waldiez/running/__init__.py +6 -0
  50. waldiez/running/base_runner.py +310 -353
  51. waldiez/running/environment.py +1 -0
  52. waldiez/running/exceptions.py +9 -0
  53. waldiez/running/post_run.py +4 -4
  54. waldiez/running/pre_run.py +51 -40
  55. waldiez/running/protocol.py +21 -101
  56. waldiez/running/run_results.py +1 -1
  57. waldiez/running/standard_runner.py +84 -277
  58. waldiez/running/step_by_step/__init__.py +46 -0
  59. waldiez/running/step_by_step/breakpoints_mixin.py +188 -0
  60. waldiez/running/step_by_step/step_by_step_models.py +224 -0
  61. waldiez/running/step_by_step/step_by_step_runner.py +745 -0
  62. waldiez/running/subprocess_runner/__base__.py +282 -0
  63. waldiez/running/subprocess_runner/__init__.py +16 -0
  64. waldiez/running/subprocess_runner/_async_runner.py +362 -0
  65. waldiez/running/subprocess_runner/_sync_runner.py +455 -0
  66. waldiez/running/subprocess_runner/runner.py +561 -0
  67. waldiez/running/timeline_processor.py +1 -1
  68. waldiez/running/utils.py +376 -1
  69. waldiez/utils/version.py +2 -6
  70. waldiez/ws/__init__.py +70 -0
  71. waldiez/ws/__main__.py +15 -0
  72. waldiez/ws/_file_handler.py +201 -0
  73. waldiez/ws/cli.py +211 -0
  74. waldiez/ws/client_manager.py +835 -0
  75. waldiez/ws/errors.py +416 -0
  76. waldiez/ws/models.py +971 -0
  77. waldiez/ws/reloader.py +342 -0
  78. waldiez/ws/server.py +469 -0
  79. waldiez/ws/session_manager.py +393 -0
  80. waldiez/ws/session_stats.py +83 -0
  81. waldiez/ws/utils.py +385 -0
  82. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/METADATA +74 -74
  83. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/RECORD +87 -65
  84. waldiez/running/patch_io_stream.py +0 -210
  85. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/WHEEL +0 -0
  86. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/entry_points.txt +0 -0
  87. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/licenses/LICENSE +0 -0
  88. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/licenses/NOTICE.md +0 -0
@@ -397,7 +397,7 @@ class WaldiezFlow(WaldiezBase):
397
397
  If no group manager is found.
398
398
  """
399
399
  for agent in self.data.agents.groupManagerAgents:
400
- if agent.data.parent_id is None:
400
+ if agent.data.parent_id is None: # pragma: no branch
401
401
  return agent
402
402
  raise ValueError("No group manager found.")
403
403
 
@@ -431,16 +431,16 @@ class WaldiezFlow(WaldiezBase):
431
431
  to_root_manager: WaldiezChat | None = None
432
432
  root_manager: WaldiezGroupManager = self.get_root_group_manager()
433
433
  for chat in self.data.chats:
434
- if chat.target == root_manager.id:
434
+ if chat.target == root_manager.id: # pragma: no branch
435
435
  # check if the source is a user agent
436
436
  source = self.get_agent_by_id(chat.source)
437
- if source.is_user:
437
+ if source.is_user: # pragma: no branch
438
438
  user_agent = source
439
439
  to_root_manager = chat
440
440
  break
441
- if not to_root_manager:
441
+ if not to_root_manager: # pragma: no cover
442
442
  return []
443
- if not user_agent:
443
+ if not user_agent: # pragma: no cover
444
444
  return []
445
445
  return [
446
446
  {
@@ -572,7 +572,7 @@ class WaldiezFlow(WaldiezBase):
572
572
  - If the model IDs are not unique.
573
573
  - If the tool IDs are not unique.
574
574
  """
575
- if member.is_group_manager:
575
+ if member.is_group_manager: # pragma: no cover
576
576
  raise ValueError(
577
577
  "In single agent mode, the agent must not be a group manager."
578
578
  )
@@ -18,6 +18,8 @@ class WaldiezAgentInfo(WaldiezBase):
18
18
 
19
19
  Attributes
20
20
  ----------
21
+ id : str
22
+ The ID of the agent.
21
23
  name : str
22
24
  The name of the agent.
23
25
  human_input_mode : WaldiezAgentHumanInputMode
@@ -27,6 +29,7 @@ class WaldiezAgentInfo(WaldiezBase):
27
29
  The type of the agent (e.g., "user", "assistant").
28
30
  """
29
31
 
32
+ id: Annotated[str, Field(description="ID of the agent")]
30
33
  name: Annotated[str, Field(description="Name of the agent")]
31
34
  human_input_mode: Annotated[
32
35
  WaldiezAgentHumanInputMode,
@@ -53,7 +56,7 @@ class WaldiezFlowInfo(WaldiezBase):
53
56
  description="List of chat participants with their info",
54
57
  default_factory=list[WaldiezAgentInfo],
55
58
  ),
56
- ]
59
+ ] = []
57
60
 
58
61
  @classmethod
59
62
  def create(
@@ -77,6 +80,7 @@ class WaldiezFlowInfo(WaldiezBase):
77
80
  for agent in agents:
78
81
  participants.append(
79
82
  WaldiezAgentInfo(
83
+ id=agent.id,
80
84
  name=agent_names.get(agent.id, agent.name),
81
85
  human_input_mode=agent.data.human_input_mode,
82
86
  agent_type=agent.agent_type,
@@ -33,7 +33,7 @@ if TYPE_CHECKING:
33
33
 
34
34
  def get_llm_requirements(
35
35
  model: "WaldiezModel",
36
- ag2_version: str,
36
+ ag2_version: str, # pylint: disable=unused-argument
37
37
  ) -> set[str]:
38
38
  """Get the LLM requirements for the model.
39
39
 
@@ -50,9 +50,16 @@ def get_llm_requirements(
50
50
  The set of LLM requirements for the model.
51
51
  """
52
52
  requirements: set[str] = {
53
+ # f"ag2[rag]=={ag2_version}",
54
+ "chromadb>=0.5,<2",
55
+ "docling>=2.15.1,<3",
56
+ "selenium>=4.28.1,<5",
57
+ "webdriver-manager==4.0.2",
53
58
  "llama-index",
54
59
  "llama-index-core",
55
- f"ag2[rag]=={ag2_version}",
60
+ "llama-index-embeddings-huggingface",
61
+ "llama-index-llms-langchain",
62
+ "llama-index-vector-stores-chroma",
56
63
  }
57
64
  match model.data.api_type:
58
65
  case "openai":
@@ -87,7 +94,7 @@ def get_llm_requirements(
87
94
  )
88
95
  case "together":
89
96
  requirements.add("llama-index-llms-together")
90
- case "other":
97
+ case "other": # pragma: no cover
91
98
  # openai compatible LLMs
92
99
  requirements.add("llama-index-llms-openai-like")
93
100
 
@@ -279,9 +286,9 @@ def do_azure_llm(model: "WaldiezModel") -> tuple[str, str]:
279
286
  f' model="{model.name}",\n'
280
287
  f" temperature={temperature},\n"
281
288
  )
282
- if model.data.base_url:
289
+ if model.data.base_url: # pragma: no branch
283
290
  arg += f' azure_endpoint="{model.data.base_url}",\n'
284
- if model.data.api_version:
291
+ if model.data.api_version: # pragma: no branch
285
292
  arg += f' api_version="{model.data.api_version}",\n'
286
293
  arg += ")"
287
294
  before = ""
@@ -322,11 +329,11 @@ def do_bedrock_llm(model: "WaldiezModel") -> tuple[str, str]:
322
329
  aws_access_key_id = model.data.aws.access_key or ""
323
330
  aws_region = model.data.aws.region or ""
324
331
  arg = f'BedrockConverse(\n model="{model.name}",\n'
325
- if profile_name:
332
+ if profile_name: # pragma: no branch
326
333
  arg += f' profile_name="{profile_name}",\n'
327
- if aws_access_key_id:
334
+ if aws_access_key_id: # pragma: no branch
328
335
  arg += f' aws_access_key_id="{aws_access_key_id}",\n'
329
- if aws_region:
336
+ if aws_region: # pragma: no branch
330
337
  arg += f' region_name="{aws_region}",\n'
331
338
  arg += ")"
332
339
  before = ""
@@ -347,11 +354,11 @@ def do_cohere_llm(model: "WaldiezModel") -> tuple[str, str]:
347
354
  A tuple containing the LLM argument string and any content before it.
348
355
  """
349
356
  arg = f'Cohere(\n model="{model.name}",\n'
350
- if model.data.api_key:
357
+ if model.data.api_key: # pragma: no branch
351
358
  arg += f' api_key="{model.data.api_key}",\n'
352
- if model.data.base_url:
359
+ if model.data.base_url: # pragma: no branch
353
360
  arg += f' base_url="{model.data.base_url}",\n'
354
- if model.data.temperature is not None:
361
+ if model.data.temperature is not None: # pragma: no branch
355
362
  arg += f" temperature={model.data.temperature},\n"
356
363
  arg += ")"
357
364
  before = ""
@@ -507,11 +514,18 @@ def do_other_llm(model: "WaldiezModel") -> tuple[str, str]:
507
514
  f' model="{model.name}",\n'
508
515
  f' api_base="{model.data.base_url}",\n'
509
516
  )
510
- if not model.data.api_key:
517
+ if not model.data.api_key: # pragma: no cover
511
518
  arg += ' api_key="na",\n'
512
- if model.data.extras:
519
+ else:
520
+ arg += f' api_key="{model.data.api_key}",\n'
521
+ if model.data.temperature is not None: # pragma: no branch
522
+ arg += f" temperature={model.data.temperature},\n"
523
+ if model.data.extras: # pragma: no branch
513
524
  for key, value in model.data.extras.items():
514
- arg += f' {key}="{value}",\n'
525
+ if isinstance(value, str):
526
+ arg += f' {key}="{value}",\n'
527
+ else:
528
+ arg += f" {key}={value},\n"
515
529
  arg += ")"
516
530
  # if model.data.price:
517
531
  before = ""
@@ -213,7 +213,7 @@ class WaldiezModel(WaldiezBase):
213
213
  optionals: list[tuple[str, type]] = [
214
214
  ("base_url", str),
215
215
  ("max_tokens", int),
216
- # ("temperature", float),
216
+ ("temperature", float),
217
217
  ("top_p", float),
218
218
  ("api_version", str),
219
219
  ("default_headers", dict),
@@ -229,6 +229,9 @@ class WaldiezModel(WaldiezBase):
229
229
  value = getattr(self, attr)
230
230
  if value:
231
231
  _llm_config[attr] = value
232
+ if "top_p" in _llm_config and "temperature" in _llm_config:
233
+ # only keep one
234
+ _llm_config.pop("top_p", None)
232
235
  if self.data.api_type == "bedrock":
233
236
  _llm_config.pop("base_url", None)
234
237
  return set_bedrock_aws_config(_llm_config, self.data.aws)
@@ -3,12 +3,12 @@
3
3
  # flake8: noqa: E501
4
4
  """Waldiez Model Data."""
5
5
 
6
- from typing import Optional
6
+ from typing import Any, Optional
7
7
 
8
- from pydantic import Field
9
- from typing_extensions import Annotated, Literal
8
+ from pydantic import Field, model_validator
9
+ from typing_extensions import Annotated, Literal, Self
10
10
 
11
- from ..common import WaldiezBase
11
+ from ..common import WaldiezBase, update_dict
12
12
  from ._aws import WaldiezModelAWS
13
13
  from ._price import WaldiezModelPrice
14
14
 
@@ -131,7 +131,7 @@ class WaldiezModelData(WaldiezBase):
131
131
  ),
132
132
  ] = None
133
133
  extras: Annotated[
134
- dict[str, str],
134
+ dict[str, Any],
135
135
  Field(
136
136
  alias="extras",
137
137
  default_factory=dict,
@@ -154,3 +154,16 @@ class WaldiezModelData(WaldiezBase):
154
154
  default=None, title="Price", description="The price of the model"
155
155
  ),
156
156
  ] = None
157
+
158
+ @model_validator(mode="after")
159
+ def validate_model_data(self) -> Self:
160
+ """Validate model data.
161
+
162
+ Returns
163
+ -------
164
+ WaldiezModelData
165
+ The validated model data.
166
+ """
167
+ if self.extras:
168
+ self.extras = update_dict(self.extras)
169
+ return self
@@ -3,6 +3,7 @@
3
3
  """Predefined tool configuration for Waldiez."""
4
4
 
5
5
  from dataclasses import dataclass
6
+ from typing import Any
6
7
 
7
8
  from .protocol import PredefinedTool
8
9
 
@@ -52,6 +53,7 @@ class PredefinedToolConfig:
52
53
  def get_content(
53
54
  self,
54
55
  secrets: dict[str, str],
56
+ runtime_kwargs: dict[str, Any] | None = None,
55
57
  ) -> str:
56
58
  """Get the content of the tool.
57
59
 
@@ -59,10 +61,12 @@ class PredefinedToolConfig:
59
61
  ----------
60
62
  secrets : dict[str, str]
61
63
  Dictionary of secrets/environment variables.
64
+ runtime_kwargs : dict[str, Any] | None, optional
65
+ Runtime keyword arguments to customize the content generation.
62
66
 
63
67
  Returns
64
68
  -------
65
69
  str
66
70
  Content of the tool.
67
71
  """
68
- return self.implementation.get_content(secrets)
72
+ return self.implementation.get_content(secrets, runtime_kwargs)
@@ -81,6 +81,7 @@ class DuckDuckGoSearchToolImpl(PredefinedTool):
81
81
  def get_content(
82
82
  self,
83
83
  secrets: dict[str, str],
84
+ runtime_kwargs: dict[str, Any] | None = None,
84
85
  ) -> str:
85
86
  """Get content for the tool.
86
87
 
@@ -89,6 +90,9 @@ class DuckDuckGoSearchToolImpl(PredefinedTool):
89
90
  secrets : dict[str, str]
90
91
  Dictionary of secrets/environment variables.
91
92
 
93
+ runtime_kwargs : dict[str, Any] | None, optional
94
+ Runtime keyword arguments to customize the content generation.
95
+
92
96
  Returns
93
97
  -------
94
98
  str