lionagi 0.16.3__tar.gz → 0.17.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. {lionagi-0.16.3 → lionagi-0.17.0}/PKG-INFO +2 -2
  2. lionagi-0.17.0/lionagi/adapters/_utils.py +13 -0
  3. lionagi-0.17.0/lionagi/adapters/async_postgres_adapter.py +102 -0
  4. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/__init__.py +0 -4
  5. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/_json_dump.py +0 -6
  6. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/__init__.py +0 -6
  7. lionagi-0.17.0/lionagi/operations/_visualize_graph.py +285 -0
  8. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/brainstorm/brainstorm.py +14 -12
  9. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/builder.py +23 -302
  10. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/flow.py +14 -11
  11. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/node.py +14 -3
  12. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/operate/operate.py +5 -11
  13. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/parse/parse.py +1 -2
  14. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/types.py +0 -2
  15. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/utils.py +11 -5
  16. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/pile.py +2 -6
  17. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/graph/graph.py +23 -6
  18. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/graph/node.py +0 -2
  19. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/message.py +0 -1
  20. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/types.py +0 -15
  21. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/endpoint.py +11 -5
  22. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/session/branch.py +24 -18
  23. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/session/session.py +2 -18
  24. lionagi-0.17.0/lionagi/version.py +1 -0
  25. {lionagi-0.16.3 → lionagi-0.17.0}/pyproject.toml +2 -2
  26. {lionagi-0.16.3 → lionagi-0.17.0}/uv.lock +3 -6
  27. lionagi-0.16.3/lionagi/adapters/_utils.py +0 -12
  28. lionagi-0.16.3/lionagi/adapters/async_postgres_adapter.py +0 -98
  29. lionagi-0.16.3/lionagi/protocols/graph/_utils.py +0 -22
  30. lionagi-0.16.3/lionagi/version.py +0 -1
  31. {lionagi-0.16.3 → lionagi-0.17.0}/.coveragerc +0 -0
  32. {lionagi-0.16.3 → lionagi-0.17.0}/.env.example +0 -0
  33. {lionagi-0.16.3 → lionagi-0.17.0}/.github/FUNDING.yml +0 -0
  34. {lionagi-0.16.3 → lionagi-0.17.0}/.github/dependabot.yml +0 -0
  35. {lionagi-0.16.3 → lionagi-0.17.0}/.github/workflows/benchmarks.yml +0 -0
  36. {lionagi-0.16.3 → lionagi-0.17.0}/.github/workflows/ci.yml +0 -0
  37. {lionagi-0.16.3 → lionagi-0.17.0}/.github/workflows/codeql.yml +0 -0
  38. {lionagi-0.16.3 → lionagi-0.17.0}/.github/workflows/docs-deploy.yml +0 -0
  39. {lionagi-0.16.3 → lionagi-0.17.0}/.github/workflows/refresh-bench-baselines.yml +0 -0
  40. {lionagi-0.16.3 → lionagi-0.17.0}/.github/workflows/release.yml +0 -0
  41. {lionagi-0.16.3 → lionagi-0.17.0}/.gitignore +0 -0
  42. {lionagi-0.16.3 → lionagi-0.17.0}/.pre-commit-config.yaml +0 -0
  43. {lionagi-0.16.3 → lionagi-0.17.0}/.python-version +0 -0
  44. {lionagi-0.16.3 → lionagi-0.17.0}/CODE_OF_CONDUCT.md +0 -0
  45. {lionagi-0.16.3 → lionagi-0.17.0}/CONTRIBUTING.md +0 -0
  46. {lionagi-0.16.3 → lionagi-0.17.0}/LICENSE +0 -0
  47. {lionagi-0.16.3 → lionagi-0.17.0}/README.md +0 -0
  48. {lionagi-0.16.3 → lionagi-0.17.0}/assets/operation_builder.gif +0 -0
  49. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/README.md +0 -0
  50. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/baselines/.gitkeep +0 -0
  51. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/baselines/concurrency-asyncio.json +0 -0
  52. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/baselines/concurrency-trio.json +0 -0
  53. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/baselines/fuzzy.json +0 -0
  54. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/baselines/ln-asyncio.json +0 -0
  55. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/baselines/ln-trio.json +0 -0
  56. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/ci_compare.py +0 -0
  57. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/concurrency_bench.py +0 -0
  58. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/fuzzy_bench.py +0 -0
  59. {lionagi-0.16.3 → lionagi-0.17.0}/benchmarks/ln_bench.py +0 -0
  60. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/001_branch_converse.ipynb +0 -0
  61. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/002_branch_interact.ipynb +0 -0
  62. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/003_branch_info.ipynb +0 -0
  63. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/004_conversation_patterns.ipynb +0 -0
  64. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/005_react_basics.ipynb +0 -0
  65. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
  66. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/007_fan_out_in.py +0 -0
  67. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/claude_proxy/README.md +0 -0
  68. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/claude_proxy/claude_code_proxy.py +0 -0
  69. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
  70. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/data/002_comedian.json +0 -0
  71. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/data/002_critic.json +0 -0
  72. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/data/006_lion_proof_ch2.md +0 -0
  73. {lionagi-0.16.3 → lionagi-0.17.0}/cookbooks/using_claude_code.py +0 -0
  74. {lionagi-0.16.3 → lionagi-0.17.0}/docs/DOCUMENTATION_STANDARDS.md +0 -0
  75. {lionagi-0.16.3 → lionagi-0.17.0}/docs/advanced/custom-operations.md +0 -0
  76. {lionagi-0.16.3 → lionagi-0.17.0}/docs/advanced/error-handling.md +0 -0
  77. {lionagi-0.16.3 → lionagi-0.17.0}/docs/advanced/flow-composition.md +0 -0
  78. {lionagi-0.16.3 → lionagi-0.17.0}/docs/advanced/index.md +0 -0
  79. {lionagi-0.16.3 → lionagi-0.17.0}/docs/advanced/observability.md +0 -0
  80. {lionagi-0.16.3 → lionagi-0.17.0}/docs/advanced/performance.md +0 -0
  81. {lionagi-0.16.3 → lionagi-0.17.0}/docs/code-of-conduct.md +0 -0
  82. {lionagi-0.16.3 → lionagi-0.17.0}/docs/comparisons/langgraph.md +0 -0
  83. {lionagi-0.16.3 → lionagi-0.17.0}/docs/contributing.md +0 -0
  84. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/brainstorming.md +0 -0
  85. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/claim-extraction.md +0 -0
  86. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/code-review-crew.md +0 -0
  87. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/data-persistence.md +0 -0
  88. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/hr-automation.md +0 -0
  89. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/index.md +0 -0
  90. {lionagi-0.16.3 → lionagi-0.17.0}/docs/cookbook/research-synthesis.md +0 -0
  91. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/index.md +0 -0
  92. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/lionagi-philosophy.md +0 -0
  93. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/messages-and-memory.md +0 -0
  94. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/models-and-providers.md +0 -0
  95. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/operations.md +0 -0
  96. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/sessions-and-branches.md +0 -0
  97. {lionagi-0.16.3 → lionagi-0.17.0}/docs/core-concepts/tools-and-functions.md +0 -0
  98. {lionagi-0.16.3 → lionagi-0.17.0}/docs/for-ai-agents/claude-code-usage.md +0 -0
  99. {lionagi-0.16.3 → lionagi-0.17.0}/docs/for-ai-agents/index.md +0 -0
  100. {lionagi-0.16.3 → lionagi-0.17.0}/docs/for-ai-agents/orchestration-guide.md +0 -0
  101. {lionagi-0.16.3 → lionagi-0.17.0}/docs/for-ai-agents/pattern-selection.md +0 -0
  102. {lionagi-0.16.3 → lionagi-0.17.0}/docs/for-ai-agents/self-improvement.md +0 -0
  103. {lionagi-0.16.3 → lionagi-0.17.0}/docs/includes/abbreviations.md +0 -0
  104. {lionagi-0.16.3 → lionagi-0.17.0}/docs/index.md +0 -0
  105. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/databases.md +0 -0
  106. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/dspy-optimization.md +0 -0
  107. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/index.md +0 -0
  108. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/llamaindex-rag.md +0 -0
  109. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/llm-providers.md +0 -0
  110. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/mcp-servers.md +0 -0
  111. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/tools.md +0 -0
  112. {lionagi-0.16.3 → lionagi-0.17.0}/docs/integrations/vector-stores.md +0 -0
  113. {lionagi-0.16.3 → lionagi-0.17.0}/docs/marketing/language-interoperability-manifesto.md +0 -0
  114. {lionagi-0.16.3 → lionagi-0.17.0}/docs/migration/from-autogen.md +0 -0
  115. {lionagi-0.16.3 → lionagi-0.17.0}/docs/migration/from-crewai.md +0 -0
  116. {lionagi-0.16.3 → lionagi-0.17.0}/docs/migration/from-langchain.md +0 -0
  117. {lionagi-0.16.3 → lionagi-0.17.0}/docs/migration/index.md +0 -0
  118. {lionagi-0.16.3 → lionagi-0.17.0}/docs/patterns/conditional-flows.md +0 -0
  119. {lionagi-0.16.3 → lionagi-0.17.0}/docs/patterns/fan-out-in.md +0 -0
  120. {lionagi-0.16.3 → lionagi-0.17.0}/docs/patterns/index.md +0 -0
  121. {lionagi-0.16.3 → lionagi-0.17.0}/docs/patterns/react-with-rag.md +0 -0
  122. {lionagi-0.16.3 → lionagi-0.17.0}/docs/patterns/sequential-analysis.md +0 -0
  123. {lionagi-0.16.3 → lionagi-0.17.0}/docs/patterns/tournament-validation.md +0 -0
  124. {lionagi-0.16.3 → lionagi-0.17.0}/docs/problem-statement.md +0 -0
  125. {lionagi-0.16.3 → lionagi-0.17.0}/docs/quickstart/claude-code-integration.md +0 -0
  126. {lionagi-0.16.3 → lionagi-0.17.0}/docs/quickstart/index.md +0 -0
  127. {lionagi-0.16.3 → lionagi-0.17.0}/docs/quickstart/installation.md +0 -0
  128. {lionagi-0.16.3 → lionagi-0.17.0}/docs/quickstart/orchestration-first.md +0 -0
  129. {lionagi-0.16.3 → lionagi-0.17.0}/docs/quickstart/your-first-flow.md +0 -0
  130. {lionagi-0.16.3 → lionagi-0.17.0}/docs/reference/api/index.md +0 -0
  131. {lionagi-0.16.3 → lionagi-0.17.0}/docs/reference/changelog.md +0 -0
  132. {lionagi-0.16.3 → lionagi-0.17.0}/docs/reference/troubleshooting.md +0 -0
  133. {lionagi-0.16.3 → lionagi-0.17.0}/docs/stylesheets/extra.css +0 -0
  134. {lionagi-0.16.3 → lionagi-0.17.0}/docs/thinking-in-lionagi/branches-as-agents.md +0 -0
  135. {lionagi-0.16.3 → lionagi-0.17.0}/docs/thinking-in-lionagi/builder-pattern.md +0 -0
  136. {lionagi-0.16.3 → lionagi-0.17.0}/docs/thinking-in-lionagi/graphs-over-chains.md +0 -0
  137. {lionagi-0.16.3 → lionagi-0.17.0}/docs/thinking-in-lionagi/index.md +0 -0
  138. {lionagi-0.16.3 → lionagi-0.17.0}/docs/thinking-in-lionagi/why-lionagi.md +0 -0
  139. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/__init__.py +0 -0
  140. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/_class_registry.py +0 -0
  141. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/_errors.py +0 -0
  142. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/_types.py +0 -0
  143. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/adapters/__init__.py +0 -0
  144. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/config.py +0 -0
  145. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/__init__.py +0 -0
  146. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/action.py +0 -0
  147. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/base.py +0 -0
  148. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/code.py +0 -0
  149. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/file.py +0 -0
  150. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/instruct.py +0 -0
  151. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/reason.py +0 -0
  152. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/fields/research.py +0 -0
  153. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/__init__.py +0 -0
  154. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/__init__.py +0 -0
  155. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/_utils.py +0 -0
  156. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/chunk.py +0 -0
  157. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/concat.py +0 -0
  158. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/concat_files.py +0 -0
  159. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/file_ops.py +0 -0
  160. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/process.py +0 -0
  161. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/file/save.py +0 -0
  162. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/schema/__init__.py +0 -0
  163. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/schema/as_readable.py +0 -0
  164. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/schema/extract_code_block.py +0 -0
  165. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/schema/extract_docstring.py +0 -0
  166. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/schema/function_to_schema.py +0 -0
  167. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
  168. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/validate/__init__.py +0 -0
  169. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/validate/common_field_validators.py +0 -0
  170. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/validate/to_num.py +0 -0
  171. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/libs/validate/validate_boolean.py +0 -0
  172. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/_async_call.py +0 -0
  173. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/_hash.py +0 -0
  174. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/_list_call.py +0 -0
  175. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/_to_list.py +0 -0
  176. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/_utils.py +0 -0
  177. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/__init__.py +0 -0
  178. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/_compat.py +0 -0
  179. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/cancel.py +0 -0
  180. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/errors.py +0 -0
  181. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/patterns.py +0 -0
  182. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/primitives.py +0 -0
  183. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/resource_tracker.py +0 -0
  184. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/task.py +0 -0
  185. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/throttle.py +0 -0
  186. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/concurrency/utils.py +0 -0
  187. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/__init__.py +0 -0
  188. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/_extract_json.py +0 -0
  189. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/_fuzzy_json.py +0 -0
  190. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/_fuzzy_match.py +0 -0
  191. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/_fuzzy_validate.py +0 -0
  192. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/_string_similarity.py +0 -0
  193. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/fuzzy/_to_dict.py +0 -0
  194. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/ln/types.py +0 -0
  195. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/models/__init__.py +0 -0
  196. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/models/field_model.py +0 -0
  197. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/models/hashable_model.py +0 -0
  198. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/models/model_params.py +0 -0
  199. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/models/operable_model.py +0 -0
  200. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/models/schema_model.py +0 -0
  201. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/ReAct/ReAct.py +0 -0
  202. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/ReAct/__init__.py +0 -0
  203. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/ReAct/utils.py +0 -0
  204. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/_act/__init__.py +0 -0
  205. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/_act/act.py +0 -0
  206. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/brainstorm/__init__.py +0 -0
  207. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/brainstorm/prompt.py +0 -0
  208. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/chat/__init__.py +0 -0
  209. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/chat/chat.py +0 -0
  210. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/communicate/__init__.py +0 -0
  211. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/communicate/communicate.py +0 -0
  212. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/instruct/__init__.py +0 -0
  213. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/instruct/instruct.py +0 -0
  214. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/interpret/__init__.py +0 -0
  215. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/interpret/interpret.py +0 -0
  216. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/manager.py +0 -0
  217. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/operate/__init__.py +0 -0
  218. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/parse/__init__.py +0 -0
  219. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/plan/__init__.py +0 -0
  220. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/plan/plan.py +0 -0
  221. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/plan/prompt.py +0 -0
  222. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/select/__init__.py +0 -0
  223. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/select/select.py +0 -0
  224. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/operations/select/utils.py +0 -0
  225. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/__init__.py +0 -0
  226. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/_concepts.py +0 -0
  227. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/action/__init__.py +0 -0
  228. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/action/function_calling.py +0 -0
  229. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/action/manager.py +0 -0
  230. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/action/tool.py +0 -0
  231. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/contracts.py +0 -0
  232. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/forms/__init__.py +0 -0
  233. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/forms/base.py +0 -0
  234. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/forms/flow.py +0 -0
  235. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/forms/form.py +0 -0
  236. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/forms/report.py +0 -0
  237. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/__init__.py +0 -0
  238. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/element.py +0 -0
  239. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/event.py +0 -0
  240. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/log.py +0 -0
  241. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/processor.py +0 -0
  242. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/generic/progression.py +0 -0
  243. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/graph/__init__.py +0 -0
  244. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/graph/edge.py +0 -0
  245. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/ids.py +0 -0
  246. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/mail/__init__.py +0 -0
  247. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/mail/exchange.py +0 -0
  248. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/mail/mail.py +0 -0
  249. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/mail/mailbox.py +0 -0
  250. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/mail/manager.py +0 -0
  251. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/mail/package.py +0 -0
  252. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/__init__.py +0 -0
  253. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/action_request.py +0 -0
  254. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/action_response.py +0 -0
  255. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/assistant_response.py +0 -0
  256. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/base.py +0 -0
  257. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/instruction.py +0 -0
  258. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/manager.py +0 -0
  259. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/system.py +0 -0
  260. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/README.md +0 -0
  261. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
  262. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
  263. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
  264. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
  265. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
  266. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
  267. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/operatives/__init__.py +0 -0
  268. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/operatives/operative.py +0 -0
  269. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/protocols/operatives/step.py +0 -0
  270. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/py.typed +0 -0
  271. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/__init__.py +0 -0
  272. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/__init__.py +0 -0
  273. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/api_calling.py +0 -0
  274. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/endpoint_config.py +0 -0
  275. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/header_factory.py +0 -0
  276. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/match_endpoint.py +0 -0
  277. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/__init__.py +0 -0
  278. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/anthropic_.py +0 -0
  279. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
  280. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/exa_.py +0 -0
  281. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/nvidia_nim_.py +0 -0
  282. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/oai_.py +0 -0
  283. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/ollama_.py +0 -0
  284. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/perplexity_.py +0 -0
  285. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/connections/providers/types.py +0 -0
  286. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/hooks/__init__.py +0 -0
  287. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/hooks/_types.py +0 -0
  288. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/hooks/_utils.py +0 -0
  289. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/hooks/hook_event.py +0 -0
  290. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/hooks/hook_registry.py +0 -0
  291. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/imodel.py +0 -0
  292. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/manager.py +0 -0
  293. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/rate_limited_processor.py +0 -0
  294. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/resilience.py +0 -0
  295. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/README.md +0 -0
  296. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/__init__.py +0 -0
  297. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/anthropic_models.py +0 -0
  298. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/claude_code.py +0 -0
  299. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/exa_models.py +0 -0
  300. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/openai_model_names.py +0 -0
  301. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/third_party/pplx_models.py +0 -0
  302. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/token_calculator.py +0 -0
  303. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/service/types.py +0 -0
  304. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/session/__init__.py +0 -0
  305. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/session/prompts.py +0 -0
  306. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/settings.py +0 -0
  307. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/tools/__init__.py +0 -0
  308. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/tools/base.py +0 -0
  309. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/tools/file/__init__.py +0 -0
  310. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/tools/file/reader.py +0 -0
  311. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/tools/types.py +0 -0
  312. {lionagi-0.16.3 → lionagi-0.17.0}/lionagi/utils.py +0 -0
  313. {lionagi-0.16.3 → lionagi-0.17.0}/main.py +0 -0
  314. {lionagi-0.16.3 → lionagi-0.17.0}/mkdocs.yml +0 -0
  315. {lionagi-0.16.3 → lionagi-0.17.0}/scripts/README.md +0 -0
  316. {lionagi-0.16.3 → lionagi-0.17.0}/scripts/update_openai_models.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.16.3
