lionagi 0.16.2__tar.gz → 0.16.3__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 (336) hide show
  1. {lionagi-0.16.2 → lionagi-0.16.3}/.github/workflows/ci.yml +10 -4
  2. {lionagi-0.16.2 → lionagi-0.16.3}/PKG-INFO +3 -12
  3. {lionagi-0.16.2 → lionagi-0.16.3}/README.md +2 -2
  4. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/adapters/_utils.py +0 -14
  5. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/__init__.py +4 -0
  6. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/fuzzy/__init__.py +4 -1
  7. lionagi-0.16.2/lionagi/libs/validate/fuzzy_validate_mapping.py → lionagi-0.16.3/lionagi/ln/fuzzy/_fuzzy_validate.py +49 -38
  8. lionagi-0.16.3/lionagi/ln/fuzzy/_to_dict.py +388 -0
  9. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/models/__init__.py +0 -2
  10. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/communicate/communicate.py +1 -1
  11. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/parse/parse.py +1 -1
  12. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/generic/pile.py +1 -1
  13. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/operatives/operative.py +2 -2
  14. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/match_endpoint.py +2 -10
  15. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/types.py +1 -3
  16. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/hooks/hook_event.py +1 -1
  17. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/hooks/hook_registry.py +1 -1
  18. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/rate_limited_processor.py +1 -1
  19. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/utils.py +3 -335
  20. lionagi-0.16.3/lionagi/version.py +1 -0
  21. {lionagi-0.16.2 → lionagi-0.16.3}/pyproject.toml +2 -16
  22. {lionagi-0.16.2 → lionagi-0.16.3}/uv.lock +2 -50
  23. lionagi-0.16.2/lionagi/adapters/postgres_model_adapter.py +0 -131
  24. lionagi-0.16.2/lionagi/libs/concurrency.py +0 -1
  25. lionagi-0.16.2/lionagi/libs/nested/flatten.py +0 -172
  26. lionagi-0.16.2/lionagi/libs/nested/nfilter.py +0 -59
  27. lionagi-0.16.2/lionagi/libs/nested/nget.py +0 -45
  28. lionagi-0.16.2/lionagi/libs/nested/ninsert.py +0 -104
  29. lionagi-0.16.2/lionagi/libs/nested/nmerge.py +0 -158
  30. lionagi-0.16.2/lionagi/libs/nested/npop.py +0 -69
  31. lionagi-0.16.2/lionagi/libs/nested/nset.py +0 -94
  32. lionagi-0.16.2/lionagi/libs/nested/unflatten.py +0 -83
  33. lionagi-0.16.2/lionagi/libs/nested/utils.py +0 -189
  34. lionagi-0.16.2/lionagi/libs/parse.py +0 -31
  35. lionagi-0.16.2/lionagi/libs/schema/json_schema.py +0 -231
  36. lionagi-0.16.2/lionagi/libs/unstructured/pdf_to_image.py +0 -45
  37. lionagi-0.16.2/lionagi/libs/unstructured/read_image_to_base64.py +0 -33
  38. lionagi-0.16.2/lionagi/libs/validate/fuzzy_match_keys.py +0 -7
  39. lionagi-0.16.2/lionagi/libs/validate/string_similarity.py +0 -7
  40. lionagi-0.16.2/lionagi/libs/validate/xml_parser.py +0 -203
  41. lionagi-0.16.2/lionagi/ln/fuzzy/_fuzzy_validate.py +0 -46
  42. lionagi-0.16.2/lionagi/models/note.py +0 -387
  43. lionagi-0.16.2/lionagi/service/connections/providers/claude_code_.py +0 -299
  44. lionagi-0.16.2/lionagi/service/third_party/__init__.py +0 -0
  45. lionagi-0.16.2/lionagi/tools/file/__init__.py +0 -3
  46. lionagi-0.16.2/lionagi/version.py +0 -1
  47. {lionagi-0.16.2 → lionagi-0.16.3}/.coveragerc +0 -0
  48. {lionagi-0.16.2 → lionagi-0.16.3}/.env.example +0 -0
  49. {lionagi-0.16.2 → lionagi-0.16.3}/.github/FUNDING.yml +0 -0
  50. {lionagi-0.16.2 → lionagi-0.16.3}/.github/dependabot.yml +0 -0
  51. {lionagi-0.16.2 → lionagi-0.16.3}/.github/workflows/benchmarks.yml +0 -0
  52. {lionagi-0.16.2 → lionagi-0.16.3}/.github/workflows/codeql.yml +0 -0
  53. {lionagi-0.16.2 → lionagi-0.16.3}/.github/workflows/docs-deploy.yml +0 -0
  54. {lionagi-0.16.2 → lionagi-0.16.3}/.github/workflows/refresh-bench-baselines.yml +0 -0
  55. {lionagi-0.16.2 → lionagi-0.16.3}/.github/workflows/release.yml +0 -0
  56. {lionagi-0.16.2 → lionagi-0.16.3}/.gitignore +0 -0
  57. {lionagi-0.16.2 → lionagi-0.16.3}/.pre-commit-config.yaml +0 -0
  58. {lionagi-0.16.2 → lionagi-0.16.3}/.python-version +0 -0
  59. {lionagi-0.16.2 → lionagi-0.16.3}/CODE_OF_CONDUCT.md +0 -0
  60. {lionagi-0.16.2 → lionagi-0.16.3}/CONTRIBUTING.md +0 -0
  61. {lionagi-0.16.2 → lionagi-0.16.3}/LICENSE +0 -0
  62. {lionagi-0.16.2 → lionagi-0.16.3}/assets/operation_builder.gif +0 -0
  63. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/README.md +0 -0
  64. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/baselines/.gitkeep +0 -0
  65. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/baselines/concurrency-asyncio.json +0 -0
  66. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/baselines/concurrency-trio.json +0 -0
  67. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/baselines/fuzzy.json +0 -0
  68. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/baselines/ln-asyncio.json +0 -0
  69. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/baselines/ln-trio.json +0 -0
  70. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/ci_compare.py +0 -0
  71. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/concurrency_bench.py +0 -0
  72. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/fuzzy_bench.py +0 -0
  73. {lionagi-0.16.2 → lionagi-0.16.3}/benchmarks/ln_bench.py +0 -0
  74. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/001_branch_converse.ipynb +0 -0
  75. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/002_branch_interact.ipynb +0 -0
  76. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/003_branch_info.ipynb +0 -0
  77. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/004_conversation_patterns.ipynb +0 -0
  78. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/005_react_basics.ipynb +0 -0
  79. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
  80. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/007_fan_out_in.py +0 -0
  81. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/claude_proxy/README.md +0 -0
  82. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/claude_proxy/claude_code_proxy.py +0 -0
  83. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
  84. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/data/002_comedian.json +0 -0
  85. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/data/002_critic.json +0 -0
  86. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/data/006_lion_proof_ch2.md +0 -0
  87. {lionagi-0.16.2 → lionagi-0.16.3}/cookbooks/using_claude_code.py +0 -0
  88. {lionagi-0.16.2 → lionagi-0.16.3}/docs/DOCUMENTATION_STANDARDS.md +0 -0
  89. {lionagi-0.16.2 → lionagi-0.16.3}/docs/advanced/custom-operations.md +0 -0
  90. {lionagi-0.16.2 → lionagi-0.16.3}/docs/advanced/error-handling.md +0 -0
  91. {lionagi-0.16.2 → lionagi-0.16.3}/docs/advanced/flow-composition.md +0 -0
  92. {lionagi-0.16.2 → lionagi-0.16.3}/docs/advanced/index.md +0 -0
  93. {lionagi-0.16.2 → lionagi-0.16.3}/docs/advanced/observability.md +0 -0
  94. {lionagi-0.16.2 → lionagi-0.16.3}/docs/advanced/performance.md +0 -0
  95. {lionagi-0.16.2 → lionagi-0.16.3}/docs/code-of-conduct.md +0 -0
  96. {lionagi-0.16.2 → lionagi-0.16.3}/docs/comparisons/langgraph.md +0 -0
  97. {lionagi-0.16.2 → lionagi-0.16.3}/docs/contributing.md +0 -0
  98. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/brainstorming.md +0 -0
  99. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/claim-extraction.md +0 -0
  100. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/code-review-crew.md +0 -0
  101. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/data-persistence.md +0 -0
  102. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/hr-automation.md +0 -0
  103. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/index.md +0 -0
  104. {lionagi-0.16.2 → lionagi-0.16.3}/docs/cookbook/research-synthesis.md +0 -0
  105. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/index.md +0 -0
  106. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/lionagi-philosophy.md +0 -0
  107. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/messages-and-memory.md +0 -0
  108. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/models-and-providers.md +0 -0
  109. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/operations.md +0 -0
  110. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/sessions-and-branches.md +0 -0
  111. {lionagi-0.16.2 → lionagi-0.16.3}/docs/core-concepts/tools-and-functions.md +0 -0
  112. {lionagi-0.16.2 → lionagi-0.16.3}/docs/for-ai-agents/claude-code-usage.md +0 -0
  113. {lionagi-0.16.2 → lionagi-0.16.3}/docs/for-ai-agents/index.md +0 -0
  114. {lionagi-0.16.2 → lionagi-0.16.3}/docs/for-ai-agents/orchestration-guide.md +0 -0
  115. {lionagi-0.16.2 → lionagi-0.16.3}/docs/for-ai-agents/pattern-selection.md +0 -0
  116. {lionagi-0.16.2 → lionagi-0.16.3}/docs/for-ai-agents/self-improvement.md +0 -0
  117. {lionagi-0.16.2 → lionagi-0.16.3}/docs/includes/abbreviations.md +0 -0
  118. {lionagi-0.16.2 → lionagi-0.16.3}/docs/index.md +0 -0
  119. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/databases.md +0 -0
  120. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/dspy-optimization.md +0 -0
  121. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/index.md +0 -0
  122. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/llamaindex-rag.md +0 -0
  123. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/llm-providers.md +0 -0
  124. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/mcp-servers.md +0 -0
  125. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/tools.md +0 -0
  126. {lionagi-0.16.2 → lionagi-0.16.3}/docs/integrations/vector-stores.md +0 -0
  127. {lionagi-0.16.2 → lionagi-0.16.3}/docs/marketing/language-interoperability-manifesto.md +0 -0
  128. {lionagi-0.16.2 → lionagi-0.16.3}/docs/migration/from-autogen.md +0 -0
  129. {lionagi-0.16.2 → lionagi-0.16.3}/docs/migration/from-crewai.md +0 -0
  130. {lionagi-0.16.2 → lionagi-0.16.3}/docs/migration/from-langchain.md +0 -0
  131. {lionagi-0.16.2 → lionagi-0.16.3}/docs/migration/index.md +0 -0
  132. {lionagi-0.16.2 → lionagi-0.16.3}/docs/patterns/conditional-flows.md +0 -0
  133. {lionagi-0.16.2 → lionagi-0.16.3}/docs/patterns/fan-out-in.md +0 -0
  134. {lionagi-0.16.2 → lionagi-0.16.3}/docs/patterns/index.md +0 -0
  135. {lionagi-0.16.2 → lionagi-0.16.3}/docs/patterns/react-with-rag.md +0 -0
  136. {lionagi-0.16.2 → lionagi-0.16.3}/docs/patterns/sequential-analysis.md +0 -0
  137. {lionagi-0.16.2 → lionagi-0.16.3}/docs/patterns/tournament-validation.md +0 -0
  138. {lionagi-0.16.2 → lionagi-0.16.3}/docs/problem-statement.md +0 -0
  139. {lionagi-0.16.2 → lionagi-0.16.3}/docs/quickstart/claude-code-integration.md +0 -0
  140. {lionagi-0.16.2 → lionagi-0.16.3}/docs/quickstart/index.md +0 -0
  141. {lionagi-0.16.2 → lionagi-0.16.3}/docs/quickstart/installation.md +0 -0
  142. {lionagi-0.16.2 → lionagi-0.16.3}/docs/quickstart/orchestration-first.md +0 -0
  143. {lionagi-0.16.2 → lionagi-0.16.3}/docs/quickstart/your-first-flow.md +0 -0
  144. {lionagi-0.16.2 → lionagi-0.16.3}/docs/reference/api/index.md +0 -0
  145. {lionagi-0.16.2 → lionagi-0.16.3}/docs/reference/changelog.md +0 -0
  146. {lionagi-0.16.2 → lionagi-0.16.3}/docs/reference/troubleshooting.md +0 -0
  147. {lionagi-0.16.2 → lionagi-0.16.3}/docs/stylesheets/extra.css +0 -0
  148. {lionagi-0.16.2 → lionagi-0.16.3}/docs/thinking-in-lionagi/branches-as-agents.md +0 -0
  149. {lionagi-0.16.2 → lionagi-0.16.3}/docs/thinking-in-lionagi/builder-pattern.md +0 -0
  150. {lionagi-0.16.2 → lionagi-0.16.3}/docs/thinking-in-lionagi/graphs-over-chains.md +0 -0
  151. {lionagi-0.16.2 → lionagi-0.16.3}/docs/thinking-in-lionagi/index.md +0 -0
  152. {lionagi-0.16.2 → lionagi-0.16.3}/docs/thinking-in-lionagi/why-lionagi.md +0 -0
  153. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/__init__.py +0 -0
  154. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/_class_registry.py +0 -0
  155. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/_errors.py +0 -0
  156. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/_types.py +0 -0
  157. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/adapters/__init__.py +0 -0
  158. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/adapters/async_postgres_adapter.py +0 -0
  159. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/config.py +0 -0
  160. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/__init__.py +0 -0
  161. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/action.py +0 -0
  162. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/base.py +0 -0
  163. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/code.py +0 -0
  164. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/file.py +0 -0
  165. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/instruct.py +0 -0
  166. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/reason.py +0 -0
  167. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/fields/research.py +0 -0
  168. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/__init__.py +0 -0
  169. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/__init__.py +0 -0
  170. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/_utils.py +0 -0
  171. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/chunk.py +0 -0
  172. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/concat.py +0 -0
  173. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/concat_files.py +0 -0
  174. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/file_ops.py +0 -0
  175. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/process.py +0 -0
  176. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/file/save.py +0 -0
  177. {lionagi-0.16.2/lionagi/libs/nested → lionagi-0.16.3/lionagi/libs/schema}/__init__.py +0 -0
  178. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/schema/as_readable.py +0 -0
  179. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/schema/extract_code_block.py +0 -0
  180. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/schema/extract_docstring.py +0 -0
  181. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/schema/function_to_schema.py +0 -0
  182. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
  183. {lionagi-0.16.2/lionagi/libs/schema → lionagi-0.16.3/lionagi/libs/validate}/__init__.py +0 -0
  184. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/validate/common_field_validators.py +0 -0
  185. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/validate/to_num.py +0 -0
  186. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/libs/validate/validate_boolean.py +0 -0
  187. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/_async_call.py +0 -0
  188. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/_hash.py +0 -0
  189. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/_json_dump.py +0 -0
  190. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/_list_call.py +0 -0
  191. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/_to_list.py +0 -0
  192. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/_utils.py +0 -0
  193. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/__init__.py +0 -0
  194. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/_compat.py +0 -0
  195. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/cancel.py +0 -0
  196. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/errors.py +0 -0
  197. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/patterns.py +0 -0
  198. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/primitives.py +0 -0
  199. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/resource_tracker.py +0 -0
  200. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/task.py +0 -0
  201. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/throttle.py +0 -0
  202. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/concurrency/utils.py +0 -0
  203. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/fuzzy/_extract_json.py +0 -0
  204. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/fuzzy/_fuzzy_json.py +0 -0
  205. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/fuzzy/_fuzzy_match.py +0 -0
  206. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/fuzzy/_string_similarity.py +0 -0
  207. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/ln/types.py +0 -0
  208. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/models/field_model.py +0 -0
  209. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/models/hashable_model.py +0 -0
  210. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/models/model_params.py +0 -0
  211. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/models/operable_model.py +0 -0
  212. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/models/schema_model.py +0 -0
  213. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/ReAct/ReAct.py +0 -0
  214. {lionagi-0.16.2/lionagi/libs/validate → lionagi-0.16.3/lionagi/operations/ReAct}/__init__.py +0 -0
  215. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/ReAct/utils.py +0 -0
  216. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/__init__.py +0 -0
  217. {lionagi-0.16.2/lionagi/operations/ReAct → lionagi-0.16.3/lionagi/operations/_act}/__init__.py +0 -0
  218. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/_act/act.py +0 -0
  219. {lionagi-0.16.2/lionagi/operations/_act → lionagi-0.16.3/lionagi/operations/brainstorm}/__init__.py +0 -0
  220. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/brainstorm/brainstorm.py +0 -0
  221. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/brainstorm/prompt.py +0 -0
  222. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/builder.py +0 -0
  223. {lionagi-0.16.2/lionagi/operations/brainstorm → lionagi-0.16.3/lionagi/operations/chat}/__init__.py +0 -0
  224. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/chat/chat.py +0 -0
  225. {lionagi-0.16.2/lionagi/libs/unstructured → lionagi-0.16.3/lionagi/operations/communicate}/__init__.py +0 -0
  226. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/flow.py +0 -0
  227. {lionagi-0.16.2/lionagi/operations/chat → lionagi-0.16.3/lionagi/operations/instruct}/__init__.py +0 -0
  228. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/instruct/instruct.py +0 -0
  229. {lionagi-0.16.2/lionagi/operations/instruct → lionagi-0.16.3/lionagi/operations/interpret}/__init__.py +0 -0
  230. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/interpret/interpret.py +0 -0
  231. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/manager.py +0 -0
  232. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/node.py +0 -0
  233. {lionagi-0.16.2/lionagi/operations/interpret → lionagi-0.16.3/lionagi/operations/operate}/__init__.py +0 -0
  234. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/operate/operate.py +0 -0
  235. {lionagi-0.16.2/lionagi/operations/operate → lionagi-0.16.3/lionagi/operations/parse}/__init__.py +0 -0
  236. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/plan/__init__.py +0 -0
  237. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/plan/plan.py +0 -0
  238. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/plan/prompt.py +0 -0
  239. {lionagi-0.16.2/lionagi/operations/parse → lionagi-0.16.3/lionagi/operations/select}/__init__.py +0 -0
  240. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/select/select.py +0 -0
  241. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/select/utils.py +0 -0
  242. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/types.py +0 -0
  243. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/operations/utils.py +0 -0
  244. {lionagi-0.16.2/lionagi/operations/select → lionagi-0.16.3/lionagi/protocols}/__init__.py +0 -0
  245. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/_concepts.py +0 -0
  246. {lionagi-0.16.2/lionagi/protocols → lionagi-0.16.3/lionagi/protocols/action}/__init__.py +0 -0
  247. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/action/function_calling.py +0 -0
  248. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/action/manager.py +0 -0
  249. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/action/tool.py +0 -0
  250. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/contracts.py +0 -0
  251. {lionagi-0.16.2/lionagi/protocols/action → lionagi-0.16.3/lionagi/protocols/forms}/__init__.py +0 -0
  252. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/forms/base.py +0 -0
  253. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/forms/flow.py +0 -0
  254. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/forms/form.py +0 -0
  255. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/forms/report.py +0 -0
  256. {lionagi-0.16.2/lionagi/protocols/forms → lionagi-0.16.3/lionagi/protocols/generic}/__init__.py +0 -0
  257. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/generic/element.py +0 -0
  258. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/generic/event.py +0 -0
  259. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/generic/log.py +0 -0
  260. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/generic/processor.py +0 -0
  261. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/generic/progression.py +0 -0
  262. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/graph/__init__.py +0 -0
  263. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/graph/_utils.py +0 -0
  264. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/graph/edge.py +0 -0
  265. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/graph/graph.py +0 -0
  266. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/graph/node.py +0 -0
  267. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/ids.py +0 -0
  268. {lionagi-0.16.2/lionagi/protocols/generic → lionagi-0.16.3/lionagi/protocols/mail}/__init__.py +0 -0
  269. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/mail/exchange.py +0 -0
  270. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/mail/mail.py +0 -0
  271. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/mail/mailbox.py +0 -0
  272. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/mail/manager.py +0 -0
  273. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/mail/package.py +0 -0
  274. {lionagi-0.16.2/lionagi/protocols/mail → lionagi-0.16.3/lionagi/protocols/messages}/__init__.py +0 -0
  275. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/action_request.py +0 -0
  276. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/action_response.py +0 -0
  277. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/assistant_response.py +0 -0
  278. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/base.py +0 -0
  279. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/instruction.py +0 -0
  280. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/manager.py +0 -0
  281. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/message.py +0 -0
  282. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/system.py +0 -0
  283. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/README.md +0 -0
  284. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
  285. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
  286. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
  287. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
  288. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
  289. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
  290. {lionagi-0.16.2/lionagi/protocols/messages → lionagi-0.16.3/lionagi/protocols/operatives}/__init__.py +0 -0
  291. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/operatives/step.py +0 -0
  292. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/protocols/types.py +0 -0
  293. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/py.typed +0 -0
  294. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/__init__.py +0 -0
  295. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/__init__.py +0 -0
  296. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/api_calling.py +0 -0
  297. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/endpoint.py +0 -0
  298. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/endpoint_config.py +0 -0
  299. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/header_factory.py +0 -0
  300. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/__init__.py +0 -0
  301. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/anthropic_.py +0 -0
  302. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
  303. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/exa_.py +0 -0
  304. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/nvidia_nim_.py +0 -0
  305. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/oai_.py +0 -0
  306. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/ollama_.py +0 -0
  307. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/connections/providers/perplexity_.py +0 -0
  308. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/hooks/__init__.py +0 -0
  309. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/hooks/_types.py +0 -0
  310. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/hooks/_utils.py +0 -0
  311. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/imodel.py +0 -0
  312. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/manager.py +0 -0
  313. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/resilience.py +0 -0
  314. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/third_party/README.md +0 -0
  315. {lionagi-0.16.2/lionagi/operations/communicate → lionagi-0.16.3/lionagi/service/third_party}/__init__.py +0 -0
  316. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/third_party/anthropic_models.py +0 -0
  317. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/third_party/claude_code.py +0 -0
  318. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/third_party/exa_models.py +0 -0
  319. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/third_party/openai_model_names.py +0 -0
  320. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/third_party/pplx_models.py +0 -0
  321. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/token_calculator.py +0 -0
  322. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/service/types.py +0 -0
  323. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/session/__init__.py +0 -0
  324. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/session/branch.py +0 -0
  325. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/session/prompts.py +0 -0
  326. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/session/session.py +0 -0
  327. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/settings.py +0 -0
  328. {lionagi-0.16.2/lionagi/protocols/operatives → lionagi-0.16.3/lionagi/tools}/__init__.py +0 -0
  329. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/tools/base.py +0 -0
  330. {lionagi-0.16.2/lionagi/tools → lionagi-0.16.3/lionagi/tools/file}/__init__.py +0 -0
  331. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/tools/file/reader.py +0 -0
  332. {lionagi-0.16.2 → lionagi-0.16.3}/lionagi/tools/types.py +0 -0
  333. {lionagi-0.16.2 → lionagi-0.16.3}/main.py +0 -0
  334. {lionagi-0.16.2 → lionagi-0.16.3}/mkdocs.yml +0 -0
  335. {lionagi-0.16.2 → lionagi-0.16.3}/scripts/README.md +0 -0
  336. {lionagi-0.16.2 → lionagi-0.16.3}/scripts/update_openai_models.py +0 -0
