lionagi 0.17.9__py3-none-any.whl → 0.17.11__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.
Files changed (151) hide show
  1. lionagi/__init__.py +1 -2
  2. lionagi/_class_registry.py +1 -2
  3. lionagi/_errors.py +1 -2
  4. lionagi/adapters/async_postgres_adapter.py +2 -10
  5. lionagi/config.py +1 -2
  6. lionagi/fields/action.py +1 -2
  7. lionagi/fields/base.py +3 -0
  8. lionagi/fields/code.py +3 -0
  9. lionagi/fields/file.py +3 -0
  10. lionagi/fields/instruct.py +1 -2
  11. lionagi/fields/reason.py +3 -2
  12. lionagi/fields/research.py +3 -0
  13. lionagi/libs/__init__.py +1 -2
  14. lionagi/libs/file/__init__.py +1 -2
  15. lionagi/libs/file/chunk.py +1 -2
  16. lionagi/libs/file/process.py +1 -2
  17. lionagi/libs/schema/__init__.py +1 -2
  18. lionagi/libs/schema/as_readable.py +1 -2
  19. lionagi/libs/schema/extract_code_block.py +1 -2
  20. lionagi/libs/schema/extract_docstring.py +1 -2
  21. lionagi/libs/schema/function_to_schema.py +1 -2
  22. lionagi/libs/schema/load_pydantic_model_from_schema.py +1 -2
  23. lionagi/libs/validate/__init__.py +1 -2
  24. lionagi/libs/validate/common_field_validators.py +1 -2
  25. lionagi/libs/validate/validate_boolean.py +1 -2
  26. lionagi/ln/fuzzy/_string_similarity.py +1 -2
  27. lionagi/ln/types.py +45 -0
  28. lionagi/models/__init__.py +1 -2
  29. lionagi/models/field_model.py +392 -286
  30. lionagi/models/hashable_model.py +98 -14
  31. lionagi/models/model_params.py +272 -271
  32. lionagi/models/operable_model.py +9 -10
  33. lionagi/models/schema_model.py +1 -2
  34. lionagi/operations/ReAct/ReAct.py +1 -2
  35. lionagi/operations/ReAct/__init__.py +1 -2
  36. lionagi/operations/ReAct/utils.py +1 -2
  37. lionagi/operations/__init__.py +1 -2
  38. lionagi/operations/_act/__init__.py +1 -2
  39. lionagi/operations/_act/act.py +1 -2
  40. lionagi/operations/brainstorm/__init__.py +1 -2
  41. lionagi/operations/brainstorm/brainstorm.py +1 -2
  42. lionagi/operations/brainstorm/prompt.py +1 -2
  43. lionagi/operations/builder.py +1 -2
  44. lionagi/operations/chat/__init__.py +1 -2
  45. lionagi/operations/chat/chat.py +1 -2
  46. lionagi/operations/communicate/communicate.py +1 -2
  47. lionagi/operations/flow.py +1 -2
  48. lionagi/operations/instruct/__init__.py +1 -2
  49. lionagi/operations/instruct/instruct.py +1 -2
  50. lionagi/operations/interpret/__init__.py +1 -2
  51. lionagi/operations/interpret/interpret.py +1 -2
  52. lionagi/operations/operate/__init__.py +1 -2
  53. lionagi/operations/operate/operate.py +1 -2
  54. lionagi/operations/parse/__init__.py +1 -2
  55. lionagi/operations/parse/parse.py +1 -2
  56. lionagi/operations/plan/__init__.py +1 -2
  57. lionagi/operations/plan/plan.py +1 -2
  58. lionagi/operations/plan/prompt.py +1 -2
  59. lionagi/operations/select/__init__.py +1 -2
  60. lionagi/operations/select/select.py +1 -2
  61. lionagi/operations/select/utils.py +1 -2
  62. lionagi/operations/types.py +1 -2
  63. lionagi/operations/utils.py +1 -2
  64. lionagi/protocols/__init__.py +1 -2
  65. lionagi/protocols/_concepts.py +1 -2
  66. lionagi/protocols/action/__init__.py +1 -2
  67. lionagi/protocols/action/function_calling.py +3 -20
  68. lionagi/protocols/action/manager.py +34 -4
  69. lionagi/protocols/action/tool.py +1 -2
  70. lionagi/protocols/contracts.py +1 -2
  71. lionagi/protocols/forms/__init__.py +1 -2
  72. lionagi/protocols/forms/base.py +1 -2
  73. lionagi/protocols/forms/flow.py +1 -2
  74. lionagi/protocols/forms/form.py +1 -2
  75. lionagi/protocols/forms/report.py +1 -2
  76. lionagi/protocols/generic/__init__.py +1 -2
  77. lionagi/protocols/generic/element.py +17 -65
  78. lionagi/protocols/generic/event.py +1 -2
  79. lionagi/protocols/generic/log.py +14 -12
  80. lionagi/protocols/generic/pile.py +6 -4
  81. lionagi/protocols/generic/processor.py +1 -2
  82. lionagi/protocols/generic/progression.py +1 -2
  83. lionagi/protocols/graph/__init__.py +1 -2
  84. lionagi/protocols/graph/edge.py +1 -2
  85. lionagi/protocols/graph/graph.py +1 -2
  86. lionagi/protocols/graph/node.py +1 -2
  87. lionagi/protocols/ids.py +1 -2
  88. lionagi/protocols/mail/__init__.py +1 -2
  89. lionagi/protocols/mail/exchange.py +1 -2
  90. lionagi/protocols/mail/mail.py +1 -2
  91. lionagi/protocols/mail/mailbox.py +1 -2
  92. lionagi/protocols/mail/manager.py +1 -2
  93. lionagi/protocols/mail/package.py +1 -2
  94. lionagi/protocols/messages/__init__.py +1 -2
  95. lionagi/protocols/messages/action_request.py +1 -2
  96. lionagi/protocols/messages/action_response.py +1 -2
  97. lionagi/protocols/messages/assistant_response.py +1 -2
  98. lionagi/protocols/messages/base.py +1 -2
  99. lionagi/protocols/messages/instruction.py +1 -2
  100. lionagi/protocols/messages/manager.py +1 -2
  101. lionagi/protocols/messages/message.py +1 -2
  102. lionagi/protocols/messages/system.py +1 -2
  103. lionagi/protocols/operatives/__init__.py +1 -2
  104. lionagi/protocols/operatives/operative.py +30 -8
  105. lionagi/protocols/operatives/step.py +1 -2
  106. lionagi/protocols/types.py +1 -2
  107. lionagi/service/connections/__init__.py +1 -2
  108. lionagi/service/connections/api_calling.py +1 -2
  109. lionagi/service/connections/endpoint.py +1 -2
  110. lionagi/service/connections/endpoint_config.py +1 -2
  111. lionagi/service/connections/header_factory.py +1 -2
  112. lionagi/service/connections/match_endpoint.py +1 -2
  113. lionagi/service/connections/mcp/__init__.py +1 -2
  114. lionagi/service/connections/mcp/wrapper.py +1 -2
  115. lionagi/service/connections/providers/__init__.py +1 -2
  116. lionagi/service/connections/providers/anthropic_.py +1 -2
  117. lionagi/service/connections/providers/claude_code_cli.py +1 -2
  118. lionagi/service/connections/providers/exa_.py +1 -2
  119. lionagi/service/connections/providers/nvidia_nim_.py +2 -27
  120. lionagi/service/connections/providers/oai_.py +1 -2
  121. lionagi/service/connections/providers/ollama_.py +1 -2
  122. lionagi/service/connections/providers/perplexity_.py +1 -2
  123. lionagi/service/hooks/__init__.py +1 -1
  124. lionagi/service/hooks/_types.py +1 -1
  125. lionagi/service/hooks/_utils.py +1 -1
  126. lionagi/service/hooks/hook_event.py +1 -1
  127. lionagi/service/hooks/hook_registry.py +1 -1
  128. lionagi/service/hooks/hooked_event.py +1 -2
  129. lionagi/service/imodel.py +1 -2
  130. lionagi/service/manager.py +1 -2
  131. lionagi/service/rate_limited_processor.py +1 -2
  132. lionagi/service/resilience.py +1 -2
  133. lionagi/service/third_party/anthropic_models.py +3 -5
  134. lionagi/service/third_party/claude_code.py +1 -2
  135. lionagi/service/token_calculator.py +1 -2
  136. lionagi/service/types.py +1 -2
  137. lionagi/session/__init__.py +1 -2
  138. lionagi/session/branch.py +1 -2
  139. lionagi/session/session.py +1 -2
  140. lionagi/tools/__init__.py +1 -2
  141. lionagi/tools/base.py +1 -2
  142. lionagi/tools/file/__init__.py +1 -2
  143. lionagi/tools/file/reader.py +1 -2
  144. lionagi/tools/types.py +1 -2
  145. lionagi/utils.py +1 -2
  146. lionagi/version.py +1 -1
  147. {lionagi-0.17.9.dist-info → lionagi-0.17.11.dist-info}/METADATA +2 -2
  148. lionagi-0.17.11.dist-info/RECORD +199 -0
  149. lionagi-0.17.9.dist-info/RECORD +0 -199
  150. {lionagi-0.17.9.dist-info → lionagi-0.17.11.dist-info}/WHEEL +0 -0
  151. {lionagi-0.17.9.dist-info → lionagi-0.17.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from pydantic import ConfigDict
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import logging
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import ClassVar, Literal
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from .builder import ExpansionStrategy, OperationGraphBuilder
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import logging
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import logging
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  PROMPT = """Perform a brainstorm session. Generate {num_instruct} concise and distinct instructions (Instruct), each representing a potential next step. We will run them in parallel under the same context. Ensure each idea:
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  """
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import TYPE_CHECKING, Literal
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import logging
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  """
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import TYPE_CHECKING, Any
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import TYPE_CHECKING
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import logging
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import TYPE_CHECKING, Any, Literal
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from .plan import plan
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import Any, Literal
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  PLAN_PROMPT = """
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from enum import Enum
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import inspect
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from .brainstorm.brainstorm import brainstorm
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import TYPE_CHECKING
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from abc import ABC, abstractmethod
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  import asyncio
@@ -116,29 +115,13 @@ class FunctionCalling(Event):
116
115
  self.execution.status = EventStatus.FAILED
117
116
  self.execution.error = str(e)
118
117
 
119
- def __str__(self) -> str:
120
- """Returns a string representation of the function call.
121
-
122
- Returns:
123
- A string in the format "function_name(arguments)".
124
- """
125
- return f"{self.func_tool.function}({self.arguments})"
126
-
127
- def __repr__(self) -> str:
128
- """Returns a detailed string representation of the function call.
129
-
130
- Returns:
131
- A string containing the class name and key attributes.
132
- """
133
- return f"FunctionCalling(function={self.func_tool.function}, arguments={self.arguments})"
134
-
135
- def to_dict(self) -> dict[str, Any]:
118
+ def to_dict(self, *args, **kw) -> dict[str, Any]:
136
119
  """Convert instance to dictionary.
137
120
 
138
121
  Returns:
139
122
  dict[str, Any]: Dictionary representation of the instance.
140
123
  """
141
- dict_ = super().to_dict()
124
+ dict_ = super().to_dict(*args, **kw)
142
125
  dict_["function"] = self.function
143
126
  dict_["arguments"] = self.arguments
144
127
  return dict_
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
4
+ import logging
5
5
  from typing import Any
6
6
 
7
7
  from lionagi.fields.action import ActionRequestModel
@@ -348,16 +348,46 @@ class ActionManager(Manager):
348
348
  if request_options and tool.name in request_options:
349
349
  tool_request_options = request_options[tool.name]
350
350
 
351
+ # Extract schema from FastMCP tool and convert to lionagi format
352
+ tool_schema = None
351
353
  try:
352
- # Create tool with request_options for Pydantic validation
354
+ if (
355
+ hasattr(tool, "inputSchema")
356
+ and tool.inputSchema is not None
357
+ and isinstance(tool.inputSchema, dict)
358
+ ):
359
+ tool_schema = {
360
+ "type": "function",
361
+ "function": {
362
+ "name": tool.name,
363
+ "description": (
364
+ tool.description
365
+ if hasattr(tool, "description")
366
+ else None
367
+ ),
368
+ "parameters": tool.inputSchema,
369
+ },
370
+ }
371
+ except Exception as schema_error:
372
+ # If schema extraction fails, let Tool auto-generate from function signature
373
+ logging.warning(
374
+ f"Could not extract schema for {tool.name}: {schema_error}"
375
+ )
376
+ tool_schema = None
377
+
378
+ try:
379
+ # Create tool with auto-populated schema from MCP discovery
353
380
  tool_obj = Tool(
354
381
  mcp_config=mcp_config,
355
382
  request_options=tool_request_options,
383
+ tool_schema=tool_schema,
356
384
  )
357
385
  self.register_tool(tool_obj, update=update)
358
386
  registered_tools.append(tool.name)
359
387
  except Exception as e:
360
- print(f"Warning: Failed to register tool {tool.name}: {e}")
388
+ logging.warning(
389
+ f"Failed to register tool {tool.name}: {e}"
390
+ )
361
391
 
362
392
  return registered_tools
363
393
 
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
 
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  """V1 Observable Protocol for gradual evolution.
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import Any, Literal
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from pydantic import BaseModel, ConfigDict, Field
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from typing import Any
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from pydantic import Field
@@ -1,3 +1,2 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from __future__ import annotations
@@ -48,22 +47,13 @@ class IDType:
48
47
  __slots__ = ("_id",)
49
48
 
50
49
  def __init__(self, id: UUID) -> None:
51
- """Initializes an IDType instance.
52
-
53
- Args:
54
- id (UUID): A UUID object (version 4 preferred).
55
- """
50
+ """Initializes an IDType instance."""
56
51
  self._id = id
57
52
 
58
53
  @classmethod
59
54
  def validate(cls, value: str | UUID | IDType) -> IDType:
60
55
  """Validates and converts a value into an IDType.
61
56
 
62
- Args:
63
- value (str | UUID | IDType):
64
- A string representing a UUID, a UUID instance, or another
65
- IDType instance.
66
-
67
57
  Returns:
68
58
  IDType: The validated IDType object.
69
59
 
@@ -105,9 +95,6 @@ class IDType:
105
95
  def __eq__(self, other: Any) -> bool:
106
96
  """Checks equality with another IDType based on UUID value.
107
97
 
108
- Args:
109
- other (Any): Another object for equality comparison.
110
-
111
98
  Returns:
112
99
  bool: True if both have the same underlying UUID; False otherwise.
113
100
  """
@@ -190,17 +177,7 @@ class Element(BaseModel, Observable):
190
177
  def _coerce_created_at(
191
178
  cls, val: float | dt.datetime | str | None
192
179
  ) -> float:
193
- """Coerces `created_at` to a float-based timestamp.
194
-
195
- Args:
196
- val (float | datetime | str | None): The initial creation time value.
197
-
198
- Returns:
199
- float: A float representing Unix epoch time in seconds.
200
-
201
- Raises:
202
- ValueError: If `val` cannot be converted to a float timestamp.
203
- """
180
+ """Coerces `created_at` to a float-based timestamp."""
204
181
  if val is None:
205
182
  return ln.now_utc().timestamp()
206
183
  if isinstance(val, float):
@@ -235,36 +212,17 @@ class Element(BaseModel, Observable):
235
212
 
236
213
  @field_validator("id", mode="before")
237
214
  def _ensure_idtype(cls, val: IDType | UUID | str) -> IDType:
238
- """Ensures `id` is validated as an IDType.
239
-
240
- Args:
241
- val (IDType | UUID | str):
242
- The incoming value for the `id` field.
243
-
244
- Returns:
245
- IDType: A validated IDType object.
246
- """
215
+ """Ensures `id` is validated as an IDType."""
247
216
  return IDType.validate(val)
248
217
 
249
218
  @field_serializer("id")
250
219
  def _serialize_id_type(self, val: IDType) -> str:
251
- """Serializes the `id` field to a string.
252
-
253
- Args:
254
- val (IDType): The IDType object to be serialized.
255
-
256
- Returns:
257
- str: The string representation of the UUID.
258
- """
220
+ """Serializes the `id` field to a string."""
259
221
  return str(val)
260
222
 
261
223
  @property
262
224
  def created_datetime(self) -> dt.datetime:
263
- """Returns the creation time as a datetime object.
264
-
265
- Returns:
266
- datetime: The creation time in UTC.
267
- """
225
+ """Returns the creation time as a datetime object."""
268
226
  return dt.datetime.fromtimestamp(self.created_at, tz=dt.timezone.utc)
269
227
 
270
228
  def __eq__(self, other: Any) -> bool:
@@ -294,23 +252,25 @@ class Element(BaseModel, Observable):
294
252
  return str(cls).split("'")[1]
295
253
  return cls.__name__
296
254
 
297
- def _to_dict(self) -> dict:
298
- dict_ = self.model_dump()
255
+ def _to_dict(self, **kw) -> dict:
256
+ """kw for model_dump."""
257
+ dict_ = self.model_dump(**kw)
299
258
  dict_["metadata"].update({"lion_class": self.class_name(full=True)})
300
259
  return {k: v for k, v in dict_.items() if ln.not_sentinel(v)}
301
260
 
302
261
  def to_dict(
303
- self, mode: Literal["python", "json", "db"] = "python"
262
+ self, mode: Literal["python", "json", "db"] = "python", **kw
304
263
  ) -> dict:
305
264
  """Converts this Element to a dictionary."""
306
265
  if mode == "python":
307
- return self._to_dict()
266
+ return self._to_dict(**kw)
308
267
  if mode == "json":
309
- return orjson.loads(self.to_json(decode=False))
268
+ return orjson.loads(self.to_json(decode=False, **kw))
310
269
  if mode == "db":
311
- dict_ = orjson.loads(self.to_json(decode=False))
270
+ dict_ = orjson.loads(self.to_json(decode=False, **kw))
312
271
  dict_["node_metadata"] = dict_.pop("metadata", {})
313
272
  return dict_
273
+ raise ValueError(f"Unsupported mode: {mode}")
314
274
 
315
275
  @classmethod
316
276
  def from_dict(cls, data: dict) -> Element:
@@ -353,9 +313,10 @@ class Element(BaseModel, Observable):
353
313
  data["metadata"] = metadata
354
314
  return cls.model_validate(data)
355
315
 
356
- def to_json(self, decode: bool = True) -> str:
316
+ def to_json(self, decode: bool = True, **kw) -> str:
357
317
  """Converts this Element to a JSON string."""
358
- dict_ = self._to_dict()
318
+ kw.pop("mode", None)
319
+ dict_ = self._to_dict(**kw)
359
320
  return ln.json_dumps(
360
321
  dict_, default=DEFAULT_ELEMENT_SERIALIZER, decode=decode
361
322
  )
@@ -383,9 +344,6 @@ def validate_order(order: Any) -> list[IDType]:
383
344
  (e.g., a single Element, a list of Elements, a dictionary with ID keys,
384
345
  or a nested structure) and returns a flat list of IDType objects.
385
346
 
386
- Args:
387
- order (Any): A potentially nested structure of items to be ordered.
388
-
389
347
  Returns:
390
348
  list[IDType]: A flat list of validated IDType objects.
391
349
 
@@ -458,9 +416,6 @@ class ID(Generic[E]):
458
416
  - UUID: Validates and wraps it.
459
417
  - str: Interpreted as a UUID if possible.
460
418
 
461
- Args:
462
- item (E): The item to convert to an ID.
463
-
464
419
  Returns:
465
420
  IDType: The validated ID.
466
421
 
@@ -477,9 +432,6 @@ class ID(Generic[E]):
477
432
  def is_id(item: Any) -> bool:
478
433
  """Checks if an item can be validated as an IDType.
479
434
 
480
- Args:
481
- item (Any): The object to check.
482
-
483
435
  Returns:
484
436
  bool: True if `item` is or can be validated as an IDType;
485
437
  otherwise, False.
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
1
+ # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
3
2
  # SPDX-License-Identifier: Apache-2.0
4
3
 
5
4
  from __future__ import annotations