lionagi 0.14.9__tar.gz → 0.14.11__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 (306) hide show
  1. {lionagi-0.14.9 → lionagi-0.14.11}/PKG-INFO +5 -1
  2. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/reason.py +1 -1
  3. lionagi-0.14.11/lionagi/libs/concurrency/throttle.py +80 -0
  4. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/parse.py +2 -1
  5. lionagi-0.14.11/lionagi/libs/unstructured/pdf_to_image.py +45 -0
  6. lionagi-0.14.11/lionagi/libs/unstructured/read_image_to_base64.py +33 -0
  7. lionagi-0.14.11/lionagi/libs/validate/to_num.py +378 -0
  8. lionagi-0.14.11/lionagi/libs/validate/xml_parser.py +203 -0
  9. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/node.py +3 -1
  10. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/graph/graph.py +13 -1
  11. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/hooks/_utils.py +2 -2
  12. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/hooks/hook_registry.py +8 -8
  13. lionagi-0.14.11/lionagi/service/third_party/__init__.py +0 -0
  14. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/tools/file/reader.py +1 -1
  15. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/tools/memory/tools.py +2 -2
  16. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/utils.py +4 -773
  17. lionagi-0.14.11/lionagi/version.py +1 -0
  18. {lionagi-0.14.9 → lionagi-0.14.11}/pyproject.toml +10 -1
  19. {lionagi-0.14.9 → lionagi-0.14.11}/scripts/update_openai_models.py +2 -2
  20. {lionagi-0.14.9 → lionagi-0.14.11}/uv.lock +54 -126
  21. lionagi-0.14.9/lionagi/version.py +0 -1
  22. {lionagi-0.14.9 → lionagi-0.14.11}/.coveragerc +0 -0
  23. {lionagi-0.14.9 → lionagi-0.14.11}/.env.example +0 -0
  24. {lionagi-0.14.9 → lionagi-0.14.11}/.github/FUNDING.yml +0 -0
  25. {lionagi-0.14.9 → lionagi-0.14.11}/.github/dependabot.yml +0 -0
  26. {lionagi-0.14.9 → lionagi-0.14.11}/.github/workflows/ci.yml +0 -0
  27. {lionagi-0.14.9 → lionagi-0.14.11}/.github/workflows/codeql.yml +0 -0
  28. {lionagi-0.14.9 → lionagi-0.14.11}/.github/workflows/docs.yml +0 -0
  29. {lionagi-0.14.9 → lionagi-0.14.11}/.github/workflows/release.yml +0 -0
  30. {lionagi-0.14.9 → lionagi-0.14.11}/.gitignore +0 -0
  31. {lionagi-0.14.9 → lionagi-0.14.11}/.pre-commit-config.yaml +0 -0
  32. {lionagi-0.14.9 → lionagi-0.14.11}/.python-version +0 -0
  33. {lionagi-0.14.9 → lionagi-0.14.11}/CODE_OF_CONDUCT.md +0 -0
  34. {lionagi-0.14.9 → lionagi-0.14.11}/CONTRIBUTING.md +0 -0
  35. {lionagi-0.14.9 → lionagi-0.14.11}/LICENSE +0 -0
  36. {lionagi-0.14.9 → lionagi-0.14.11}/README.md +0 -0
  37. {lionagi-0.14.9 → lionagi-0.14.11}/assets/operation_builder.gif +0 -0
  38. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/001_branch_converse.ipynb +0 -0
  39. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/002_branch_interact.ipynb +0 -0
  40. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/003_branch_info.ipynb +0 -0
  41. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/004_conversation_patterns.ipynb +0 -0
  42. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/005_react_basics.ipynb +0 -0
  43. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
  44. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/007_fan_out_in.py +0 -0
  45. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/claude_proxy/README.md +0 -0
  46. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/claude_proxy/claude_code_proxy.py +0 -0
  47. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
  48. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/data/002_comedian.json +0 -0
  49. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/data/002_critic.json +0 -0
  50. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/data/006_lion_proof_ch2.md +0 -0
  51. {lionagi-0.14.9 → lionagi-0.14.11}/cookbooks/using_claude_code.py +0 -0
  52. {lionagi-0.14.9 → lionagi-0.14.11}/docs/Makefile +0 -0
  53. {lionagi-0.14.9 → lionagi-0.14.11}/docs/_static/custom.css +0 -0
  54. {lionagi-0.14.9 → lionagi-0.14.11}/docs/_templates/layout.html +0 -0
  55. {lionagi-0.14.9 → lionagi-0.14.11}/docs/conf.py +0 -0
  56. {lionagi-0.14.9 → lionagi-0.14.11}/docs/discussions/anyio-migration.md +0 -0
  57. {lionagi-0.14.9 → lionagi-0.14.11}/docs/index.rst +0 -0
  58. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/action.rst +0 -0
  59. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/adapter.rst +0 -0
  60. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/branch.rst +0 -0
  61. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/branch_operations.rst +0 -0
  62. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/concepts.rst +0 -0
  63. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/element_id.rst +0 -0
  64. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/event.rst +0 -0
  65. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/form.rst +0 -0
  66. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/graph.rst +0 -0
  67. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/index.rst +0 -0
  68. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/instruct.rst +0 -0
  69. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/lib_file.rst +0 -0
  70. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/lib_nested.rst +0 -0
  71. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/lib_package.rst +0 -0
  72. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/lib_schema.rst +0 -0
  73. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/lib_validate.rst +0 -0
  74. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/log.rst +0 -0
  75. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/mail.rst +0 -0
  76. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/message.rst +0 -0
  77. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/models.rst +0 -0
  78. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/operative_step.rst +0 -0
  79. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/pile.rst +0 -0
  80. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/processor.rst +0 -0
  81. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/progression.rst +0 -0
  82. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/service.rst +0 -0
  83. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/session.rst +0 -0
  84. {lionagi-0.14.9 → lionagi-0.14.11}/docs/modules/utils.rst +0 -0
  85. {lionagi-0.14.9 → lionagi-0.14.11}/docs/tutorials/get_started.rst +0 -0
  86. {lionagi-0.14.9 → lionagi-0.14.11}/docs/tutorials/get_started_pt2.rst +0 -0
  87. {lionagi-0.14.9 → lionagi-0.14.11}/docs/tutorials/get_started_pt3.rst +0 -0
  88. {lionagi-0.14.9 → lionagi-0.14.11}/docs/tutorials/index.rst +0 -0
  89. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/__init__.py +0 -0
  90. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/_class_registry.py +0 -0
  91. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/_errors.py +0 -0
  92. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/_types.py +0 -0
  93. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/adapters/__init__.py +0 -0
  94. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/adapters/async_postgres_adapter.py +0 -0
  95. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/adapters/postgres_model_adapter.py +0 -0
  96. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/config.py +0 -0
  97. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/__init__.py +0 -0
  98. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/action.py +0 -0
  99. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/base.py +0 -0
  100. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/code.py +0 -0
  101. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/file.py +0 -0
  102. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/instruct.py +0 -0
  103. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/fields/research.py +0 -0
  104. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/__init__.py +0 -0
  105. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/__init__.py +0 -0
  106. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/cancel.py +0 -0
  107. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/errors.py +0 -0
  108. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/patterns.py +0 -0
  109. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/primitives.py +0 -0
  110. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/resource_tracker.py +0 -0
  111. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/concurrency/task.py +0 -0
  112. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/__init__.py +0 -0
  113. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/chunk.py +0 -0
  114. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/concat.py +0 -0
  115. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/concat_files.py +0 -0
  116. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/file_ops.py +0 -0
  117. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/params.py +0 -0
  118. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/process.py +0 -0
  119. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/file/save.py +0 -0
  120. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/hash/__init__.py +0 -0
  121. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/hash/hash_dict.py +0 -0
  122. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/hash/manager.py +0 -0
  123. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/__init__.py +0 -0
  124. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/flatten.py +0 -0
  125. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/nfilter.py +0 -0
  126. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/nget.py +0 -0
  127. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/ninsert.py +0 -0
  128. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/nmerge.py +0 -0
  129. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/npop.py +0 -0
  130. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/nset.py +0 -0
  131. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/unflatten.py +0 -0
  132. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/nested/utils.py +0 -0
  133. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/package/__init__.py +0 -0
  134. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/package/imports.py +0 -0
  135. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/package/management.py +0 -0
  136. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/package/params.py +0 -0
  137. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/package/system.py +0 -0
  138. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/__init__.py +0 -0
  139. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/as_readable.py +0 -0
  140. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/extract_code_block.py +0 -0
  141. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/extract_docstring.py +0 -0
  142. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/function_to_schema.py +0 -0
  143. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/json_schema.py +0 -0
  144. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
  145. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/__init__.py +0 -0
  146. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/base.py +0 -0
  147. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/llmlingua.py +0 -0
  148. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/perplexity.py +0 -0
  149. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/symbolic_compress_context.py +0 -0
  150. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang.py +0 -0
  151. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/base.py +0 -0
  152. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/abstract_algebra.toml +0 -0
  153. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/category_theory.toml +0 -0
  154. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/complex_analysis.toml +0 -0
  155. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json +0 -0
  156. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/group_theory.toml +0 -0
  157. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/math_logic.toml +0 -0
  158. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/reflective_patterns.toml +0 -0
  159. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/set_theory.toml +0 -0
  160. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/frameworks/topology_fundamentals.toml +0 -0
  161. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/mapping/lion_emoji_mapping.toml +0 -0
  162. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/mapping/python_math_mapping.toml +0 -0
  163. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/mapping/rust_chinese_mapping.toml +0 -0
  164. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/resources/utility/base_synthlang_system_prompt.toml +0 -0
  165. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/synthlang_/translate_to_synthlang.py +0 -0
  166. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/token_transform/types.py +0 -0
  167. {lionagi-0.14.9/lionagi/operations/communicate → lionagi-0.14.11/lionagi/libs/unstructured}/__init__.py +0 -0
  168. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/validate/__init__.py +0 -0
  169. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/validate/common_field_validators.py +0 -0
  170. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/validate/fuzzy_match_keys.py +0 -0
  171. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/validate/fuzzy_validate_mapping.py +0 -0
  172. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/validate/string_similarity.py +0 -0
  173. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/libs/validate/validate_boolean.py +0 -0
  174. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/__init__.py +0 -0
  175. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/field_model.py +0 -0
  176. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/hashable_model.py +0 -0
  177. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/model_params.py +0 -0
  178. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/note.py +0 -0
  179. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/operable_model.py +0 -0
  180. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/models/schema_model.py +0 -0
  181. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/ReAct/ReAct.py +0 -0
  182. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/ReAct/__init__.py +0 -0
  183. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/ReAct/utils.py +0 -0
  184. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/__init__.py +0 -0
  185. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/_act/__init__.py +0 -0
  186. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/_act/act.py +0 -0
  187. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/brainstorm/__init__.py +0 -0
  188. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/brainstorm/brainstorm.py +0 -0
  189. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/brainstorm/prompt.py +0 -0
  190. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/builder.py +0 -0
  191. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/chat/__init__.py +0 -0
  192. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/chat/chat.py +0 -0
  193. {lionagi-0.14.9/lionagi/operations/translate → lionagi-0.14.11/lionagi/operations/communicate}/__init__.py +0 -0
  194. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/communicate/communicate.py +0 -0
  195. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/flow.py +0 -0
  196. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/instruct/__init__.py +0 -0
  197. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/instruct/instruct.py +0 -0
  198. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/interpret/__init__.py +0 -0
  199. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/interpret/interpret.py +0 -0
  200. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/manager.py +0 -0
  201. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/operate/__init__.py +0 -0
  202. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/operate/operate.py +0 -0
  203. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/parse/__init__.py +0 -0
  204. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/parse/parse.py +0 -0
  205. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/plan/__init__.py +0 -0
  206. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/plan/plan.py +0 -0
  207. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/plan/prompt.py +0 -0
  208. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/select/__init__.py +0 -0
  209. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/select/select.py +0 -0
  210. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/select/utils.py +0 -0
  211. {lionagi-0.14.9/lionagi/service/third_party → lionagi-0.14.11/lionagi/operations/translate}/__init__.py +0 -0
  212. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/translate/translate.py +0 -0
  213. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/types.py +0 -0
  214. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/operations/utils.py +0 -0
  215. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/__init__.py +0 -0
  216. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/_concepts.py +0 -0
  217. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/action/__init__.py +0 -0
  218. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/action/function_calling.py +0 -0
  219. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/action/manager.py +0 -0
  220. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/action/tool.py +0 -0
  221. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/forms/__init__.py +0 -0
  222. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/forms/base.py +0 -0
  223. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/forms/flow.py +0 -0
  224. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/forms/form.py +0 -0
  225. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/forms/report.py +0 -0
  226. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/__init__.py +0 -0
  227. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/element.py +0 -0
  228. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/event.py +0 -0
  229. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/log.py +0 -0
  230. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/pile.py +0 -0
  231. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/processor.py +0 -0
  232. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/generic/progression.py +0 -0
  233. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/graph/__init__.py +0 -0
  234. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/graph/edge.py +0 -0
  235. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/graph/node.py +0 -0
  236. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/mail/__init__.py +0 -0
  237. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/mail/exchange.py +0 -0
  238. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/mail/mail.py +0 -0
  239. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/mail/mailbox.py +0 -0
  240. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/mail/manager.py +0 -0
  241. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/mail/package.py +0 -0
  242. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/__init__.py +0 -0
  243. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/action_request.py +0 -0
  244. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/action_response.py +0 -0
  245. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/assistant_response.py +0 -0
  246. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/base.py +0 -0
  247. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/instruction.py +0 -0
  248. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/manager.py +0 -0
  249. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/message.py +0 -0
  250. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/system.py +0 -0
  251. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/README.md +0 -0
  252. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
  253. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
  254. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
  255. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
  256. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
  257. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
  258. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/operatives/__init__.py +0 -0
  259. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/operatives/operative.py +0 -0
  260. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/operatives/step.py +0 -0
  261. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/protocols/types.py +0 -0
  262. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/py.typed +0 -0
  263. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/__init__.py +0 -0
  264. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/__init__.py +0 -0
  265. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/api_calling.py +0 -0
  266. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/endpoint.py +0 -0
  267. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/endpoint_config.py +0 -0
  268. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/header_factory.py +0 -0
  269. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/match_endpoint.py +0 -0
  270. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/__init__.py +0 -0
  271. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/anthropic_.py +0 -0
  272. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/claude_code_.py +0 -0
  273. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
  274. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/exa_.py +0 -0
  275. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/oai_.py +0 -0
  276. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/ollama_.py +0 -0
  277. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/perplexity_.py +0 -0
  278. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/connections/providers/types.py +0 -0
  279. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/hooks/__init__.py +0 -0
  280. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/hooks/_types.py +0 -0
  281. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/hooks/hook_event.py +0 -0
  282. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/imodel.py +0 -0
  283. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/manager.py +0 -0
  284. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/rate_limited_processor.py +0 -0
  285. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/resilience.py +0 -0
  286. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/third_party/README.md +0 -0
  287. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/third_party/anthropic_models.py +0 -0
  288. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/third_party/claude_code.py +0 -0
  289. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/third_party/exa_models.py +0 -0
  290. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/third_party/openai_model_names.py +0 -0
  291. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/third_party/pplx_models.py +0 -0
  292. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/token_calculator.py +0 -0
  293. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/service/types.py +0 -0
  294. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/session/__init__.py +0 -0
  295. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/session/branch.py +0 -0
  296. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/session/prompts.py +0 -0
  297. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/session/session.py +0 -0
  298. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/settings.py +0 -0
  299. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/tools/__init__.py +0 -0
  300. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/tools/base.py +0 -0
  301. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/tools/file/__init__.py +0 -0
  302. {lionagi-0.14.9 → lionagi-0.14.11}/lionagi/tools/types.py +0 -0
  303. {lionagi-0.14.9 → lionagi-0.14.11}/main.py +0 -0
  304. {lionagi-0.14.9 → lionagi-0.14.11}/scripts/README.md +0 -0
  305. {lionagi-0.14.9 → lionagi-0.14.11}/scripts/concat.py +0 -0
  306. {lionagi-0.14.9 → lionagi-0.14.11}/scripts/config.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.14.9