@@ -39,12 +39,18 @@ jobs:
39
39
  run: |
40
40
  uv venv
41
41
  uv sync --extra all
42
-
43
- - name: Run tests
42
+
43
+ - name: Run tests with coverage
44
44
  run: |
45
45
  source .venv/bin/activate
46
- uv run pytest --asyncio-mode=auto --maxfail=1 --disable-warnings tests/
47
-
46
+ uv run pytest --asyncio-mode=auto --maxfail=1 --disable-warnings --cov=lionagi --cov-report=xml --cov-report=term tests/
47
+
48
+ - name: Upload coverage reports to Codecov
49
+ uses: codecov/codecov-action@v5
50
+ with:
51
+ token: ${{ secrets.CODECOV_TOKEN }}
52
+ slug: khive-ai/lionagi
53
+
48
54
  - name: Check code style and compatibility
49
55
  run: |
50
56
  source .venv/bin/activate
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.16.2
3
+ Version: 0.16.3
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -226,8 +226,6 @@ Requires-Dist: backoff>=2.0.0
226
226
  Requires-Dist: jinja2>=3.0.0
227
227
  Requires-Dist: json-repair>=0.40.0
228
228
  Requires-Dist: msgspec>=0.18.0
229
- Requires-Dist: pillow>=10.0.0
230
- Requires-Dist: psutil>=6.0.0
231
229
  Requires-Dist: pydantic-settings>=2.8.0