3
+ Version: 0.17.0
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -228,7 +228,7 @@ Requires-Dist: json-repair>=0.40.0
228
228
  Requires-Dist: msgspec>=0.18.0
229
229
  Requires-Dist: pydantic-settings>=2.8.0
230
230
  Requires-Dist: pydantic>=2.8.0
231
- Requires-Dist: pydapter[pandas]>=1.1.1
231
+ Requires-Dist: pydapter>=1.1.1
232
232
  Requires-Dist: python-dotenv>=1.1.0
233
233
  Requires-Dist: tiktoken>=0.9.0
234
234
  Provides-Extra: all
@@ -0,0 +1,13 @@
1
+ def check_async_postgres_available():
2
+ from lionagi.utils import is_import_installed
3
+
4
+ all_import_present = 0
5
+ for pkg in ("sqlalchemy", "asyncpg"):
6
+ if is_import_installed(pkg):
7
+ all_import_present += 1
8
+ if all_import_present == 2:
9
+ return True
10
+ return ImportError(
11
+ "This adapter requires postgres option to be installed. "
12
+ 'Please install them using `uv pip install "lionagi[postgres]"`.'
13
+ )
@@ -0,0 +1,102 @@
1
+ """
2
+ Simplified LionAGI async PostgreSQL adapter for pydapter v1.0.4+
3
+
4
+ This adapter leverages pydapter's improved raw SQL handling.
5
+ No workarounds needed - pydapter now properly handles:
6
+ - Raw SQL without table parameter
7
+ - No table inspection for raw SQL
8
+ - ORDER BY operations
9
+ - Both SQLite and PostgreSQL connections
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import ClassVar, TypeVar
15
+
16
+ from pydapter import AsyncAdapter
17
+
18
+ T = TypeVar("T")
19
+
20
+
21
+ def create_lionagi_async_postgres_adapter() -> type[AsyncAdapter]:
22
+ from pydapter.extras.async_postgres_ import AsyncPostgresAdapter
23
+
24
+ class LionAGIAsyncPostgresAdapter(AsyncPostgresAdapter[T]):
25
+ """
26
+ Streamlined async adapter for lionagi Nodes.
27
+
28
+ Features:
29
+ - Auto-creates tables with lionagi schema
30
+ - Inherits all pydapter v1.0.4+ improvements
31
+ - No workarounds needed for SQLite or raw SQL
32
+ """
33
+
34
+ obj_key: ClassVar[str] = "lionagi_async_pg"
35
+
36
+ @classmethod
37
+ async def to_obj(
38
+ cls,
39
+ subj,
40
+ /,
41
+ *,
42
+ many: bool = True,
43
+ adapt_meth: str = None,
44
+ **kw,
45
+ ):
46
+ """Write lionagi Node(s) to database with auto-table creation."""
47
+ # Auto-create table if needed
48
+ if table := kw.get("table"):
49
+ if engine_url := (kw.get("dsn") or kw.get("engine_url")):
50
+ await cls._ensure_table(engine_url, table)
51
+ elif engine := kw.get("engine"):
52
+ await cls._ensure_table(engine, table)
53
+
54
+ return await super().to_obj(
55
+ subj, many=many, adapt_meth=adapt_meth, **kw
56
+ )
57
+
58
+ @classmethod
59
+ async def _ensure_table(cls, engine_or_url, table_name: str):
60
+ """Create table with lionagi schema if it doesn't exist."""
61
+ import sqlalchemy as sa
62
+ from sqlalchemy.ext.asyncio import create_async_engine
63
+
64
+ should_dispose = False
65
+ if isinstance(engine_or_url, str):
66
+ engine = create_async_engine(engine_or_url, future=True)
67
+ should_dispose = True
68
+ else:
69
+ engine = engine_or_url
70
+
71
+ try:
72
+ async with engine.begin() as conn:
73
+ # Determine JSON type based on database
74
+ engine_url = str(engine.url)
75
+ json_type = (
76
+ sa.dialects.postgresql.JSONB
77
+ if "postgresql" in engine_url
78
+ else sa.JSON
79
+ )
80
+
81
+ # Create table with lionagi schema
82
+ await conn.run_sync(
83
+ lambda sync_conn: sa.Table(
84
+ table_name,
85
+ sa.MetaData(),
86
+ sa.Column("id", sa.String, primary_key=True),
87
+ sa.Column("content", json_type),
88
+ sa.Column("node_metadata", json_type),
89
+ sa.Column("created_at", sa.Float),
90
+ sa.Column("embedding", json_type, nullable=True),
91
+ ).create(sync_conn, checkfirst=True)
92
+ )
93
+ finally:
94
+ if should_dispose:
95
+ await engine.dispose()
96
+
97
+ return LionAGIAsyncPostgresAdapter
98
+
99
+
100
+ LionAGIAsyncPostgresAdapter = create_lionagi_async_postgres_adapter()
101
+
102
+ __all__ = ("LionAGIAsyncPostgresAdapter",)
@@ -1,8 +1,6 @@
1
1
  from ._async_call import alcall, bcall