3
+ Version: 0.14.11
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>, Liangbingyan Luo <llby_luo@outlook.com>
6
6
  License: Apache License
@@ -264,6 +264,10 @@ Provides-Extra: sqlite
264
264
  Requires-Dist: aiosqlite>=0.21.0; extra == 'sqlite'
265
265
  Provides-Extra: tools
266
266
  Requires-Dist: docling>=2.15.0; extra == 'tools'
267
+ Provides-Extra: unstructured
268
+ Requires-Dist: opencv-python>=4.2.0.34; extra == 'unstructured'
269
+ Provides-Extra: xml
270
+ Requires-Dist: xmltodict>=0.12.0; extra == 'xml'
267
271
  Description-Content-Type: text/markdown
268
272
 
269
273
  ![PyPI - Version](https://img.shields.io/pypi/v/lionagi?labelColor=233476aa&color=231fc935)
@@ -4,8 +4,8 @@
4
4
 
5
5
  from pydantic import Field, field_validator
6
6
 
7
+ from lionagi.libs.validate.to_num import to_num
7
8
  from lionagi.models import FieldModel, HashableModel
8
- from lionagi.utils import to_num
9
9
 
10
10
  __all__ = ("Reason",)
11
11
 
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import functools
5
+ from collections.abc import Callable
6
+ from time import sleep, time
7
+ from typing import Any, TypeVar
8
+
9
+ T = TypeVar("T")
10
+
11
+
12
+ __all__ = ("Throttle",)
13
+
14
+
15
+ class Throttle:
16
+ """
17
+ Provide a throttling mechanism for function calls.
18
+
19
+ When used as a decorator, it ensures that the decorated function can only
20
+ be called once per specified period. Subsequent calls within this period
21
+ are delayed to enforce this constraint.
22
+
23
+ Attributes:
24
+ period: The minimum time period (in seconds) between successive calls.
25
+ """
26
+
27
+ def __init__(self, period: float) -> None:
28
+ """
29
+ Initialize a new instance of Throttle.
30
+
31
+ Args:
32
+ period: The minimum time period (in seconds) between
33
+ successive calls.
34
+ """
35
+ self.period = period
36
+ self.last_called = 0
37
+
38
+ def __call__(self, func: Callable[..., T]) -> Callable[..., T]:
39
+ """
40
+ Decorate a synchronous function with the throttling mechanism.
41
+
42
+ Args:
43
+ func: The synchronous function to be throttled.
44
+
45
+ Returns:
46
+ The throttled synchronous function.
47
+ """
48
+
49
+ @functools.wraps(func)
50
+ def wrapper(*args, **kwargs) -> Any:
51
+ elapsed = time() - self.last_called
52
+ if elapsed < self.period:
53
+ sleep(self.period - elapsed)
54
+ self.last_called = time()
55
+ return func(*args, **kwargs)
56
+
57
+ return wrapper
58
+
59
+ def __call_async__(
60
+ self, func: Callable[..., Callable[..., T]]
61
+ ) -> Callable[..., Callable[..., T]]:
62
+ """
63
+ Decorate an asynchronous function with the throttling mechanism.
64
+
65
+ Args:
66
+ func: The asynchronous function to be throttled.
67
+
68
+ Returns:
69
+ The throttled asynchronous function.
70
+ """
71
+
72
+ @functools.wraps(func)
73
+ async def wrapper(*args, **kwargs) -> Any:
74
+ elapsed = time() - self.last_called
75
+ if elapsed < self.period:
76
+ await asyncio.sleep(self.period - elapsed)
77
+ self.last_called = time()
78
+ return await func(*args, **kwargs)
79
+
80
+ return wrapper
@@ -8,7 +8,8 @@ from lionagi.libs.schema.function_to_schema import function_to_schema
8
8
  from lionagi.libs.validate.fuzzy_match_keys import fuzzy_match_keys
9
9
  from lionagi.libs.validate.fuzzy_validate_mapping import fuzzy_validate_mapping
10
10
  from lionagi.libs.validate.string_similarity import string_similarity
11
- from lionagi.utils import fuzzy_parse_json, to_dict, to_json, to_num
11
+ from lionagi.libs.validate.to_num import to_num
12
+ from lionagi.utils import fuzzy_parse_json, to_dict, to_json
12
13
 
13
14
  validate_keys = fuzzy_match_keys # for backward compatibility
14
15
  validate_mapping = fuzzy_validate_mapping # for backward compatibility
@@ -0,0 +1,45 @@
1
+ from lionagi.utils import check_import, is_import_installed
2
+
3
+ _HAS_PDF2IMAGE = is_import_installed("pdf2image")
4
+
5
+
6
+ def pdf_to_images(
7
+ pdf_path: str, output_folder: str, dpi: int = 300, fmt: str = "jpeg"
8
+ ) -> list:
9
+ """
10
+ Convert a PDF file into images, one image per page.
11
+
12
+ Args:
13
+ pdf_path (str): Path to the input PDF file.
14
+ output_folder (str): Directory to save the output images.
15
+ dpi (int): Dots per inch (resolution) for conversion (default: 300).
16
+ fmt (str): Image format (default: 'jpeg'). Use 'png' if preferred.
17
+
18
+ Returns:
19
+ list: A list of file paths for the saved images.
20
+ """
21
+ if not _HAS_PDF2IMAGE:
22
+ raise ModuleNotFoundError(
23
+ "pdf2image is not installed, please install it with `pip install lionagi[unstructured]`"
24
+ )
25
+
26
+ import os
27
+
28
+ convert_from_path = check_import(
29
+ "pdf2image", import_name="convert_from_path"
30
+ )
31
+
32
+ # Ensure the output folder exists
33
+ os.makedirs(output_folder, exist_ok=True)
34
+
35
+ # Convert PDF to a list of PIL Image objects
36
+ images = convert_from_path(pdf_path, dpi=dpi)
37
+
38
+ saved_paths = []
39
+ for i, image in enumerate(images):
40
+ # Construct the output file name
41
+ image_file = os.path.join(output_folder, f"page_{i + 1}.{fmt}")
42
+ image.save(image_file, fmt.upper())
43
+ saved_paths.append(image_file)
44
+
45
+ return saved_paths
@@ -0,0 +1,33 @@
1
+ from pathlib import Path
2
+
3
+ from lionagi.utils import is_import_installed
4
+
5
+ _HAS_OPENCV = is_import_installed("cv2")
6
+
7
+
8
+ __all__ = ("read_image_to_base64",)
9
+
10
+
11
+ def read_image_to_base64(image_path: str | Path) -> str:
12
+ if not _HAS_OPENCV:
13
+ raise ModuleNotFoundError(
14
+ "OpenCV is not installed, please install it with `pip install lionagi[unstructured]`"
15
+ )
16
+
17
+ import base64
18
+
19
+ import cv2
20
+
21
+ image_path = str(image_path)
22
+ image = cv2.imread(image_path, cv2.COLOR_BGR2RGB)
23
+
24
+ if image is None:
25
+ raise ValueError(f"Could not read image from path: {image_path}")
26
+
27
+ file_extension = "." + image_path.split(".")[-1]
28
+
29
+ success, buffer = cv2.imencode(file_extension, image)
30
+ if not success:
31
+ raise ValueError(f"Could not encode image to {file_extension} format.")
32
+ encoded_image = base64.b64encode(buffer).decode("utf-8")
33
+ return encoded_image
@@ -0,0 +1,378 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from decimal import Decimal
5
+ from typing import Any, Literal, TypeVar
6
+
7
+ # Type definitions
8
+ NUM_TYPE_LITERAL = Literal["int", "float", "complex"]
9
+ NUM_TYPES = type[int] | type[float] | type[complex] | NUM_TYPE_LITERAL
10
+ NumericType = TypeVar("NumericType", int, float, complex)
11
+
12
+ # Type mapping
13
+ TYPE_MAP = {"int": int, "float": float, "complex": complex}
14
+
15
+ # Regex patterns for different numeric formats
16
+ PATTERNS = {
17
+ "scientific": r"[-+]?(?:\d*\.)?\d+[eE][-+]?\d+",
18
+ "complex_sci": r"[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?[-+](?:\d*\.)?\d+(?:[eE][-+]?\d+)?[jJ]",
19
+ "complex": r"[-+]?(?:\d*\.)?\d+[-+](?:\d*\.)?\d+[jJ]",
20
+ "pure_imaginary": r"[-+]?(?:\d*\.)?\d*[jJ]",
21
+ "percentage": r"[-+]?(?:\d*\.)?\d+%",
22
+ "fraction": r"[-+]?\d+/\d+",
23
+ "decimal": r"[-+]?(?:\d*\.)?\d+",
24
+ "special": r"[-+]?(?:inf|infinity|nan)",
25
+ }
26
+
27
+
28
+ def to_num(
29
+ input_: Any,
30
+ /,
31
+ *,
32
+ upper_bound: int | float | None = None,
33
+ lower_bound: int | float | None = None,
34
+ num_type: NUM_TYPES = float,
35
+ precision: int | None = None,
36
+ num_count: int = 1,
37
+ ) -> int | float | complex | list[int | float | complex]:
38
+ """Convert input to numeric type(s) with validation and bounds checking.
39
+
40
+ Args:
41
+ input_value: The input to convert to number(s).
42
+ upper_bound: Maximum allowed value (inclusive).
43
+ lower_bound: Minimum allowed value (inclusive).
44
+ num_type: Target numeric type ('int', 'float', 'complex' or type objects).
45
+ precision: Number of decimal places for rounding (float only).
46
+ num_count: Number of numeric values to extract.
47
+
48
+ Returns:
49
+ Converted number(s). Single value if num_count=1, else list.
50
+
51
+ Raises:
52
+ ValueError: For invalid input or out of bounds values.
53
+ TypeError: For invalid input types or invalid type conversions.
54
+ """
55
+ # Validate input
56
+ if isinstance(input_, (list, tuple)):
57
+ raise TypeError("Input cannot be a sequence")
58
+
59
+ # Handle boolean input
60
+ if isinstance(input_, bool):
61
+ return validate_num_type(num_type)(input_)
62
+
63
+ # Handle direct numeric input
64
+ if isinstance(input_, (int, float, complex, Decimal)):
65
+ inferred_type = type(input_)
66
+ if isinstance(input_, Decimal):
67
+ inferred_type = float
68
+ value = float(input_) if not isinstance(input_, complex) else input_
69
+ value = apply_bounds(value, upper_bound, lower_bound)
70
+ value = apply_precision(value, precision)
71
+ return convert_type(value, validate_num_type(num_type), inferred_type)
72
+
73
+ # Convert input to string and extract numbers
74
+ input_str = str(input_)
75
+ number_matches = extract_numbers(input_str)
76
+
77
+ if not number_matches:
78
+ raise ValueError(f"No valid numbers found in: {input_str}")
79
+
80
+ # Process numbers
81
+ results = []
82
+ target_type = validate_num_type(num_type)
83
+
84
+ number_matches = (
85
+ number_matches[:num_count]
86
+ if num_count < len(number_matches)
87
+ else number_matches
88
+ )
89
+
90
+ for type_and_value in number_matches:
91
+ try:
92
+ # Infer appropriate type
93
+ inferred_type = infer_type(type_and_value)
94
+
95
+ # Parse to numeric value
96
+ value = parse_number(type_and_value)
97
+
98
+ # Apply bounds if not complex
99
+ value = apply_bounds(value, upper_bound, lower_bound)
100
+
101
+ # Apply precision
102
+ value = apply_precision(value, precision)
103
+
104
+ # Convert to target type if different from inferred
105
+ value = convert_type(value, target_type, inferred_type)
106
+
107
+ results.append(value)
108
+
109
+ except Exception as e:
110
+ if len(type_and_value) == 2:
111
+ raise type(e)(
112
+ f"Error processing {type_and_value[1]}: {str(e)}"
113
+ )
114
+ raise type(e)(f"Error processing {type_and_value}: {str(e)}")
115
+
116
+ if results and num_count == 1:
117
+ return results[0]
118
+ return results
119
+
120
+
121
+ def extract_numbers(text: str) -> list[tuple[str, str]]:
122
+ """Extract numeric values from text using ordered regex patterns.
123
+
124
+ Args:
125
+ text: The text to extract numbers from.
126
+
127
+ Returns:
128
+ List of tuples containing (pattern_type, matched_value).
129
+ """
130
+ combined_pattern = "|".join(PATTERNS.values())
131
+ matches = re.finditer(combined_pattern, text, re.IGNORECASE)
132
+ numbers = []
133
+
134
+ for match in matches:
135
+ value = match.group()
136
+ # Check which pattern matched
137
+ for pattern_name, pattern in PATTERNS.items():
138
+ if re.fullmatch(pattern, value, re.IGNORECASE):
139
+ numbers.append((pattern_name, value))
140
+ break
141
+
142
+ return numbers
143
+
144
+
145
+ def validate_num_type(num_type: NUM_TYPES) -> type:
146
+ """Validate and normalize numeric type specification.
147
+
148
+ Args:
149
+ num_type: The numeric type to validate.
150
+
151
+ Returns:
152
+ The normalized Python type object.
153
+
154
+ Raises:
155
+ ValueError: If the type specification is invalid.
156
+ """
157
+ if isinstance(num_type, str):
158
+ if num_type not in TYPE_MAP:
159
+ raise ValueError(f"Invalid number type: {num_type}")
160
+ return TYPE_MAP[num_type]
161
+
162
+ if num_type not in (int, float, complex):
163
+ raise ValueError(f"Invalid number type: {num_type}")
164
+ return num_type
165
+
166
+
167
+ def infer_type(value: tuple[str, str]) -> type:
168
+ """Infer appropriate numeric type from value.
169
+
170
+ Args:
171
+ value: Tuple of (pattern_type, matched_value).
172
+
173
+ Returns:
174
+ The inferred Python type.
175
+ """
176
+ pattern_type, _ = value
177
+ if pattern_type in ("complex", "complex_sci", "pure_imaginary"):
178
+ return complex
179
+ return float
180
+
181
+
182
+ def convert_special(value: str) -> float:
183
+ """Convert special float values (inf, -inf, nan).
184
+
185
+ Args:
186
+ value: The string value to convert.
187
+
188
+ Returns:
189
+ The converted float value.
190
+ """
191
+ value = value.lower()
192
+ if "infinity" in value or "inf" in value:
193
+ return float("-inf") if value.startswith("-") else float("inf")
194
+ return float("nan")
195
+
196
+
197
+ def convert_percentage(value: str) -> float:
198
+ """Convert percentage string to float.
199
+
200
+ Args:
201
+ value: The percentage string to convert.
202
+
203
+ Returns:
204
+ The converted float value.
205
+
206
+ Raises:
207
+ ValueError: If the percentage value is invalid.
208
+ """
209
+ try:
210
+ return float(value.rstrip("%")) / 100
211
+ except ValueError as e:
212
+ raise ValueError(f"Invalid percentage value: {value}") from e
213
+
214
+
215
+ def convert_complex(value: str) -> complex:
216
+ """Convert complex number string to complex.
217
+
218
+ Args:
219
+ value: The complex number string to convert.
220
+
221
+ Returns:
222
+ The converted complex value.
223
+
224
+ Raises:
225
+ ValueError: If the complex number is invalid.
226
+ """
227
+ try:
228
+ # Handle pure imaginary numbers
229
+ if value.endswith("j") or value.endswith("J"):
230
+ if value in ("j", "J"):
231
+ return complex(0, 1)
232
+ if value in ("+j", "+J"):
233
+ return complex(0, 1)
234
+ if value in ("-j", "-J"):
235
+ return complex(0, -1)
236
+ if "+" not in value and "-" not in value[1:]:
237
+ # Pure imaginary number
238
+ imag = float(value[:-1] or "1")
239
+ return complex(0, imag)
240
+
241
+ return complex(value.replace(" ", ""))
242
+ except ValueError as e:
243
+ raise ValueError(f"Invalid complex number: {value}") from e
244
+
245
+
246
+ def convert_type(
247
+ value: float | complex,
248
+ target_type: type,
249
+ inferred_type: type,
250
+ ) -> int | float | complex:
251
+ """Convert value to target type if specified, otherwise use inferred type.
252
+
253
+ Args:
254
+ value: The value to convert.
255
+ target_type: The requested target type.
256
+ inferred_type: The inferred type from the value.
257
+
258
+ Returns:
259
+ The converted value.
260
+
261
+ Raises:
262
+ TypeError: If the conversion is not possible.
263
+ """
264
+ try:
265
+ # If no specific type requested, use inferred type
266
+ if target_type is float and inferred_type is complex:
267
+ return value
268
+
269
+ # Handle explicit type conversions
270
+ if target_type is int and isinstance(value, complex):
271
+ raise TypeError("Cannot convert complex number to int")
272
+ return target_type(value)
273
+ except (ValueError, TypeError) as e:
274
+ raise TypeError(
275
+ f"Cannot convert {value} to {target_type.__name__}"
276
+ ) from e
277
+
278
+
279
+ def apply_bounds(
280
+ value: float | complex,
281
+ upper_bound: float | None = None,
282
+ lower_bound: float | None = None,
283
+ ) -> float | complex:
284
+ """Apply bounds checking to numeric value.
285
+
286
+ Args:
287
+ value: The value to check.
288
+ upper_bound: Maximum allowed value (inclusive).
289
+ lower_bound: Minimum allowed value (inclusive).
290
+
291
+ Returns:
292
+ The validated value.
293
+
294
+ Raises:
295
+ ValueError: If the value is outside bounds.
296
+ """
297
+ if isinstance(value, complex):
298
+ return value
299
+
300
+ if upper_bound is not None and value > upper_bound:
301
+ raise ValueError(f"Value {value} exceeds upper bound {upper_bound}")
302
+ if lower_bound is not None and value < lower_bound:
303
+ raise ValueError(f"Value {value} below lower bound {lower_bound}")
304
+ return value
305
+
306
+
307
+ def apply_precision(
308
+ value: float | complex,
309
+ precision: int | None,
310
+ ) -> float | complex:
311
+ """Apply precision rounding to numeric value.
312
+
313
+ Args:
314
+ value: The value to round.
315
+ precision: Number of decimal places.
316
+
317
+ Returns:
318
+ The rounded value.
319
+ """
320
+ if precision is None or isinstance(value, complex):
321
+ return value
322
+ if isinstance(value, float):
323
+ return round(value, precision)
324
+ return value
325
+
326
+
327
+ def parse_number(type_and_value: tuple[str, str]) -> float | complex:
328
+ """Parse string to numeric value based on pattern type.
329
+
330
+ Args:
331
+ type_and_value: Tuple of (pattern_type, matched_value).
332
+
333
+ Returns:
334
+ The parsed numeric value.
335
+
336
+ Raises:
337
+ ValueError: If parsing fails.
338
+ """
339
+ num_type, value = type_and_value
340
+ value = value.strip()
341
+
342
+ try:
343
+ if num_type == "special":
344
+ return convert_special(value)
345
+
346
+ if num_type == "percentage":
347
+ return convert_percentage(value)
348
+
349
+ if num_type == "fraction":
350
+ if "/" not in value:
351
+ raise ValueError(f"Invalid fraction: {value}")
352
+ if value.count("/") > 1:
353
+ raise ValueError(f"Invalid fraction: {value}")
354
+ num, denom = value.split("/")
355
+ if not (num.strip("-").isdigit() and denom.isdigit()):
356
+ raise ValueError(f"Invalid fraction: {value}")
357
+ denom_val = float(denom)
358
+ if denom_val == 0:
359
+ raise ValueError("Division by zero")
360
+ return float(num) / denom_val
361
+ if num_type in ("complex", "complex_sci", "pure_imaginary"):
362
+ return convert_complex(value)
363
+ if num_type == "scientific":
364
+ if "e" not in value.lower():
365
+ raise ValueError(f"Invalid scientific notation: {value}")
366
+ parts = value.lower().split("e")
367
+ if len(parts) != 2:
368
+ raise ValueError(f"Invalid scientific notation: {value}")
369
+ if not (parts[1].lstrip("+-").isdigit()):
370
+ raise ValueError(f"Invalid scientific notation: {value}")
371
+ return float(value)
372
+ if num_type == "decimal":
373
+ return float(value)
374
+
375
+ raise ValueError(f"Unknown number type: {num_type}")
376
+ except Exception as e:
377
+ # Preserve the specific error type but wrap with more context
378
+ raise type(e)(f"Failed to parse {value} as {num_type}: {str(e)}")