232
230
  Requires-Dist: pydantic>=2.8.0
233
231
  Requires-Dist: pydapter[pandas]>=1.1.1
@@ -235,7 +233,6 @@ Requires-Dist: python-dotenv>=1.1.0
235
233
  Requires-Dist: tiktoken>=0.9.0
236
234
  Provides-Extra: all
237
235
  Requires-Dist: aiosqlite>=0.21.0; extra == 'all'
238
- Requires-Dist: claude-code-sdk>=0.0.15; extra == 'all'
239
236
  Requires-Dist: datamodel-code-generator>=0.31.2; extra == 'all'
240
237
  Requires-Dist: docling>=2.15.0; extra == 'all'
241
238
  Requires-Dist: fastmcp>=2.10.5; extra == 'all'
@@ -244,8 +241,6 @@ Requires-Dist: networkx>=3.0.0; extra == 'all'
244
241
  Requires-Dist: ollama>=0.4.0; extra == 'all'
245
242
  Requires-Dist: pydapter[postgres]; extra == 'all'
246
243
  Requires-Dist: rich>=13.0.0; extra == 'all'
247
- Provides-Extra: claude-code
248
- Requires-Dist: claude-code-sdk>=0.0.15; extra == 'claude-code'
249
244
  Provides-Extra: graph
