lionagi 0.17.11__tar.gz → 0.18.0__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.
Files changed (344) hide show
  1. lionagi-0.18.0/AGENTS.md +31 -0
  2. {lionagi-0.17.11 → lionagi-0.18.0}/PKG-INFO +1 -2
  3. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/react_mcp_with_schema.py +1 -1
  4. lionagi-0.18.0/docs/quickstart/installation.md +77 -0
  5. lionagi-0.18.0/docs/quickstart/your-first-flow.md +80 -0
  6. lionagi-0.18.0/lionagi/libs/schema/minimal_yaml.py +98 -0
  7. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/types.py +32 -5
  8. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/field_model.py +9 -0
  9. lionagi-0.18.0/lionagi/operations/ReAct/ReAct.py +618 -0
  10. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/ReAct/utils.py +3 -0
  11. lionagi-0.18.0/lionagi/operations/act/act.py +206 -0
  12. lionagi-0.18.0/lionagi/operations/chat/chat.py +190 -0
  13. lionagi-0.18.0/lionagi/operations/communicate/communicate.py +183 -0
  14. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/flow.py +4 -4
  15. lionagi-0.18.0/lionagi/operations/interpret/interpret.py +87 -0
  16. lionagi-0.18.0/lionagi/operations/operate/operate.py +316 -0
  17. lionagi-0.18.0/lionagi/operations/parse/parse.py +215 -0
  18. lionagi-0.18.0/lionagi/operations/select/select.py +141 -0
  19. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/select/utils.py +1 -1
  20. lionagi-0.18.0/lionagi/operations/types.py +122 -0
  21. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/log.py +3 -2
  22. lionagi-0.18.0/lionagi/protocols/messages/__init__.py +29 -0
  23. lionagi-0.18.0/lionagi/protocols/messages/action_request.py +111 -0
  24. lionagi-0.18.0/lionagi/protocols/messages/action_response.py +97 -0
  25. lionagi-0.18.0/lionagi/protocols/messages/assistant_response.py +178 -0
  26. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/messages/base.py +26 -18
  27. lionagi-0.18.0/lionagi/protocols/messages/instruction.py +324 -0
  28. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/messages/manager.py +112 -62
  29. lionagi-0.18.0/lionagi/protocols/messages/message.py +142 -0
  30. lionagi-0.18.0/lionagi/protocols/messages/system.py +73 -0
  31. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/types.py +0 -2
  32. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/endpoint.py +0 -8
  33. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/oai_.py +29 -94
  34. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/ollama_.py +3 -2
  35. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/hooked_event.py +2 -2
  36. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/claude_code.py +3 -2
  37. lionagi-0.18.0/lionagi/service/third_party/openai_models.py +433 -0
  38. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/branch.py +170 -178
  39. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/session.py +3 -9
  40. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/tools/file/reader.py +2 -2
  41. lionagi-0.18.0/lionagi/version.py +1 -0
  42. {lionagi-0.17.11 → lionagi-0.18.0}/mkdocs.yml +17 -41
  43. {lionagi-0.17.11 → lionagi-0.18.0}/pyproject.toml +1 -2
  44. {lionagi-0.17.11 → lionagi-0.18.0}/uv.lock +1 -3
  45. lionagi-0.17.11/docs/comparisons/langgraph.md +0 -440
  46. lionagi-0.17.11/docs/marketing/language-interoperability-manifesto.md +0 -181
  47. lionagi-0.17.11/docs/migration/from-autogen.md +0 -243
  48. lionagi-0.17.11/docs/migration/from-crewai.md +0 -259
  49. lionagi-0.17.11/docs/migration/from-langchain.md +0 -350
  50. lionagi-0.17.11/docs/migration/index.md +0 -64
  51. lionagi-0.17.11/docs/quickstart/claude-code-integration.md +0 -153
  52. lionagi-0.17.11/docs/quickstart/index.md +0 -53
  53. lionagi-0.17.11/docs/quickstart/installation.md +0 -61
  54. lionagi-0.17.11/docs/quickstart/orchestration-first.md +0 -229
  55. lionagi-0.17.11/docs/quickstart/your-first-flow.md +0 -253
  56. lionagi-0.17.11/docs/thinking-in-lionagi/branches-as-agents.md +0 -202
  57. lionagi-0.17.11/docs/thinking-in-lionagi/builder-pattern.md +0 -276
  58. lionagi-0.17.11/docs/thinking-in-lionagi/graphs-over-chains.md +0 -306
  59. lionagi-0.17.11/docs/thinking-in-lionagi/index.md +0 -86
  60. lionagi-0.17.11/docs/thinking-in-lionagi/why-lionagi.md +0 -169
  61. lionagi-0.17.11/lionagi/operations/ReAct/ReAct.py +0 -381
  62. lionagi-0.17.11/lionagi/operations/_act/act.py +0 -86
  63. lionagi-0.17.11/lionagi/operations/chat/chat.py +0 -174
  64. lionagi-0.17.11/lionagi/operations/communicate/communicate.py +0 -124
  65. lionagi-0.17.11/lionagi/operations/interpret/interpret.py +0 -42
  66. lionagi-0.17.11/lionagi/operations/operate/operate.py +0 -210
  67. lionagi-0.17.11/lionagi/operations/parse/parse.py +0 -187
  68. lionagi-0.17.11/lionagi/operations/select/select.py +0 -80
  69. lionagi-0.17.11/lionagi/operations/types.py +0 -26
  70. lionagi-0.17.11/lionagi/protocols/messages/action_request.py +0 -209
  71. lionagi-0.17.11/lionagi/protocols/messages/action_response.py +0 -155
  72. lionagi-0.17.11/lionagi/protocols/messages/assistant_response.py +0 -207
  73. lionagi-0.17.11/lionagi/protocols/messages/instruction.py +0 -668
  74. lionagi-0.17.11/lionagi/protocols/messages/message.py +0 -252
  75. lionagi-0.17.11/lionagi/protocols/messages/system.py +0 -144
  76. lionagi-0.17.11/lionagi/protocols/messages/templates/README.md +0 -28
  77. lionagi-0.17.11/lionagi/protocols/messages/templates/action_request.jinja2 +0 -5
  78. lionagi-0.17.11/lionagi/protocols/messages/templates/action_response.jinja2 +0 -9
  79. lionagi-0.17.11/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -6
  80. lionagi-0.17.11/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -61
  81. lionagi-0.17.11/lionagi/protocols/messages/templates/system_message.jinja2 +0 -11
  82. lionagi-0.17.11/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -7
  83. lionagi-0.17.11/lionagi/service/connections/providers/types.py +0 -28
  84. lionagi-0.17.11/lionagi/service/third_party/openai_model_names.py +0 -198
  85. lionagi-0.17.11/lionagi/service/types.py +0 -58
  86. lionagi-0.17.11/lionagi/tools/file/__init__.py +0 -2
  87. lionagi-0.17.11/lionagi/version.py +0 -1
  88. {lionagi-0.17.11 → lionagi-0.18.0}/.coveragerc +0 -0
  89. {lionagi-0.17.11 → lionagi-0.18.0}/.env.example +0 -0
  90. {lionagi-0.17.11 → lionagi-0.18.0}/.github/FUNDING.yml +0 -0
  91. {lionagi-0.17.11 → lionagi-0.18.0}/.github/dependabot.yml +0 -0
  92. {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/benchmarks.yml +0 -0
  93. {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/ci.yml +0 -0
  94. {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/codeql.yml +0 -0
  95. {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/docs-deploy.yml +0 -0
  96. {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/refresh-bench-baselines.yml +0 -0
  97. {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/release.yml +0 -0
  98. {lionagi-0.17.11 → lionagi-0.18.0}/.gitignore +0 -0
  99. {lionagi-0.17.11 → lionagi-0.18.0}/.pre-commit-config.yaml +0 -0
  100. {lionagi-0.17.11 → lionagi-0.18.0}/.python-version +0 -0
  101. {lionagi-0.17.11 → lionagi-0.18.0}/CODE_OF_CONDUCT.md +0 -0
  102. {lionagi-0.17.11 → lionagi-0.18.0}/CONTRIBUTING.md +0 -0
  103. {lionagi-0.17.11 → lionagi-0.18.0}/LICENSE +0 -0
  104. {lionagi-0.17.11 → lionagi-0.18.0}/README.md +0 -0
  105. {lionagi-0.17.11 → lionagi-0.18.0}/assets/operation_builder.gif +0 -0
  106. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/README.md +0 -0
  107. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/.gitkeep +0 -0
  108. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/concurrency-asyncio.json +0 -0
  109. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/concurrency-trio.json +0 -0
  110. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/fuzzy.json +0 -0
  111. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/ln-asyncio.json +0 -0
  112. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/ln-trio.json +0 -0
  113. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/ci_compare.py +0 -0
  114. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/README.md +0 -0
  115. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_detailed_20250922_182217.csv +0 -0
  116. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_professional.py +0 -0
  117. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_results_20250922_182217.json +0 -0
  118. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_summary_20250922_182217.csv +0 -0
  119. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/generate_benchmark_report.py +0 -0
  120. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/report.md +0 -0
  121. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/concurrency_bench.py +0 -0
  122. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/fuzzy_bench.py +0 -0
  123. {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/ln_bench.py +0 -0
  124. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/001_branch_converse.ipynb +0 -0
  125. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/002_branch_interact.ipynb +0 -0
  126. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/003_branch_info.ipynb +0 -0
  127. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/004_conversation_patterns.ipynb +0 -0
  128. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/005_react_basics.ipynb +0 -0
  129. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
  130. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/007_fan_out_in.py +0 -0
  131. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/data/002_comedian.json +0 -0
  132. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/data/002_critic.json +0 -0
  133. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/data/006_lion_proof_ch2.md +0 -0
  134. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/claude_proxy/README.md +0 -0
  135. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/claude_proxy/claude_code_proxy.py +0 -0
  136. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
  137. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/using_claude_code.py +0 -0
  138. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/.mcp.json +0 -0
  139. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/README.md +0 -0
  140. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/search_group.py +0 -0
  141. {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/search_group_config.json +0 -0
  142. {lionagi-0.17.11 → lionagi-0.18.0}/docs/DOCUMENTATION_STANDARDS.md +0 -0
  143. {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/custom-operations.md +0 -0
  144. {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/error-handling.md +0 -0
  145. {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/flow-composition.md +0 -0
  146. {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/index.md +0 -0
  147. {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/observability.md +0 -0
  148. {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/performance.md +0 -0
  149. {lionagi-0.17.11 → lionagi-0.18.0}/docs/code-of-conduct.md +0 -0
  150. {lionagi-0.17.11 → lionagi-0.18.0}/docs/contributing.md +0 -0
  151. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/brainstorming.md +0 -0
  152. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/claim-extraction.md +0 -0
  153. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/code-review-crew.md +0 -0
  154. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/data-persistence.md +0 -0
  155. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/hr-automation.md +0 -0
  156. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/index.md +0 -0
  157. {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/research-synthesis.md +0 -0
  158. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/index.md +0 -0
  159. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/lionagi-philosophy.md +0 -0
  160. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/messages-and-memory.md +0 -0
  161. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/models-and-providers.md +0 -0
  162. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/operations.md +0 -0
  163. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/sessions-and-branches.md +0 -0
  164. {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/tools-and-functions.md +0 -0
  165. {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/claude-code-usage.md +0 -0
  166. {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/index.md +0 -0
  167. {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/orchestration-guide.md +0 -0
  168. {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/pattern-selection.md +0 -0
  169. {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/self-improvement.md +0 -0
  170. {lionagi-0.17.11 → lionagi-0.18.0}/docs/includes/abbreviations.md +0 -0
  171. {lionagi-0.17.11 → lionagi-0.18.0}/docs/index.md +0 -0
  172. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/databases.md +0 -0
  173. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/dspy-optimization.md +0 -0
  174. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/index.md +0 -0
  175. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/llamaindex-rag.md +0 -0
  176. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/llm-providers.md +0 -0
  177. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/mcp-servers.md +0 -0
  178. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/tools.md +0 -0
  179. {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/vector-stores.md +0 -0
  180. {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/conditional-flows.md +0 -0
  181. {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/fan-out-in.md +0 -0
  182. {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/index.md +0 -0
  183. {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/react-with-rag.md +0 -0
  184. {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/sequential-analysis.md +0 -0
  185. {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/tournament-validation.md +0 -0
  186. {lionagi-0.17.11 → lionagi-0.18.0}/docs/problem-statement.md +0 -0
  187. {lionagi-0.17.11 → lionagi-0.18.0}/docs/reference/api/index.md +0 -0
  188. {lionagi-0.17.11 → lionagi-0.18.0}/docs/reference/changelog.md +0 -0
  189. {lionagi-0.17.11 → lionagi-0.18.0}/docs/reference/troubleshooting.md +0 -0
  190. {lionagi-0.17.11 → lionagi-0.18.0}/docs/stylesheets/extra.css +0 -0
  191. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/__init__.py +0 -0
  192. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/_class_registry.py +0 -0
  193. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/_errors.py +0 -0
  194. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/_types.py +0 -0
  195. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/adapters/__init__.py +0 -0
  196. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/adapters/_utils.py +0 -0
  197. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/adapters/async_postgres_adapter.py +0 -0
  198. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/config.py +0 -0
  199. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/__init__.py +0 -0
  200. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/action.py +0 -0
  201. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/base.py +0 -0
  202. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/code.py +0 -0
  203. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/file.py +0 -0
  204. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/instruct.py +0 -0
  205. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/reason.py +0 -0
  206. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/research.py +0 -0
  207. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/__init__.py +0 -0
  208. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/file/__init__.py +0 -0
  209. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/file/chunk.py +0 -0
  210. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/file/process.py +0 -0
  211. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/__init__.py +0 -0
  212. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/as_readable.py +0 -0
  213. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/breakdown_pydantic_annotation.py +0 -0
  214. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/extract_code_block.py +0 -0
  215. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/extract_docstring.py +0 -0
  216. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/function_to_schema.py +0 -0
  217. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
  218. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/__init__.py +0 -0
  219. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/common_field_validators.py +0 -0
  220. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/to_num.py +0 -0
  221. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/validate_boolean.py +0 -0
  222. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/__init__.py +0 -0
  223. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_async_call.py +0 -0
  224. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_hash.py +0 -0
  225. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_json_dump.py +0 -0
  226. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_list_call.py +0 -0
  227. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_to_list.py +0 -0
  228. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_utils.py +0 -0
  229. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/__init__.py +0 -0
  230. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/_compat.py +0 -0
  231. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/cancel.py +0 -0
  232. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/errors.py +0 -0
  233. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/patterns.py +0 -0
  234. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/primitives.py +0 -0
  235. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/resource_tracker.py +0 -0
  236. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/task.py +0 -0
  237. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/utils.py +0 -0
  238. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/__init__.py +0 -0
  239. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_extract_json.py +0 -0
  240. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_fuzzy_json.py +0 -0
  241. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_fuzzy_match.py +0 -0
  242. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_fuzzy_validate.py +0 -0
  243. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_string_similarity.py +0 -0
  244. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_to_dict.py +0 -0
  245. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/__init__.py +0 -0
  246. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/hashable_model.py +0 -0
  247. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/model_params.py +0 -0
  248. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/operable_model.py +0 -0
  249. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/schema_model.py +0 -0
  250. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/ReAct/__init__.py +0 -0
  251. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/__init__.py +0 -0
  252. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/_visualize_graph.py +0 -0
  253. {lionagi-0.17.11/lionagi/operations/_act → lionagi-0.18.0/lionagi/operations/act}/__init__.py +0 -0
  254. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/brainstorm/__init__.py +0 -0
  255. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/brainstorm/brainstorm.py +0 -0
  256. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/brainstorm/prompt.py +0 -0
  257. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/builder.py +0 -0
  258. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/chat/__init__.py +0 -0
  259. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/communicate/__init__.py +0 -0
  260. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/instruct/__init__.py +0 -0
  261. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/instruct/instruct.py +0 -0
  262. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/interpret/__init__.py +0 -0
  263. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/manager.py +0 -0
  264. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/node.py +0 -0
  265. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/operate/__init__.py +0 -0
  266. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/parse/__init__.py +0 -0
  267. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/plan/__init__.py +0 -0
  268. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/plan/plan.py +0 -0
  269. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/plan/prompt.py +0 -0
  270. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/select/__init__.py +0 -0
  271. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/utils.py +0 -0
  272. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/__init__.py +0 -0
  273. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/_concepts.py +0 -0
  274. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/__init__.py +0 -0
  275. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/function_calling.py +0 -0
  276. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/manager.py +0 -0
  277. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/tool.py +0 -0
  278. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/contracts.py +0 -0
  279. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/__init__.py +0 -0
  280. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/base.py +0 -0
  281. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/flow.py +0 -0
  282. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/form.py +0 -0
  283. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/report.py +0 -0
  284. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/__init__.py +0 -0
  285. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/element.py +0 -0
  286. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/event.py +0 -0
  287. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/pile.py +0 -0
  288. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/processor.py +0 -0
  289. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/progression.py +0 -0
  290. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/__init__.py +0 -0
  291. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/edge.py +0 -0
  292. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/graph.py +0 -0
  293. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/node.py +0 -0
  294. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/ids.py +0 -0
  295. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/__init__.py +0 -0
  296. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/exchange.py +0 -0
  297. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/mail.py +0 -0
  298. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/mailbox.py +0 -0
  299. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/manager.py +0 -0
  300. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/package.py +0 -0
  301. {lionagi-0.17.11/lionagi/protocols/messages → lionagi-0.18.0/lionagi/protocols/operatives}/__init__.py +0 -0
  302. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/operatives/operative.py +0 -0
  303. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/operatives/step.py +0 -0
  304. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/py.typed +0 -0
  305. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/__init__.py +0 -0
  306. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/broadcaster.py +0 -0
  307. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/__init__.py +0 -0
  308. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/api_calling.py +0 -0
  309. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/endpoint_config.py +0 -0
  310. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/header_factory.py +0 -0
  311. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/match_endpoint.py +0 -0
  312. {lionagi-0.17.11/lionagi/protocols/operatives → lionagi-0.18.0/lionagi/service/connections/mcp}/__init__.py +0 -0
  313. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/mcp/wrapper.py +0 -0
  314. {lionagi-0.17.11/lionagi/service/connections/mcp → lionagi-0.18.0/lionagi/service/connections/providers}/__init__.py +0 -0
  315. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/anthropic_.py +0 -0
  316. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
  317. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/exa_.py +0 -0
  318. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/nvidia_nim_.py +0 -0
  319. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/perplexity_.py +0 -0
  320. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/__init__.py +0 -0
  321. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/_types.py +0 -0
  322. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/_utils.py +0 -0
  323. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/hook_event.py +0 -0
  324. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/hook_registry.py +0 -0
  325. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/imodel.py +0 -0
  326. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/manager.py +0 -0
  327. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/rate_limited_processor.py +0 -0
  328. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/resilience.py +0 -0
  329. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/README.md +0 -0
  330. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/__init__.py +0 -0
  331. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/anthropic_models.py +0 -0
  332. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/exa_models.py +0 -0
  333. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/pplx_models.py +0 -0
  334. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/token_calculator.py +0 -0
  335. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/__init__.py +0 -0
  336. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/prompts.py +0 -0
  337. {lionagi-0.17.11/lionagi/service/connections/providers → lionagi-0.18.0/lionagi/tools}/__init__.py +0 -0
  338. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/tools/base.py +0 -0
  339. {lionagi-0.17.11/lionagi/tools → lionagi-0.18.0/lionagi/tools/file}/__init__.py +0 -0
  340. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/tools/types.py +0 -0
  341. {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/utils.py +0 -0
  342. {lionagi-0.17.11 → lionagi-0.18.0}/main.py +0 -0
  343. {lionagi-0.17.11 → lionagi-0.18.0}/scripts/README.md +0 -0
  344. {lionagi-0.17.11 → lionagi-0.18.0}/scripts/update_openai_models.py +0 -0
@@ -0,0 +1,31 @@
1
+ # Repository Guidelines
2
+
3
+ ## Project Structure & Module Organization
4
+ - Core runtime lives in `lionagi/` with subpackages for adapters, operations, session orchestration, protocol definitions, and tool integrations.
5
+ - Reusable assets, demos, and reference notebooks sit under `assets/`, `cookbooks/`, and `notebooks/`; automation scripts are in `scripts/`.
6
+ - Tests mirror the package layout in `tests/` (for example `tests/session/`, `tests/operations/`) with shared fixtures in `tests/fixtures/`.
7
+ - Documentation sources are maintained in `docs/` (MkDocs) and long-form guides in `CLAUDE.md`; published artifacts land in `site/` after builds.
8
+
9
+ ## Build, Test, and Development Commands
10
+ - Install or update the environment with `uv sync --dev`; this pulls project and tooling dependencies from `pyproject.toml` / `uv.lock`.
11
+ - Run the full suite via `uv run pytest`; pass `-m "not slow"` or `-k session` to target subsets while retaining pytest defaults (parallel, strict markers).
12
+ - Format and lint before committing: `uv run black .`, `uv run ruff check lionagi tests`, and `pre-commit run --all-files` for the configured hook chain.
13
+
14
+ ## Coding Style & Naming Conventions
15
+ - Follow Black’s 79-character line length and isort’s Black profile; keep imports grouped standard/third-party/local.
16
+ - Prefer explicit type hints and Pydantic models for structured data; name modules and directories in snake_case, classes in PascalCase, async coroutines with `_async` suffix when clarity helps.
17
+ - Avoid introducing new global state; prefer dependency injection through service or session layers within `lionagi/`.
18
+
19
+ ## Testing Guidelines
20
+ - Place unit tests adjacent to the relevant module subtree (`tests/operations/test_branch.py`, etc.) using filenames that start with `test_` and classes prefixed `Test`.
21
+ - Leverage pytest markers declared in `pyproject.toml` (`unit`, `integration`, `slow`, `performance`); mark long-running or network-dependent flows to keep CI lean.
22
+ - Maintain coverage by extending fixtures and factories in `tests/fixtures/`; include regression cases for bugs and concurrency edge scenarios.
23
+
24
+ ## Commit & Pull Request Guidelines
25
+ - Match the existing history: concise, sentence-case summaries in the imperative voice (e.g., `Improve session retry logic`).
26
+ - Each PR should describe scope, testing evidence (`uv run pytest` output, linting), linked GitHub issues, and screenshots or logs for UX-facing changes.
27
+ - Keep changesets focused, update `docs/` or `mkdocs.yml` alongside API changes, and request reviews once CI is green.
28
+
29
+ ## Documentation & Configuration Notes
30
+ - Keep `.env.example` aligned with new configuration keys; avoid committing real secrets or API tokens.
31
+ - When altering public interfaces, update `docs/` and regenerate the MkDocs site with `uv run mkdocs build` to verify navigation.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.17.11
3
+ Version: 0.18.0
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -223,7 +223,6 @@ Requires-Dist: aiocache>=0.12.0
223
223
  Requires-Dist: aiohttp>=3.11.0
224
224
  Requires-Dist: anyio>=4.7.0
225
225
  Requires-Dist: backoff>=2.0.0
226
- Requires-Dist: jinja2>=3.0.0
227
226
  Requires-Dist: json-repair>=0.40.0
228
227
  Requires-Dist: msgspec>=0.18.0
229
228
  Requires-Dist: pydantic-settings>=2.8.0
@@ -69,7 +69,7 @@ async def test_react_with_mcp():
69
69
  ),
70
70
  "context": {},
71
71
  },
72
- tools=["search_exa_search", "search_perplexity_search"],
72
+ tools=["exa_search", "perplexity_search"],
73
73
  max_extensions=3,
74
74
  verbose=True,
75
75
  )
@@ -0,0 +1,77 @@
1
+ # Installation
2
+
3
+ ## Install LionAGI
4
+
5
+ **Recommended**: Use `uv` for faster dependency resolution:
6
+ ```bash
7
+ uv add lionagi
8
+ ```
9
+
10
+ **Alternative**: Standard pip installation:
11
+ ```bash
12
+ pip install lionagi
13
+ ```
14
+
15
+ ## Configure API Keys
16
+
17
+ Create a `.env` file in your project root:
18
+
19
+ ```bash
20
+ # At minimum, add one provider
21
+ OPENAI_API_KEY=your_key_here
22
+
23
+ # Optional: Additional providers
24
+ ANTHROPIC_API_KEY=your_key_here
25
+ OPENROUTER_API_KEY=your_key_here
26
+ NVIDIA_NIM_API_KEY=your_key_here
27
+ GROQ_API_KEY=your_key_here
28
+ PERPLEXITY_API_KEY=your_key_here
29
+ EXA_API_KEY=your_key_here
30
+ ```
31
+
32
+ LionAGI automatically loads from `.env` - no manual configuration needed.
33
+
34
+ ## Verify Installation
35
+
36
+ Run this test to confirm everything works:
37
+
38
+ ```python
39
+ from lionagi import Branch, iModel
40
+
41
+ async def test():
42
+ gpt4 = iModel(provider="openai", model="gpt-4o-mini")
43
+ branch = Branch(chat_model=gpt4)
44
+ reply = await branch.chat("Hello from LionAGI!")
45
+ print(f"LionAGI says: {reply}")
46
+
47
+ if __name__ == "__main__":
48
+ import anyio
49
+ anyio.run(test)
50
+ ```
51
+
52
+ Expected output: A conversational response from the model.
53
+
54
+ ## Supported Providers
55
+
56
+ LionAGI comes pre-configured for these providers:
57
+
58
+ - **`openai`** - GPT-5, GPT-4.1, o4-mini
59
+ - **`anthropic`** - Claude 4.5 Sonnet, Claude 4.1 Opus
60
+ - **`claude_code`** - Claude Code SDK integration
61
+ - **`ollama`** - Local model hosting
62
+ - **`openrouter`** - Access 200+ models via single API
63
+ - **`nvidia_nim`** - NVIDIA inference microservices
64
+ - **`groq`** - Fast inference on LPU hardware
65
+ - **`perplexity`** - Search-augmented responses
66
+
67
+ ### Custom Providers
68
+
69
+ **OpenAI-compatible endpoints**:
70
+ ```python
71
+ custom = iModel(
72
+ provider="openai_compatible",
73
+ model="custom-model",
74
+ api_key="your_key",
75
+ base_url="https://custom-endpoint.com/v1"
76
+ )
77
+ ```
@@ -0,0 +1,80 @@
1
+ # Your First Flow
2
+
3
+ This quickstart shows LionAGI's core pattern: **multiple specialized branches working together**.
4
+
5
+ We'll build a self-critiquing joke generator - one branch writes jokes, another critiques them, then they iterate to improve.
6
+
7
+ ## Complete Example
8
+
9
+ ```python
10
+ from lionagi import Branch, iModel
11
+
12
+ chat_model = iModel(provider="openai", model="gpt-4.1-mini")
13
+
14
+ async def generate_joke(joke_request):
15
+ # Create two specialized branches
16
+ comedian = Branch(
17
+ chat_model=chat_model,
18
+ system="You are a comedian who makes technical concepts funny."
19
+ )
20
+
21
+ editor = Branch(
22
+ chat_model=chat_model,
23
+ system="You are an editor who improves clarity and punch."
24
+ )
25
+
26
+ # Flow: Generate → Critique → Revise → Verify
27
+ joke = await comedian.communicate(
28
+ "Write a short joke",
29
+ context={"user_input": joke_request}
30
+ )
31
+
32
+ feedback = await editor.communicate(
33
+ "Give humorous critical feedback to improve this joke by addressing clarity and punch.",
34
+ context={"joke": joke}
35
+ )
36
+
37
+ revision = await comedian.communicate(
38
+ "Revise the joke based on this feedback.",
39
+ context={"feedback": feedback}
40
+ )
41
+
42
+ final_check = await editor.communicate(
43
+ "Is this version better than the original? If yes, reply the following token (including the square brackets) '[YES]' only, otherwise elaborate on why not without including the token.",
44
+ context={"revised_joke": revision}
45
+ )
46
+
47
+ # Return improved version if approved
48
+ if "[yes]" in final_check.lower():
49
+ return revision
50
+ return joke # Fallback to original if not improved
51
+
52
+ # Run it
53
+ if __name__ == "__main__":
54
+ import anyio
55
+ result = anyio.run(generate_joke, "machine learning")
56
+ print(result)
57
+ ```
58
+
59
+ ## What Just Happened
60
+
61
+ **Branch**: Independent conversation context with its own system prompt and memory
62
+ - `comedian` = creative joke writing
63
+ - `editor` = critical feedback
64
+
65
+ **Flow**: Sequential operations across branches
66
+ 1. Comedian generates initial joke
67
+ 2. Editor provides feedback
68
+ 3. Comedian revises based on feedback
69
+ 4. Editor validates improvement
70
+
71
+ **Context**: Each `communicate()` call can include context from previous steps
72
+
73
+ ## Try It
74
+
75
+ Save the code above and run:
76
+ ```bash
77
+ uv run your_script.py
78
+ ```
79
+
80
+ Expected output: A refined joke about machine learning, improved through iteration.
@@ -0,0 +1,98 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import orjson
6
+ import yaml
7
+
8
+ # --- YAML Dumper with minimal, readable settings --------------------------------
9
+
10
+
11
+ class MinimalDumper(yaml.SafeDumper):
12
+ # Disable anchors/aliases (&id001, *id001) for repeated objects.
13
+ def ignore_aliases(self, data: Any) -> bool: # type: ignore[override]
14
+ return True
15
+
16
+
17
+ def _represent_str(dumper: yaml.SafeDumper, data: str):
18
+ # Use block scalars for multiline text; plain style otherwise.
19
+ if "\n" in data:
20
+ return dumper.represent_scalar(
21
+ "tag:yaml.org,2002:str", data, style="|"
22
+ )
23
+ return dumper.represent_scalar("tag:yaml.org,2002:str", data)
24
+
25
+
26
+ MinimalDumper.add_representer(str, _represent_str)
27
+
28
+ # --- Optional pruning of empty values -------------------------------------------
29
+
30
+
31
+ def _is_empty(x: Any) -> bool:
32
+ """
33
+ Define 'empty' for pruning. Keeps 0 and False.
34
+ - None or '' (after strip) are empty
35
+ - Empty containers are empty
36
+ """
37
+ if x is None:
38
+ return True
39
+ if isinstance(x, str):
40
+ return x.strip() == ""
41
+ if isinstance(x, dict):
42
+ return len(x) == 0
43
+ if isinstance(x, (list, tuple, set)):
44
+ return len(x) == 0
45
+ # Keep numbers (including 0) and booleans (including False)
46
+ return False
47
+
48
+
49
+ def _prune(x: Any) -> Any:
50
+ """Recursively remove empty leaves and empty containers produced thereby."""
51
+ if isinstance(x, dict):
52
+ pruned = {k: _prune(v) for k, v in x.items() if not _is_empty(v)}
53
+ # Remove keys that became empty after recursion
54
+ return {k: v for k, v in pruned.items() if not _is_empty(v)}
55
+ if isinstance(x, list):
56
+ pruned_list = [_prune(v) for v in x if not _is_empty(v)]
57
+ return [v for v in pruned_list if not _is_empty(v)]
58
+ if isinstance(x, tuple):
59
+ pruned_list = [_prune(v) for v in x if not _is_empty(v)]
60
+ return tuple(v for v in pruned_list if not _is_empty(v))
61
+ if isinstance(x, set):
62
+ pruned_set = {_prune(v) for v in x if not _is_empty(v)}
63
+ return {v for v in pruned_set if not _is_empty(v)}
64
+ return x
65
+
66
+
67
+ # --- Public API ------------------------------------------------------------------
68
+
69
+
70
+ def minimal_yaml(
71
+ value: Any,
72
+ *,
73
+ drop_empties: bool = True,
74
+ indent: int = 2,
75
+ line_width: int = 2**31 - 1, # avoid PyYAML inserting line-wraps
76
+ sort_keys: bool = False,
77
+ ) -> str:
78
+ """
79
+ Convert any Python value (dict/list/scalars) to a minimal, readable YAML string.
80
+ - Lists -> YAML sequences with '- '
81
+ - Dicts -> 'key: value' mappings
82
+ - Multiline strings -> block scalars (|)
83
+ - Optional pruning of empty values (keeps 0 and False)
84
+ - No aliases/anchors
85
+ """
86
+ if isinstance(value, str):
87
+ value = orjson.loads(value)
88
+
89
+ data = _prune(value) if drop_empties else value
90
+ return yaml.dump(
91
+ data,
92
+ Dumper=MinimalDumper,
93
+ default_flow_style=False, # block style
94
+ sort_keys=sort_keys, # preserve insertion order
95
+ allow_unicode=True,
96
+ indent=indent,
97
+ width=line_width,
98
+ )
@@ -232,10 +232,13 @@ class Params:
232
232
  dict_.update(kw_)
233
233
  return dict_
234
234
 
235
- def to_dict(self) -> dict[str, str]:
235
+ def to_dict(self, exclude: set[str] = None) -> dict[str, str]:
236
236
  data = {}
237
+ exclude = exclude or set()
237
238
  for k in self.allowed():
238
- if not self._is_sentinel(v := getattr(self, k, Undefined)):
239
+ if k not in exclude and not self._is_sentinel(
240
+ v := getattr(self, k, Undefined)
241
+ ):
239
242
  data[k] = v
240
243
  return data
241
244
 
@@ -249,6 +252,12 @@ class Params:
249
252
  return False
250
253
  return hash(self) == hash(other)
251
254
 
255
+ def with_updates(self, **kwargs: Any) -> DataClass:
256
+ """Return a new instance with updated fields."""
257
+ dict_ = self.to_dict()
258
+ dict_.update(kwargs)
259
+ return type(self)(**dict_)
260
+
252
261
 
253
262
  @dataclass(slots=True)
254
263
  class DataClass:
@@ -296,11 +305,13 @@ class DataClass:
296
305
  for k in self.allowed():
297
306
  _validate_strict(k)
298
307
 
299
- def to_dict(self) -> dict[str, str]:
308
+ def to_dict(self, exclude: set[str] = None) -> dict[str, str]:
300
309
  data = {}
301
- print(self.allowed())
310
+ exclude = exclude or set()
302
311
  for k in type(self).allowed():
303
- if not self._is_sentinel(v := getattr(self, k)):
312
+ if k not in exclude and not self._is_sentinel(
313
+ v := getattr(self, k)
314
+ ):
304
315
  data[k] = v
305
316
  return data
306
317
 
@@ -311,6 +322,22 @@ class DataClass:
311
322
  return True
312
323
  return is_sentinel(value)
313
324
 
325
+ def with_updates(self, **kwargs: Any) -> DataClass:
326
+ """Return a new instance with updated fields."""
327
+ dict_ = self.to_dict()
328
+ dict_.update(kwargs)
329
+ return type(self)(**dict_)
330
+
331
+ def __hash__(self) -> int:
332
+ from ._hash import hash_dict
333
+
334
+ return hash_dict(self.to_dict())
335
+
336
+ def __eq__(self, other: Any) -> bool:
337
+ if not isinstance(other, DataClass):
338
+ return False
339
+ return hash(self) == hash(other)
340
+
314
341
 
315
342
  KeysLike = Sequence[str] | KeysDict
316
343
 
@@ -513,6 +513,15 @@ class FieldModel(Params):
513
513
  # These are FieldTemplate markers, don't pass to FieldInfo
514
514
  pass
515
515
  else:
516
+ # Filter out unserializable objects from json_schema_extra
517
+ # to avoid Pydantic serialization errors when generating JSON schema
518
+ from pydantic import BaseModel
519
+
520
+ # Skip model classes and other unserializable types
521
+ if isinstance(meta.value, type):
522
+ # Skip type objects (including model classes) - they can't be serialized
523
+ continue
524
+
516
525
  # Any other metadata goes in json_schema_extra
517
526
  if "json_schema_extra" not in field_kwargs:
518
527
  field_kwargs["json_schema_extra"] = {}