2
2
  from ._hash import hash_dict
3
3
  from ._json_dump import (
4
- DEFAULT_SERIALIZER,
5
- DEFAULT_SERIALIZER_OPTION,
6
4
  get_orjson_default,
7
5
  json_dumpb,
8
6
  json_dumps,
@@ -48,8 +46,6 @@ __all__ = (
48
46
  "alcall",
49
47
  "bcall",
50
48
  "hash_dict",
51
- "DEFAULT_SERIALIZER",
52
- "DEFAULT_SERIALIZER_OPTION",
53
49
  "get_orjson_default",
54
50
  "json_dumps",
55
51
  "make_options",
@@ -15,8 +15,6 @@ import orjson
15
15
 
16
16
  __all__ = [
17
17
  "get_orjson_default",
18
- "DEFAULT_SERIALIZER",
19
- "DEFAULT_SERIALIZER_OPTION",
20
18
  "make_options",
21
19
  "json_dumpb",
22
20
  "json_dumps",
@@ -193,10 +191,6 @@ def _cached_default(
193
191
 
194
192
  # --------- defaults & options -------------------------------------------------
195
193
 
196
- # Compact, no newline, no sorting: neutral default for most use-cases.
197
- DEFAULT_SERIALIZER_OPTION = 0
198
- DEFAULT_SERIALIZER = get_orjson_default()
199
-
200
194
 
201
195
  def make_options(
202
196
  *,
@@ -2,11 +2,9 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from .brainstorm.brainstorm import BrainstormOperation, brainstorm
6
5
  from .builder import ExpansionStrategy, OperationGraphBuilder
7
6
  from .flow import flow
8
7
  from .node import BranchOperations, Operation
9
- from .plan.plan import PlanOperation, plan
10
8
 
11
9
  Builder = OperationGraphBuilder
12
10
 
@@ -17,9 +15,5 @@ __all__ = (
17
15
  "flow",
18
16
  "BranchOperations",
19
17
  "Operation",
20
- "plan",
21
- "PlanOperation",
22
- "brainstorm",
23
- "BrainstormOperation",
24
18
  "Builder",
25
19
  )
@@ -0,0 +1,285 @@
1
+ def visualize_graph(
2
+ builder,
3
+ title: str = "Operation Graph",
4
+ figsize=(14, 10),
5
+ ):
6
+ """Visualization with improved layout for complex graphs."""
7
+ from lionagi.utils import is_import_installed
8
+
9
+ if not is_import_installed("matplotlib"):
10
+ raise ImportError(
11
+ "matplotlib is required for visualization. "
12
+ "Please install it using `pip install matplotlib`."
13
+ )
14
+ if not is_import_installed("networkx"):
15
+ raise ImportError(
16
+ "networkx is required for visualization. "
17
+ "Please install it using `pip install networkx`."
18
+ )
19
+
20
+ import matplotlib.pyplot as plt
21
+ import networkx as nx
22
+ import numpy as np
23
+
24
+ graph = builder.get_graph()
25
+
26
+ # Convert to networkx
27
+ G = nx.DiGraph()
28
+
29
+ # Track node positions for hierarchical layout
30
+ node_levels = {}
31
+ node_labels = {}
32
+ node_colors = []
33
+ node_sizes = []
34
+
35
+ # First pass: add nodes and determine levels
36
+ for node in graph.internal_nodes.values():
37
+ node_id = str(node.id)[:8]
38
+ G.add_node(node_id)
39
+
40
+ # Determine level based on dependencies
41
+ in_edges = [
42
+ e
43
+ for e in graph.internal_edges.values()
44
+ if str(e.tail)[:8] == node_id
45
+ ]
46
+ if not in_edges:
47
+ level = 0 # Root nodes
48
+ else:
49
+ # Get max level of predecessors + 1
50
+ pred_levels = []
51
+ for edge in in_edges:
52
+ pred_id = str(edge.head)[:8]
53
+ if pred_id in node_levels:
54
+ pred_levels.append(node_levels[pred_id])
55
+ level = max(pred_levels, default=0) + 1
56
+
57
+ node_levels[node_id] = level
58
+
59
+ # Create label
60
+ ref_id = node.metadata.get("reference_id", "")
61
+ if ref_id:
62
+ label = f"{node.operation}\n[{ref_id}]"
63
+ else:
64
+ label = f"{node.operation}\n{node_id}"
65
+ node_labels[node_id] = label
66
+
67
+ # Color and size based on status and type
68
+ if node.id in builder._executed:
69
+ node_colors.append("#90EE90") # Light green
70
+ node_sizes.append(4000)
71
+ elif node.metadata.get("expansion_source"):
72
+ node_colors.append("#87CEEB") # Sky blue
73
+ node_sizes.append(3500)
74
+ elif node.metadata.get("aggregation"):
75
+ node_colors.append("#FFD700") # Gold
76
+ node_sizes.append(4500)
77
+ elif node.metadata.get("is_condition_check"):
78
+ node_colors.append("#DDA0DD") # Plum
79
+ node_sizes.append(3500)
80
+ else:
81
+ node_colors.append("#E0E0E0") # Light gray
82
+ node_sizes.append(3000)
83
+
84
+ # Add edges
85
+ edge_colors = []
86
+ edge_styles = []
87
+ edge_widths = []
88
+ edge_labels = {}
89
+
90
+ for edge in graph.internal_edges.values():
91
+ head_id = str(edge.head)[:8]
92
+ tail_id = str(edge.tail)[:8]
93
+ G.add_edge(head_id, tail_id)
94
+
95
+ # Style edges based on type
96
+ edge_label = edge.label[0] if edge.label else ""
97
+ edge_labels[(head_id, tail_id)] = edge_label
98
+
99
+ if "expansion" in edge_label:
100
+ edge_colors.append("#4169E1") # Royal blue
101
+ edge_styles.append("dashed")
102
+ edge_widths.append(2)
103
+ elif "aggregate" in edge_label:
104
+ edge_colors.append("#FF6347") # Tomato
105
+ edge_styles.append("dotted")
106
+ edge_widths.append(2.5)
107
+ else:
108
+ edge_colors.append("#808080") # Gray
109
+ edge_styles.append("solid")
110
+ edge_widths.append(1.5)
111
+
112
+ # Create improved hierarchical layout
113
+ pos = {}
114
+ nodes_by_level = {}
115
+
116
+ for node_id, level in node_levels.items():
117
+ if level not in nodes_by_level:
118
+ nodes_by_level[level] = []
119
+ nodes_by_level[level].append(node_id)
120
+
121
+ # Position nodes with better spacing algorithm
122
+ y_spacing = 2.5
123
+ max_width = 16 # Maximum horizontal spread
124
+
125
+ for level, nodes in nodes_by_level.items():
126
+ num_nodes = len(nodes)
127
+
128
+ if num_nodes <= 6:
129
+ # Normal spacing for small levels
130
+ x_spacing = 2.5
131
+ x_offset = -(num_nodes - 1) * x_spacing / 2
132
+ for i, node_id in enumerate(nodes):
133
+ pos[node_id] = (x_offset + i * x_spacing, -level * y_spacing)
134
+ else:
135
+ # Multi-row layout for large levels
136
+ nodes_per_row = min(6, int(np.ceil(np.sqrt(num_nodes * 1.5))))
137
+ rows = int(np.ceil(num_nodes / nodes_per_row))
138
+
139
+ for i, node_id in enumerate(nodes):
140
+ row = i // nodes_per_row
141
+ col = i % nodes_per_row
142
+
143
+ # Calculate row width
144
+ nodes_in_row = min(
145
+ nodes_per_row, num_nodes - row * nodes_per_row
146
+ )
147
+ x_spacing = 2.5
148
+ x_offset = -(nodes_in_row - 1) * x_spacing / 2
149
+
150
+ # Add slight y offset for different rows
151
+ y_offset = row * 0.8
152
+
153
+ pos[node_id] = (
154
+ x_offset + col * x_spacing,
155
+ -level * y_spacing - y_offset,
156
+ )
157
+
158
+ # Create figure
159
+ plt.figure(figsize=figsize)
160
+
161
+ # Draw nodes
162
+ nx.draw_networkx_nodes(
163
+ G,
164
+ pos,
165
+ node_color=node_colors,
166
+ node_size=node_sizes,
167
+ alpha=0.9,
168
+ linewidths=2,
169
+ edgecolors="black",
170
+ )
171
+
172
+ # Draw edges with different styles - use curved edges for better visibility
173
+ for i, (u, v) in enumerate(G.edges()):
174
+ # Calculate curve based on node positions
175
+ u_pos = pos[u]
176
+ v_pos = pos[v]
177
+
178
+ # Determine connection style based on relative positions
179
+ if abs(u_pos[0] - v_pos[0]) > 5: # Far apart horizontally
180
+ connectionstyle = "arc3,rad=0.2"
181
+ else:
182
+ connectionstyle = "arc3,rad=0.1"
183
+
184
+ nx.draw_networkx_edges(
185
+ G,
186
+ pos,
187
+ [(u, v)],
188
+ edge_color=[edge_colors[i]],
189
+ style=edge_styles[i],
190
+ width=edge_widths[i],
191
+ alpha=0.7,
192
+ arrows=True,
193
+ arrowsize=20,
194
+ arrowstyle="-|>",
195
+ connectionstyle=connectionstyle,
196
+ )
197
+
198
+ # Draw labels
199
+ nx.draw_networkx_labels(
200
+ G,
201
+ pos,
202
+ node_labels,
203
+ font_size=9,
204
+ font_weight="bold",
205
+ font_family="monospace",
206
+ )
207
+
208
+ # Draw edge labels (only for smaller graphs)
209
+ if len(G.edges()) < 20:
210
+ nx.draw_networkx_edge_labels(
211
+ G,
212
+ pos,
213
+ edge_labels,
214
+ font_size=7,
215
+ font_color="darkblue",
216
+ bbox=dict(
217
+ boxstyle="round,pad=0.3",
218
+ facecolor="white",
219
+ edgecolor="none",
220
+ alpha=0.7,
221
+ ),
222
+ )
223
+
224
+ plt.title(title, fontsize=18, fontweight="bold", pad=20)
225
+ plt.axis("off")
226
+
227
+ # Enhanced legend
228
+ from matplotlib.lines import Line2D
229
+ from matplotlib.patches import Patch, Rectangle
230
+
231
+ legend_elements = [
232
+ Patch(facecolor="#90EE90", edgecolor="black", label="Executed"),
233
+ Patch(facecolor="#87CEEB", edgecolor="black", label="Expanded"),
234
+ Patch(facecolor="#FFD700", edgecolor="black", label="Aggregation"),
235
+ Patch(facecolor="#DDA0DD", edgecolor="black", label="Condition"),
236
+ Patch(facecolor="#E0E0E0", edgecolor="black", label="Pending"),
237
+ Line2D([0], [0], color="#808080", linewidth=2, label="Sequential"),
238
+ Line2D(
239
+ [0],
240
+ [0],
241
+ color="#4169E1",
242
+ linewidth=2,
243
+ linestyle="dashed",
244
+ label="Expansion",
245
+ ),
246
+ Line2D(
247
+ [0],
248
+ [0],
249
+ color="#FF6347",
250
+ linewidth=2,
251
+ linestyle="dotted",
252
+ label="Aggregate",
253
+ ),
254
+ ]
255
+
256
+ plt.legend(
257
+ handles=legend_elements,
258
+ loc="upper left",
259
+ bbox_to_anchor=(0, 1),
260
+ frameon=True,
261
+ fancybox=True,
262
+ shadow=True,
263
+ ncol=2,
264
+ )
265
+
266
+ # Add statistics box
267
+ stats_text = f"Nodes: {len(G.nodes())}\nEdges: {len(G.edges())}\nExecuted: {len(builder._executed)}"
268
+ if nodes_by_level:
269
+ max_level = max(nodes_by_level.keys())
270
+ stats_text += f"\nLevels: {max_level + 1}"
271
+
272
+ plt.text(
273
+ 0.98,
274
+ 0.02,
275
+ stats_text,
276
+ transform=plt.gca().transAxes,
277
+ bbox=dict(boxstyle="round,pad=0.5", facecolor="lightgray", alpha=0.8),
278
+ verticalalignment="bottom",
279
+ horizontalalignment="right",
280
+ fontsize=10,
281
+ fontfamily="monospace",
282
+ )
283
+
284
+ plt.tight_layout()
285
+ plt.show()
@@ -3,7 +3,7 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  import logging
6
- from typing import Any, Literal
6
+ from typing import TYPE_CHECKING, Any, Literal
7
7
 
8
8
  from pydantic import BaseModel
9
9
 
@@ -12,11 +12,13 @@ from lionagi.fields.instruct import (
12
12
  Instruct,
13
13
  InstructResponse,
14
14
  )
15
- from lionagi.ln import alcall
15
+ from lionagi.ln import alcall, to_list
16
16
  from lionagi.protocols.generic.element import ID
17
- from lionagi.session.branch import Branch
18
- from lionagi.session.session import Session
19
- from lionagi.utils import to_list
17
+
18
+ if TYPE_CHECKING:
19
+ from lionagi.session.branch import Branch
20
+ from lionagi.session.session import Session
21
+
20
22
 
21
23
  from ..utils import prepare_instruct, prepare_session
22
24
  from .prompt import PROMPT
@@ -58,8 +60,8 @@ def chunked(iterable, n):
58
60
 
59
61
  async def run_instruct(
60
62
  ins: Instruct,
61
- session: Session,
62
- branch: Branch,
63
+ session: "Session",
64
+ branch: "Branch",
63
65
  auto_run: bool,
64
66
  verbose: bool = True,
65
67
  **kwargs: Any,
@@ -113,8 +115,8 @@ async def run_instruct(
113
115
  async def brainstorm(
114
116
  instruct: Instruct | dict[str, Any],
115
117
  num_instruct: int = 2,
116
- session: Session | None = None,
117
- branch: Branch | ID.Ref | None = None,
118
+ session: "Session" = None,
119
+ branch: ID["Branch"].Ref | None = None,
118
120
  auto_run: bool = True,
119
121
  auto_explore: bool = False,
120
122
  explore_kwargs: dict[str, Any] | None = None,
@@ -156,8 +158,8 @@ async def brainstorm(
156
158
  async def brainstormStream(
157
159
  instruct: Instruct | dict[str, Any],
158
160
  num_instruct: int = 2,
159
- session: Session | None = None,
160
- branch: Branch | ID.Ref | None = None,
161
+ session: "Session" = None,
162
+ branch: ID["Branch"].Ref | None = None,
161
163
  auto_run: bool = True,
162
164
  auto_explore: bool = False,
163
165
  explore_kwargs: dict[str, Any] | None = None,
@@ -377,7 +379,7 @@ async def brainstormStream(
377
379
  all_responses = []
378
380
 
379
381
  async def explore_concurrent_chunk(
380
- sub_instructs: list[Instruct], base_branch: Branch
382
+ sub_instructs: list[Instruct], base_branch: "Branch"
381
383
  ):
382
384
  """
383
385
  Explore instructions in a single chunk concurrently.