250
245
  Requires-Dist: matplotlib>=3.7.0; extra == 'graph'
251
246
  Requires-Dist: networkx>=3.0.0; extra == 'graph'
@@ -263,10 +258,6 @@ Provides-Extra: schema
263
258
  Requires-Dist: datamodel-code-generator>=0.31.2; extra == 'schema'
264
259
  Provides-Extra: sqlite
265
260
  Requires-Dist: aiosqlite>=0.21.0; extra == 'sqlite'
266
- Provides-Extra: tools
267
- Requires-Dist: docling>=2.15.0; extra == 'tools'
268
- Provides-Extra: unstructured
269
- Requires-Dist: opencv-python>=4.2.0.34; extra == 'unstructured'
270
261
  Provides-Extra: xml
271
262
  Requires-Dist: xmltodict>=0.12.0; extra == 'xml'
272
263
  Description-Content-Type: text/markdown
@@ -274,6 +265,7 @@ Description-Content-Type: text/markdown
274
265
  ![PyPI - Version](https://img.shields.io/pypi/v/lionagi?labelColor=233476aa&color=231fc935)
275
266
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/lionagi?color=blue)
276
267
  ![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
268
+ [![codecov](https://codecov.io/github/khive-ai/lionagi/graph/badge.svg?token=FAE47FY26T)](https://codecov.io/github/khive-ai/lionagi)
277
269
 
278
270
  [Documentation](https://khive-ai.github.io/lionagi/) |
279
271
  [Discord](https://discord.gg/JDj9ENhUE8) |
@@ -416,7 +408,7 @@ Seamlessly route to different models in the same workflow.
416
408
 
417
409
  ### Claude Code Integration
418
410
 
419
- LionAGI now supports Anthropic's Claude Code [Python SDK](https://github.com/anthropics/claude-code-sdk-python), and [CLI SDK](https://docs.anthropic.com/en/docs/claude-code/sdk) enabling autonomous coding capabilities with persistent session management. The CLI endpoint
411
+ LionAGI now supports Anthropic's Claude Code [CLI SDK](https://docs.anthropic.com/en/docs/claude-code/sdk) enabling autonomous coding capabilities with persistent session management. The CLI endpoint
420
412
  directly connects to claude code, and is recommended, you can either use it via a [proxy server](https://github.com/khive-ai/lionagi/tree/main/cookbooks/claude_proxy) or directly with `query_cli` endpoint, provided you have already logged onto claude code cli in your terminal.
421
413
 
422
414
  ```python
@@ -484,7 +476,6 @@ Key features:
484
476
  ```
485
477
  "lionagi[reader]" - Reader tool for any unstructured data and web pages
486
478
  "lionagi[ollama]" - Ollama model support for local inference
487
- "lionagi[claude-code]" - Claude code python SDK integration (cli endpoint does not require this)
488
479
  "lionagi[rich]" - Rich output formatting for better console display
489
480
  "lionagi[schema]" - Convert pydantic schema to make the Model class persistent
490
481
  "lionagi[postgres]" - Postgres database support for storing and retrieving structured data
@@ -1,6 +1,7 @@
1
1
  ![PyPI - Version](https://img.shields.io/pypi/v/lionagi?labelColor=233476aa&color=231fc935)
2
2
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/lionagi?color=blue)
3
3
  ![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
4
+ [![codecov](https://codecov.io/github/khive-ai/lionagi/graph/badge.svg?token=FAE47FY26T)](https://codecov.io/github/khive-ai/lionagi)
4
5
 
5
6
  [Documentation](https://khive-ai.github.io/lionagi/) |
6
7
  [Discord](https://discord.gg/JDj9ENhUE8) |
@@ -143,7 +144,7 @@ Seamlessly route to different models in the same workflow.
143
144
 
144
145
  ### Claude Code Integration
145
146
 
146
- LionAGI now supports Anthropic's Claude Code [Python SDK](https://github.com/anthropics/claude-code-sdk-python), and [CLI SDK](https://docs.anthropic.com/en/docs/claude-code/sdk) enabling autonomous coding capabilities with persistent session management. The CLI endpoint
147
+ LionAGI now supports Anthropic's Claude Code [CLI SDK](https://docs.anthropic.com/en/docs/claude-code/sdk) enabling autonomous coding capabilities with persistent session management. The CLI endpoint
147
148
  directly connects to claude code, and is recommended, you can either use it via a [proxy server](https://github.com/khive-ai/lionagi/tree/main/cookbooks/claude_proxy) or directly with `query_cli` endpoint, provided you have already logged onto claude code cli in your terminal.
148
149
 
149
150
  ```python
@@ -211,7 +212,6 @@ Key features:
211
212
  ```
212
213
  "lionagi[reader]" - Reader tool for any unstructured data and web pages
213
214
  "lionagi[ollama]" - Ollama model support for local inference
214
- "lionagi[claude-code]" - Claude code python SDK integration (cli endpoint does not require this)
215
215
  "lionagi[rich]" - Rich output formatting for better console display
216
216
  "lionagi[schema]" - Convert pydantic schema to make the Model class persistent
217
217
  "lionagi[postgres]" - Postgres database support for storing and retrieving structured data
@@ -10,17 +10,3 @@ def check_async_postgres_available():
10
10
  "This adapter requires postgres option to be installed. "
11
11
  'Please install them using `uv pip install "lionagi[postgres]"`.'
12
12
  )
13
-
14
-
15
- def check_postgres_available():
16
- try:
17
- from pydapter.model_adapters.postgres_model import PostgresModelAdapter
18
- from sqlalchemy import String
19
- from sqlalchemy.orm import DeclarativeBase
20
-
21
- return True
22
- except Exception:
23
- return ImportError(
24
- "This adapter requires postgres option to be installed. "
25
- 'Please install them using `uv pip install "lionagi[postgres]"`.'
26
- )
@@ -37,8 +37,10 @@ from .fuzzy import (
37
37
  extract_json,
38
38
  fuzzy_json,
39
39
  fuzzy_match_keys,
40
+ fuzzy_validate_mapping,
40
41
  fuzzy_validate_pydantic,
41
42
  string_similarity,
43
+ to_dict,
42
44
  )
43
45
  from .types import is_sentinel, not_sentinel
44
46
 
@@ -80,4 +82,6 @@ __all__ = (
80
82
  "string_similarity",
81
83
  "is_sentinel",
82
84
  "not_sentinel",
85
+ "to_dict",
86
+ "fuzzy_validate_mapping",
83
87
  )
@@ -1,10 +1,12 @@
1
1
  from ._extract_json import extract_json
2
2
  from ._fuzzy_json import fuzzy_json
3
3
  from ._fuzzy_match import FuzzyMatchKeysParams, fuzzy_match_keys
4
- from ._fuzzy_validate import fuzzy_validate_pydantic
4
+ from ._fuzzy_validate import fuzzy_validate_mapping, fuzzy_validate_pydantic
5
5
  from ._string_similarity import SIMILARITY_TYPE, string_similarity
6
+ from ._to_dict import to_dict
6
7
 
7
8
  __all__ = (
9
+ "to_dict",
8
10
  "fuzzy_json",
9
11
  "fuzzy_match_keys",
10
12
  "extract_json",
@@ -12,4 +14,5 @@ __all__ = (
12
14
  "SIMILARITY_TYPE",
13
15
  "fuzzy_validate_pydantic",
14
16
  "FuzzyMatchKeysParams",
17
+ "fuzzy_validate_mapping",
15
18
  )
@@ -1,45 +1,55 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
1
  from collections.abc import Callable, Sequence
6
2
  from typing import Any, Literal
7
3
 
8
- from lionagi.utils import KeysDict, Params, to_dict, to_json
4
+ from pydantic import BaseModel
9
5
 
10
- from .fuzzy_match_keys import fuzzy_match_keys
11
- from .string_similarity import SIMILARITY_TYPE
6
+ from lionagi._errors import ValidationError
12
7
 
8
+ from ..types import KeysDict
9
+ from ._extract_json import extract_json
10
+ from ._fuzzy_match import FuzzyMatchKeysParams, fuzzy_match_keys
11
+ from ._string_similarity import SIMILARITY_TYPE
12
+ from ._to_dict import to_dict
13
13
 
14
- class FuzzyValidateMappingParams(Params):
15
- similarity_algo: SIMILARITY_TYPE | Callable[[str, str], float] = (
16
- "jaro_winkler"
17
- )
18
- similarity_threshold: float = 0.85
19
- fuzzy_match: bool = True
20
- handle_unmatched: Literal["ignore", "raise", "remove", "fill", "force"] = (
21
- "ignore"
22
- )
23
- fill_value: Any = None
24
- fill_mapping: dict[str, Any] | None = None
25
- strict: bool = False
26
- suppress_conversion_errors: bool = False
27
-
28
- def __call__(
29
- self, d_: dict[str, Any], keys: Sequence[str] | KeysDict
30
- ) -> dict[str, Any]:
31
- return fuzzy_validate_mapping(
32
- d_,
33
- keys,
34
- similarity_algo=self.similarity_algo,
35
- similarity_threshold=self.similarity_threshold,
36
- fuzzy_match=self.fuzzy_match,
37
- handle_unmatched=self.handle_unmatched,
38
- fill_value=self.fill_value,
39
- fill_mapping=self.fill_mapping,
40
- strict=self.strict,
41
- suppress_conversion_errors=self.suppress_conversion_errors,
42
- )
14
+ __all__ = ("fuzzy_validate_pydantic",)
15
+
16
+
17
+ def fuzzy_validate_pydantic(
18
+ text,
19
+ /,
20
+ model_type: type[BaseModel],
21
+ fuzzy_parse: bool = True,
22
+ fuzzy_match: bool = False,
23
+ fuzzy_match_params: FuzzyMatchKeysParams | dict = None,
24
+ ):
25
+ try:
26
+ model_data = extract_json(text, fuzzy_parse=fuzzy_parse)
27
+ except Exception as e:
28
+ raise ValidationError(
29
+ f"Failed to extract valid JSON from model response: {e}"
30
+ ) from e
31
+
32
+ d = model_data
33
+ if fuzzy_match:
34
+ if fuzzy_match_params is None:
35
+ model_data = fuzzy_match_keys(
36
+ d, model_type.model_fields, handle_unmatched="remove"
37
+ )
38
+ elif isinstance(fuzzy_match_params, dict):
39
+ model_data = fuzzy_match_keys(
40
+ d, model_type.model_fields, **fuzzy_match_params
41
+ )
42
+ elif isinstance(fuzzy_match_params, FuzzyMatchKeysParams):
43
+ model_data = fuzzy_match_params(d, model_type.model_fields)
44
+ else:
45
+ raise TypeError(
46
+ "fuzzy_keys_params must be a dict or FuzzyMatchKeysParams instance"
47
+ )
48
+
49
+ try:
50
+ return model_type.model_validate(model_data)
51
+ except Exception as e:
52
+ raise ValidationError(f"Validation failed: {e}") from e
43
53
 
44
54
 
45
55
  def fuzzy_validate_mapping(
@@ -100,14 +110,15 @@ def fuzzy_validate_mapping(
100
110
  if isinstance(d, str):
101
111
  # First try to_json for JSON strings and code blocks
102
112
  try:
103
- json_result = to_json(d)
113
+ json_result = extract_json(
114
+ d, fuzzy_parse=True, return_one_if_single=True
115
+ )
104
116
  dict_input = (
105
117
  json_result[0]
106
118
  if isinstance(json_result, list)
107
119
  else json_result
108
120
  )
109
121
  except Exception:
110
- # Fall back to to_dict for other string formats
111
122
  dict_input = to_dict(
112
123
  d, str_type="json", fuzzy_parse=True, suppress=True
113
124
  )
@@ -0,0 +1,388 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import dataclasses
5
+ import json
6
+ from collections.abc import Callable, Iterable, Mapping, Sequence
7
+ from enum import Enum as _Enum
8
+ from typing import Any, Literal
9
+
10
+ from ._fuzzy_json import fuzzy_json
11
+
12
+ # ----------------------------
13
+ # Helpers (small, tight, local)
14
+ # ----------------------------
15
+
16
+
17
+ def _is_na(obj: Any) -> bool:
18
+ """None / Pydantic undefined sentinels -> treat as NA."""
19
+ if obj is None:
20
+ return True
21
+ # Avoid importing pydantic types; match by typename to stay lightweight
22
+ tname = type(obj).__name__
23
+ return tname in {
24
+ "Undefined",
25
+ "UndefinedType",
26
+ "PydanticUndefined",
27
+ "PydanticUndefinedType",
28
+ }
29
+
30
+
31
+ def _enum_class_to_dict(
32
+ enum_cls: type[_Enum], use_enum_values: bool
33
+ ) -> dict[str, Any]:
34
+ members = dict(enum_cls.__members__) # cheap, stable
35
+ if use_enum_values:
36
+ return {k: v.value for k, v in members.items()}
37
+ return {k: v for k, v in members.items()}
38
+
39
+
40
+ def _parse_str(
41
+ s: str,
42
+ *,
43
+ fuzzy_parse: bool,
44
+ str_type: Literal["json", "xml"] | None,
45
+ parser: Callable[[str], Any] | None,
46
+ **kwargs: Any,
47
+ ) -> Any:
48
+ """Parse str -> Python object. Keep imports local to avoid cold start overhead."""
49
+ if parser is not None:
50
+ return parser(s, **kwargs)
51
+
52
+ if str_type == "xml":
53
+ # xmltodict is optional; import only if needed
54
+ import xmltodict
55
+
56
+ return xmltodict.parse(s, **kwargs)
57
+
58
+ # JSON path
59
+ if fuzzy_parse:
60
+ # If the caller supplied a fuzzy parser in scope, use it; otherwise fallback.
61
+ # We intentionally do not import anything heavy here.
62
+ with contextlib.suppress(NameError):
63
+ return fuzzy_json(s, **kwargs) # type: ignore[name-defined]
64
+ return json.loads(s, **kwargs)
65
+
66
+
67
+ def _object_to_mapping_like(
68
+ obj: Any,
69
+ *,
70
+ use_model_dump: bool,
71
+ **kwargs: Any,
72
+ ) -> Mapping | dict | Any:
73
+ """
74
+ Convert 'custom' objects to mapping-like, if possible.
75
+ Order:
76
+ 1) Pydantic v2 'model_dump' (duck-typed)
77
+ 2) Common methods: to_dict, dict, to_json/json (parsed if string)
78
+ 3) Dataclass
79
+ 4) __dict__
80
+ 5) dict(obj)
81
+ """
82
+ # 1) Pydantic v2
83
+ if use_model_dump and hasattr(obj, "model_dump"):
84
+ return obj.model_dump(**kwargs)
85
+
86
+ # 2) Common methods
87
+ for name in ("to_dict", "dict", "to_json", "json"):
88
+ if hasattr(obj, name):
89
+ res = getattr(obj, name)(**kwargs)
90
+ return json.loads(res) if isinstance(res, str) else res
91
+
92
+ # 3) Dataclass
93
+ if dataclasses.is_dataclass(obj):
94
+ # asdict is already recursive; keep it (fast enough & simple)
95
+ return dataclasses.asdict(obj)
96
+
97
+ # 4) __dict__
98
+ if hasattr(obj, "__dict__"):
99
+ return obj.__dict__
100
+
101
+ # 5) Try dict() fallback
102
+ return dict(obj) # may raise -> handled by caller
103
+
104
+
105
+ def _enumerate_iterable(it: Iterable) -> dict[int, Any]:
106
+ return {i: v for i, v in enumerate(it)}
107
+
108
+
109
+ # ---------------------------------------
110
+ # Recursive pre-processing (single pass)
111
+ # ---------------------------------------
112
+
113
+
114
+ def _preprocess_recursive(
115
+ obj: Any,
116
+ *,
117
+ depth: int,
118
+ max_depth: int,
119
+ recursive_custom_types: bool,
120
+ str_parse_opts: dict[str, Any],
121
+ use_model_dump: bool,
122
+ ) -> Any:
123
+ """
124
+ Recursively process nested structures:
125
+ - Parse strings (JSON/XML/custom parser)
126
+ - Recurse into dict/list/tuple/set/etc.
127
+ - If recursive_custom_types=True, convert custom objects to mapping-like then continue
128
+ Containers retain their original types (dict stays dict, list stays list, set stays set, etc.)
129
+ """
130
+ if depth >= max_depth:
131
+ return obj
132
+
133
+ # Fast paths by exact type where possible
134
+ t = type(obj)
135
+
136
+ # Strings: try to parse; on failure, keep as-is
137
+ if t is str:
138
+ try:
139
+ parsed = _parse_str(obj, **str_parse_opts)
140
+ except Exception:
141
+ return obj
142
+ return _preprocess_recursive(
143
+ parsed,
144
+ depth=depth + 1,
145
+ max_depth=max_depth,
146
+ recursive_custom_types=recursive_custom_types,
147
+ str_parse_opts=str_parse_opts,
148
+ use_model_dump=use_model_dump,
149
+ )
150
+
151
+ # Dict-like
152
+ if isinstance(obj, Mapping):
153
+ # Recurse only into values (keys kept as-is)
154
+ return {
155
+ k: _preprocess_recursive(
156
+ v,
157
+ depth=depth + 1,
158
+ max_depth=max_depth,
159
+ recursive_custom_types=recursive_custom_types,
160
+ str_parse_opts=str_parse_opts,
161
+ use_model_dump=use_model_dump,
162
+ )
163
+ for k, v in obj.items()
164
+ }
165
+
166
+ # Sequence/Set-like (but not str)
167
+ if isinstance(obj, (list, tuple, set, frozenset)):
168
+ items = [
169
+ _preprocess_recursive(
170
+ v,
171
+ depth=depth + 1,
172
+ max_depth=max_depth,
173
+ recursive_custom_types=recursive_custom_types,
174
+ str_parse_opts=str_parse_opts,
175
+ use_model_dump=use_model_dump,
176
+ )
177
+ for v in obj
178
+ ]
179
+ if t is list:
180
+ return items
181
+ if t is tuple:
182
+ return tuple(items)
183
+ if t is set:
184
+ return set(items)
185
+ if t is frozenset:
186
+ return frozenset(items)
187
+
188
+ # Enum *class* (rare in values, but preserve your original attempt)
189
+ if isinstance(obj, type) and issubclass(obj, _Enum):
190
+ try:
191
+ enum_map = _enum_class_to_dict(
192
+ obj,
193
+ use_enum_values=str_parse_opts.get("use_enum_values", True),
194
+ )
195
+ return _preprocess_recursive(
196
+ enum_map,
197
+ depth=depth + 1,
198
+ max_depth=max_depth,
199
+ recursive_custom_types=recursive_custom_types,
200
+ str_parse_opts=str_parse_opts,
201
+ use_model_dump=use_model_dump,
202
+ )
203
+ except Exception:
204
+ return obj
205
+
206
+ # Custom objects
207
+ if recursive_custom_types:
208
+ with contextlib.suppress(Exception):
209
+ mapped = _object_to_mapping_like(
210
+ obj, use_model_dump=use_model_dump
211
+ )
212
+ return _preprocess_recursive(
213
+ mapped,
214
+ depth=depth + 1,
215
+ max_depth=max_depth,
216
+ recursive_custom_types=recursive_custom_types,
217
+ str_parse_opts=str_parse_opts,
218
+ use_model_dump=use_model_dump,
219
+ )
220
+
221
+ return obj
222
+
223
+
224
+ # ---------------------------------------
225
+ # Top-level conversion (non-recursive)
226
+ # ---------------------------------------
227
+
228
+
229
+ def _convert_top_level_to_dict(
230
+ obj: Any,
231
+ *,
232
+ fuzzy_parse: bool,
233
+ str_type: Literal["json", "xml"] | None,
234
+ parser: Callable[[str], Any] | None,
235
+ use_model_dump: bool,
236
+ use_enum_values: bool,
237
+ **kwargs: Any,
238
+ ) -> dict[str, Any]:
239
+ """
240
+ Convert a *single* object to dict using the 'brute force' rules.
241
+ Mirrors your original order, with fixes & optimizations.
242
+ """
243
+ # Set -> {v: v}
244
+ if isinstance(obj, set):
245
+ return {v: v for v in obj}
246
+
247
+ # Enum class -> members mapping
248
+ if isinstance(obj, type) and issubclass(obj, _Enum):
249
+ return _enum_class_to_dict(obj, use_enum_values)
250
+
251
+ # Mapping -> copy to plain dict (preserve your copy semantics)
252
+ if isinstance(obj, Mapping):
253
+ return dict(obj)
254
+
255
+ # None / pydantic undefined -> {}
256
+ if _is_na(obj):
257
+ return {}
258
+
259
+ # str -> parse (and return *as parsed*, which may be list, dict, etc.)
260
+ if isinstance(obj, str):
261
+ return _parse_str(
262
+ obj,
263
+ fuzzy_parse=fuzzy_parse,
264
+ str_type=str_type,
265
+ parser=parser,
266
+ **kwargs,
267
+ )
268
+
269
+ # Try "custom" object conversions
270
+ # (Covers BaseModel via model_dump, dataclasses, __dict__, json-strings, etc.)
271
+ try:
272
+ # If it's *not* a Sequence (e.g., numbers, objects) we try object conversion first,
273
+ # faithfully following your previous "non-Sequence -> model path" behavior.
274
+ if not isinstance(obj, Sequence):
275
+ converted = _object_to_mapping_like(
276
+ obj, use_model_dump=use_model_dump, **kwargs
277
+ )
278
+ # If conversion returned a string, try to parse JSON to mapping; else pass-through
279
+ if isinstance(converted, str):
280
+ return _parse_str(
281
+ converted,
282
+ fuzzy_parse=fuzzy_parse,
283
+ str_type="json",
284
+ parser=None,
285
+ )
286
+ if isinstance(converted, Mapping):
287
+ return dict(converted)
288
+ # If it's a list/tuple/etc., enumerate (your original did that after the fact)
289
+ if isinstance(converted, Iterable) and not isinstance(
290
+ converted, (str, bytes, bytearray)
291
+ ):
292
+ return _enumerate_iterable(converted)
293
+ # Best effort final cast
294
+ return dict(converted)
295
+
296
+ except Exception:
297
+ # Fall through to other strategies
298
+ pass
299
+
300
+ # Iterable (list/tuple/namedtuple/frozenset/…): enumerate
301
+ if isinstance(obj, Iterable) and not isinstance(
302
+ obj, (str, bytes, bytearray)
303
+ ):
304
+ return _enumerate_iterable(obj)
305
+
306
+ # Dataclass fallback (reachable only if it wasn't caught above)
307
+ with contextlib.suppress(Exception):
308
+ if dataclasses.is_dataclass(obj):
309
+ return dataclasses.asdict(obj)
310
+
311
+ # Last-ditch attempt
312
+ return dict(obj) # may raise, handled by top-level try/except
313
+
314
+
315
+ # ---------------
316
+ # Public function
317
+ # ---------------
318
+
319
+
320
+ def to_dict(
321
+ input_: Any,
322
+ /,
323
+ *,
324
+ use_model_dump: bool = True,
325
+ fuzzy_parse: bool = False,
326
+ suppress: bool = False,
327
+ str_type: Literal["json", "xml"] | None = "json",
328
+ parser: Callable[[str], Any] | None = None,
329
+ recursive: bool = False,
330
+ max_recursive_depth: int | None = None,
331
+ recursive_python_only: bool = True,
332
+ use_enum_values: bool = False,
333
+ **kwargs: Any,
334
+ ) -> dict[str, Any]:
335
+ """
336
+ Convert various input types to a dictionary, with optional recursive processing.
337
+ Semantics preserved from original implementation.
338
+ """
339
+ try:
340
+ # Clamp recursion depth (match your constraints)
341
+ if not isinstance(max_recursive_depth, int):
342
+ max_depth = 5
343
+ else:
344
+ if max_recursive_depth < 0:
345
+ raise ValueError(
346
+ "max_recursive_depth must be a non-negative integer"
347
+ )
348
+ if max_recursive_depth > 10:
349
+ raise ValueError(
350
+ "max_recursive_depth must be less than or equal to 10"
351
+ )
352
+ max_depth = max_recursive_depth
353
+
354
+ # Prepare one small dict to avoid repeated arg passing and lookups
355
+ str_parse_opts = {
356
+ "fuzzy_parse": fuzzy_parse,
357
+ "str_type": str_type,
358
+ "parser": parser,
359
+ "use_enum_values": use_enum_values, # threaded for enum class in recursion
360
+ **kwargs,
361
+ }
362
+
363
+ obj = input_
364
+ if recursive:
365
+ obj = _preprocess_recursive(
366
+ obj,
367
+ depth=0,
368
+ max_depth=max_depth,
369
+ recursive_custom_types=not recursive_python_only,
370
+ str_parse_opts=str_parse_opts,
371
+ use_model_dump=use_model_dump,
372
+ )
373
+
374
+ # Final top-level conversion
375
+ return _convert_top_level_to_dict(
376
+ obj,
377
+ fuzzy_parse=fuzzy_parse,
378
+ str_type=str_type,
379
+ parser=parser,
380
+ use_model_dump=use_model_dump,
381
+ use_enum_values=use_enum_values,
382
+ **kwargs,
383
+ )
384
+
385
+ except Exception as e:
386
+ if suppress or input_ == "":
387
+ return {}
388
+ raise e
@@ -5,7 +5,6 @@
5
5
  from .field_model import FieldModel
6
6
  from .hashable_model import HashableModel
7
7
  from .model_params import ModelParams
8
- from .note import Note
9
8
  from .operable_model import OperableModel
10
9
  from .schema_model import SchemaModel
11
10
 
@@ -13,7 +12,6 @@ __all__ = (
13
12
  "FieldModel",
14
13
  "ModelParams",
15
14
  "OperableModel",
16
- "Note",
17
15
  "SchemaModel",
18
16
  "HashableModel",
19
17
  )