lionagi 0.7.8__tar.gz → 0.8.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 (253) hide show
  1. {lionagi-0.7.8 → lionagi-0.8.0}/PKG-INFO +1 -1
  2. lionagi-0.8.0/docs/modules/form.rst +329 -0
  3. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/manager.py +1 -1
  4. lionagi-0.8.0/lionagi/operatives/forms/base.py +80 -0
  5. lionagi-0.8.0/lionagi/operatives/forms/flow.py +74 -0
  6. lionagi-0.8.0/lionagi/operatives/forms/form.py +82 -0
  7. lionagi-0.8.0/lionagi/operatives/forms/report.py +45 -0
  8. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/types.py +3 -0
  9. lionagi-0.8.0/lionagi/version.py +1 -0
  10. {lionagi-0.7.8 → lionagi-0.8.0}/pyproject.toml +1 -1
  11. lionagi-0.7.8/docs/modules/form.rst +0 -193
  12. lionagi-0.7.8/lionagi/operatives/forms/base.py +0 -237
  13. lionagi-0.7.8/lionagi/operatives/forms/form.py +0 -786
  14. lionagi-0.7.8/lionagi/operatives/forms/report.py +0 -323
  15. lionagi-0.7.8/lionagi/operatives/forms/utils.py +0 -26
  16. lionagi-0.7.8/lionagi/version.py +0 -1
  17. {lionagi-0.7.8 → lionagi-0.8.0}/.env.example +0 -0
  18. {lionagi-0.7.8 → lionagi-0.8.0}/.github/FUNDING.yml +0 -0
  19. {lionagi-0.7.8 → lionagi-0.8.0}/.github/dependabot.yml +0 -0
  20. {lionagi-0.7.8 → lionagi-0.8.0}/.github/workflows/ci.yml +0 -0
  21. {lionagi-0.7.8 → lionagi-0.8.0}/.github/workflows/codeql.yml +0 -0
  22. {lionagi-0.7.8 → lionagi-0.8.0}/.github/workflows/docs.yml +0 -0
  23. {lionagi-0.7.8 → lionagi-0.8.0}/.github/workflows/release.yml +0 -0
  24. {lionagi-0.7.8 → lionagi-0.8.0}/.gitignore +0 -0
  25. {lionagi-0.7.8 → lionagi-0.8.0}/.pre-commit-config.yaml +0 -0
  26. {lionagi-0.7.8 → lionagi-0.8.0}/CODE_OF_CONDUCT.md +0 -0
  27. {lionagi-0.7.8 → lionagi-0.8.0}/CONTRIBUTING.md +0 -0
  28. {lionagi-0.7.8 → lionagi-0.8.0}/LICENSE +0 -0
  29. {lionagi-0.7.8 → lionagi-0.8.0}/README.md +0 -0
  30. {lionagi-0.7.8 → lionagi-0.8.0}/cookbooks/ch01_get_started.md +0 -0
  31. {lionagi-0.7.8 → lionagi-0.8.0}/cookbooks/ch02_concepts.md +0 -0
  32. {lionagi-0.7.8 → lionagi-0.8.0}/dev_tools/count_code_base_lines.py +0 -0
  33. {lionagi-0.7.8 → lionagi-0.8.0}/docs/Makefile +0 -0
  34. {lionagi-0.7.8 → lionagi-0.8.0}/docs/_static/custom.css +0 -0
  35. {lionagi-0.7.8 → lionagi-0.8.0}/docs/_templates/layout.html +0 -0
  36. {lionagi-0.7.8 → lionagi-0.8.0}/docs/conf.py +0 -0
  37. {lionagi-0.7.8 → lionagi-0.8.0}/docs/index.rst +0 -0
  38. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/action.rst +0 -0
  39. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/adapter.rst +0 -0
  40. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/branch.rst +0 -0
  41. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/branch_operations.rst +0 -0
  42. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/concepts.rst +0 -0
  43. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/element_id.rst +0 -0
  44. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/event.rst +0 -0
  45. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/graph.rst +0 -0
  46. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/index.rst +0 -0
  47. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/instruct.rst +0 -0
  48. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/lib_file.rst +0 -0
  49. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/lib_nested.rst +0 -0
  50. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/lib_package.rst +0 -0
  51. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/lib_schema.rst +0 -0
  52. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/lib_validate.rst +0 -0
  53. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/log.rst +0 -0
  54. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/mail.rst +0 -0
  55. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/message.rst +0 -0
  56. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/models.rst +0 -0
  57. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/operative_step.rst +0 -0
  58. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/pile.rst +0 -0
  59. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/processor.rst +0 -0
  60. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/progression.rst +0 -0
  61. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/service.rst +0 -0
  62. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/session.rst +0 -0
  63. {lionagi-0.7.8 → lionagi-0.8.0}/docs/modules/utils.rst +0 -0
  64. {lionagi-0.7.8 → lionagi-0.8.0}/docs/tutorials/get_started.rst +0 -0
  65. {lionagi-0.7.8 → lionagi-0.8.0}/docs/tutorials/get_started_pt2.rst +0 -0
  66. {lionagi-0.7.8 → lionagi-0.8.0}/docs/tutorials/get_started_pt3.rst +0 -0
  67. {lionagi-0.7.8 → lionagi-0.8.0}/docs/tutorials/index.rst +0 -0
  68. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/__init__.py +0 -0
  69. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/_class_registry.py +0 -0
  70. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/_errors.py +0 -0
  71. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/_types.py +0 -0
  72. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/__init__.py +0 -0
  73. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/file/__init__.py +0 -0
  74. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/file/chunk.py +0 -0
  75. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/file/file_ops.py +0 -0
  76. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/file/params.py +0 -0
  77. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/file/process.py +0 -0
  78. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/file/save.py +0 -0
  79. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/__init__.py +0 -0
  80. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/flatten.py +0 -0
  81. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/nfilter.py +0 -0
  82. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/nget.py +0 -0
  83. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/ninsert.py +0 -0
  84. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/nmerge.py +0 -0
  85. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/npop.py +0 -0
  86. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/nset.py +0 -0
  87. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/unflatten.py +0 -0
  88. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/nested/utils.py +0 -0
  89. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/package/__init__.py +0 -0
  90. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/package/imports.py +0 -0
  91. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/package/management.py +0 -0
  92. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/package/params.py +0 -0
  93. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/package/system.py +0 -0
  94. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/parse.py +0 -0
  95. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/schema/__init__.py +0 -0
  96. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/schema/as_readable.py +0 -0
  97. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/schema/extract_code_block.py +0 -0
  98. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/schema/extract_docstring.py +0 -0
  99. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/schema/function_to_schema.py +0 -0
  100. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/schema/json_schema.py +0 -0
  101. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/token_transform/__init__.py +0 -0
  102. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/token_transform/llmlingua.py +0 -0
  103. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/token_transform/perplexity.py +0 -0
  104. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/token_transform/synthlang.py +0 -0
  105. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/validate/__init__.py +0 -0
  106. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/validate/common_field_validators.py +0 -0
  107. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/validate/fuzzy_match_keys.py +0 -0
  108. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/validate/fuzzy_validate_mapping.py +0 -0
  109. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/validate/string_similarity.py +0 -0
  110. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/libs/validate/validate_boolean.py +0 -0
  111. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/ReAct/ReAct.py +0 -0
  112. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/ReAct/__init__.py +0 -0
  113. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/ReAct/utils.py +0 -0
  114. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/__init__.py +0 -0
  115. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/_act/__init__.py +0 -0
  116. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/_act/act.py +0 -0
  117. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/brainstorm/__init__.py +0 -0
  118. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/brainstorm/brainstorm.py +0 -0
  119. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/brainstorm/prompt.py +0 -0
  120. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/chat/__init__.py +0 -0
  121. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/chat/chat.py +0 -0
  122. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/communicate/__init__.py +0 -0
  123. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/communicate/communicate.py +0 -0
  124. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/instruct/__init__.py +0 -0
  125. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/instruct/instruct.py +0 -0
  126. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/interpret/__init__.py +0 -0
  127. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/interpret/interpret.py +0 -0
  128. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/operate/__init__.py +0 -0
  129. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/operate/operate.py +0 -0
  130. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/parse/__init__.py +0 -0
  131. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/parse/parse.py +0 -0
  132. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/plan/__init__.py +0 -0
  133. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/plan/plan.py +0 -0
  134. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/plan/prompt.py +0 -0
  135. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/select/__init__.py +0 -0
  136. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/select/select.py +0 -0
  137. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/select/utils.py +0 -0
  138. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/translate/__init__.py +0 -0
  139. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/translate/translate.py +0 -0
  140. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/types.py +0 -0
  141. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operations/utils.py +0 -0
  142. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/__init__.py +0 -0
  143. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/action/__init__.py +0 -0
  144. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/action/function_calling.py +0 -0
  145. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/action/manager.py +0 -0
  146. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/action/request_response_model.py +0 -0
  147. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/action/tool.py +0 -0
  148. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/action/utils.py +0 -0
  149. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/forms/__init__.py +0 -0
  150. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/__init__.py +0 -0
  151. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/base.py +0 -0
  152. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/instruct.py +0 -0
  153. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/instruct_collection.py +0 -0
  154. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/node.py +0 -0
  155. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/prompts.py +0 -0
  156. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/instruct/reason.py +0 -0
  157. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/manager.py +0 -0
  158. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/models/__init__.py +0 -0
  159. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/models/field_model.py +0 -0
  160. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/models/model_params.py +0 -0
  161. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/models/note.py +0 -0
  162. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/models/operable_model.py +0 -0
  163. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/models/schema_model.py +0 -0
  164. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/operative.py +0 -0
  165. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/step.py +0 -0
  166. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/__init__.py +0 -0
  167. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/base.py +0 -0
  168. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/concurrent.py +0 -0
  169. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/concurrent_chunk.py +0 -0
  170. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/concurrent_sequential_chunk.py +0 -0
  171. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/params.py +0 -0
  172. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/sequential.py +0 -0
  173. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/sequential_chunk.py +0 -0
  174. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/sequential_concurrent_chunk.py +0 -0
  175. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/operatives/strategies/utils.py +0 -0
  176. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/__init__.py +0 -0
  177. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/_concepts.py +0 -0
  178. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/__init__.py +0 -0
  179. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/adapter.py +0 -0
  180. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/json_adapter.py +0 -0
  181. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/pandas_/__init__.py +0 -0
  182. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/pandas_/csv_adapter.py +0 -0
  183. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/pandas_/excel_adapter.py +0 -0
  184. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/pandas_/pd_dataframe_adapter.py +0 -0
  185. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/pandas_/pd_series_adapter.py +0 -0
  186. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/adapters/types.py +0 -0
  187. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/__init__.py +0 -0
  188. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/element.py +0 -0
  189. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/event.py +0 -0
  190. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/log.py +0 -0
  191. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/pile.py +0 -0
  192. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/processor.py +0 -0
  193. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/generic/progression.py +0 -0
  194. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/graph/__init__.py +0 -0
  195. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/graph/edge.py +0 -0
  196. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/graph/graph.py +0 -0
  197. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/graph/node.py +0 -0
  198. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/mail/__init__.py +0 -0
  199. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/mail/exchange.py +0 -0
  200. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/mail/mail.py +0 -0
  201. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/mail/mailbox.py +0 -0
  202. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/mail/manager.py +0 -0
  203. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/mail/package.py +0 -0
  204. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/__init__.py +0 -0
  205. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/action_request.py +0 -0
  206. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/action_response.py +0 -0
  207. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/assistant_response.py +0 -0
  208. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/base.py +0 -0
  209. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/instruction.py +0 -0
  210. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/manager.py +0 -0
  211. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/message.py +0 -0
  212. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/system.py +0 -0
  213. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/README.md +0 -0
  214. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
  215. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
  216. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
  217. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
  218. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
  219. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
  220. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/protocols/types.py +0 -0
  221. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/__init__.py +0 -0
  222. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/endpoints/__init__.py +0 -0
  223. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/endpoints/base.py +0 -0
  224. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/endpoints/chat_completion.py +0 -0
  225. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/endpoints/match_endpoint.py +0 -0
  226. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/endpoints/rate_limited_processor.py +0 -0
  227. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/endpoints/token_calculator.py +0 -0
  228. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/imodel.py +0 -0
  229. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/manager.py +0 -0
  230. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/__init__.py +0 -0
  231. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/anthropic_/__init__.py +0 -0
  232. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/anthropic_/messages.py +0 -0
  233. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/exa_/__init__.py +0 -0
  234. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/exa_/models.py +0 -0
  235. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/exa_/search.py +0 -0
  236. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/exa_/types.py +0 -0
  237. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/groq_/__init__.py +0 -0
  238. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/groq_/chat_completions.py +0 -0
  239. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/openai_/__init__.py +0 -0
  240. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/openai_/chat_completions.py +0 -0
  241. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/openrouter_/__init__.py +0 -0
  242. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/openrouter_/chat_completions.py +0 -0
  243. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/perplexity_/__init__.py +0 -0
  244. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/perplexity_/chat_completions.py +0 -0
  245. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/providers/types.py +0 -0
  246. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/service/types.py +0 -0
  247. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/session/__init__.py +0 -0
  248. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/session/branch.py +0 -0
  249. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/session/session.py +0 -0
  250. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/settings.py +0 -0
  251. {lionagi-0.7.8 → lionagi-0.8.0}/lionagi/utils.py +0 -0
  252. {lionagi-0.7.8 → lionagi-0.8.0}/prompts/doc_style.md +0 -0
  253. {lionagi-0.7.8 → lionagi-0.8.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.7.8
3
+ Version: 0.8.0
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -0,0 +1,329 @@
1
+ ======================================
2
+ Form & Flow
3
+ ======================================
4
+
5
+ The forms module provides a flexible system for handling structured data transformations
6
+ through forms and multi-step flows. It consists of four core components:
7
+
8
+ 1. :class:`BaseForm` - Foundation for form handling
9
+ 2. :class:`Form` - Enhanced form with input/output field distinction
10
+ 3. :class:`FlowDefinition` - Multi-step transformation pipeline
11
+ 4. :class:`Report` - Aggregator for completed forms
12
+
13
+ -----------
14
+ Base Form
15
+ -----------
16
+
17
+ .. module:: lionagi.operatives.forms.base
18
+ :synopsis: Core form functionality.
19
+
20
+ .. class:: BaseForm
21
+
22
+ **Inherits from**: :class:`lionagi.protocols.generic.element.Element`
23
+
24
+ A minimal form class that tracks output fields and validates completeness.
25
+ Uses Pydantic v2 with ``ConfigDict(extra="allow", arbitrary_types_allowed=True)``.
26
+
27
+ **Attributes**:
28
+
29
+ - **assignment** (*str | None*) -- A DSL string describing the transformation
30
+ - **output_fields** (*list[str]*) -- Fields considered mandatory outputs
31
+ - **none_as_valid** (*bool*) -- If True, None is accepted as valid
32
+ - **has_processed** (*bool*) -- Marks if form is completed
33
+
34
+ **Methods**:
35
+
36
+ .. method:: is_completed() -> bool
37
+
38
+ Check if all required output fields are set and valid.
39
+ A field is considered valid if:
40
+
41
+ - It exists and has a value
42
+ - The value is not UNDEFINED
43
+ - If none_as_valid=False, the value is not None
44
+
45
+ .. method:: check_completeness(how: Literal["raise", "return_missing"]) -> list[str]
46
+
47
+ Return missing required fields or raise an exception.
48
+
49
+ Parameters:
50
+ - **how** -- If "raise", raises ValueError for missing fields.
51
+ If "return_missing", returns list of missing field names.
52
+
53
+ .. method:: get_results(valid_only: bool = False) -> dict[str, Any]
54
+
55
+ Return a dict of output fields, optionally filtering invalid values.
56
+
57
+ Parameters:
58
+ - **valid_only** -- If True, omit fields with None/UNDEFINED values
59
+ (depending on none_as_valid setting)
60
+
61
+ **Example**::
62
+
63
+ from lionagi.operatives.forms import BaseForm
64
+
65
+ form = BaseForm(
66
+ output_fields=["result"],
67
+ none_as_valid=False
68
+ )
69
+ form.result = "computation complete"
70
+ assert form.is_completed()
71
+ print(form.get_results()) # {"result": "computation complete"}
72
+
73
+ # With none_as_valid=True
74
+ form = BaseForm(
75
+ output_fields=["optional_result"],
76
+ none_as_valid=True
77
+ )
78
+ form.optional_result = None
79
+ assert form.is_completed() # True, None is valid
80
+
81
+ -----------
82
+ Flow System
83
+ -----------
84
+
85
+ .. module:: lionagi.operatives.forms.flow
86
+ :synopsis: Multi-step flow handling.
87
+
88
+ .. class:: FlowStep
89
+
90
+ **Inherits from**: :class:`pydantic.BaseModel`
91
+
92
+ A single transformation step in a multi-step flow.
93
+ Uses Pydantic v2 with ``ConfigDict(arbitrary_types_allowed=True)``.
94
+
95
+ **Attributes**:
96
+
97
+ - **name** (*str*) -- Step identifier (e.g., "step_1")
98
+ - **inputs** (*list[str]*) -- Required input fields for this step
99
+ - **outputs** (*list[str]*) -- Fields produced by this step
100
+ - **description** (*str | None*) -- Optional step documentation
101
+
102
+ .. class:: FlowDefinition
103
+
104
+ **Inherits from**: :class:`pydantic.BaseModel`
105
+
106
+ Manages a sequence of transformation steps using a DSL.
107
+ Uses Pydantic v2 with ``ConfigDict(arbitrary_types_allowed=True)``.
108
+
109
+ **Attributes**:
110
+
111
+ - **steps** (*List[FlowStep]*) -- Ordered list of transformation steps
112
+
113
+ **Methods**:
114
+
115
+ .. method:: parse_flow_string(flow_str: str)
116
+
117
+ Parse a DSL string like "a,b->c; c->d" into FlowSteps.
118
+ Each step is named sequentially (step_1, step_2, etc.).
119
+ Empty segments and whitespace are handled gracefully.
120
+
121
+ .. method:: get_required_fields() -> set[str]
122
+
123
+ Return fields needed as inputs but not produced by prior steps.
124
+ For example, in "a->b; b,c->d", returns {"a", "c"} since:
125
+
126
+ - "a" is needed by step 1 but not produced earlier
127
+ - "b" is needed by step 2 but produced by step 1
128
+ - "c" is needed by step 2 but not produced earlier
129
+
130
+ .. method:: get_produced_fields() -> set[str]
131
+
132
+ Return all fields produced by any step.
133
+ For example, in "a->b,c; c->d", returns {"b", "c", "d"}.
134
+
135
+ **Example**::
136
+
137
+ from lionagi.operatives.forms import FlowDefinition
138
+
139
+ flow = FlowDefinition()
140
+
141
+ # Parse text processing pipeline
142
+ flow.parse_flow_string(
143
+ "text->tokens; tokens->embeddings; embeddings->clusters"
144
+ )
145
+
146
+ print(flow.get_required_fields()) # {"text"}
147
+ print(flow.get_produced_fields()) # {"tokens", "embeddings", "clusters"}
148
+
149
+ # Steps are named sequentially
150
+ for step in flow.steps:
151
+ print(f"{step.name}: {step.inputs} -> {step.outputs}")
152
+
153
+ ------
154
+ Form
155
+ ------
156
+
157
+ .. module:: lionagi.operatives.forms.form
158
+ :synopsis: Enhanced form with input/output distinction.
159
+
160
+ .. class:: Form
161
+
162
+ **Inherits from**: :class:`BaseForm`
163
+
164
+ A form that distinguishes between input and request (output) fields.
165
+ Uses Pydantic v2 with ``ConfigDict(extra="allow", arbitrary_types_allowed=True)``.
166
+
167
+ **Attributes**:
168
+
169
+ - **flow_definition** (*Optional[FlowDefinition]*) -- For multi-step flows
170
+ - **guidance** (*str | None*) -- Optional processing guidance
171
+ - **task** (*str | None*) -- Task description
172
+
173
+ **Validators**:
174
+
175
+ - **parse_assignment_into_flow**: Creates FlowDefinition for multi-step assignments
176
+ - **compute_output_fields**: Sets output_fields based on assignment or flow
177
+
178
+ **Methods**:
179
+
180
+ .. method:: fill_fields(**kwargs)
181
+
182
+ Update form fields with provided values.
183
+ Useful for partial updates when you don't want to recreate the form.
184
+
185
+ .. method:: to_instructions() -> dict[str, Any]
186
+
187
+ Return a dictionary suitable for LLM consumption, containing:
188
+
189
+ - assignment: The DSL string
190
+ - flow: FlowDefinition as dict (if multi-step)
191
+ - guidance: Optional processing guidance
192
+ - task: Optional task description
193
+ - required_outputs: List of required output fields
194
+
195
+ **Example**::
196
+
197
+ from lionagi.operatives.forms import Form
198
+
199
+ # Single-step form
200
+ form = Form(assignment="user_input->greeting")
201
+ form.fill_fields(user_input="Alice")
202
+
203
+ # Multi-step form with all produced fields as outputs
204
+ form = Form(
205
+ assignment="name,age->profile; profile->recommendation",
206
+ guidance="Generate personalized recommendations",
207
+ task="User profiling"
208
+ )
209
+
210
+ # The flow is automatically parsed
211
+ assert form.flow_definition is not None
212
+ assert len(form.flow_definition.steps) == 2
213
+
214
+ # All produced fields are outputs
215
+ assert set(form.output_fields) == {"profile", "recommendation"}
216
+
217
+ --------
218
+ Report
219
+ --------
220
+
221
+ .. module:: lionagi.operatives.forms.report
222
+ :synopsis: Form aggregation and tracking.
223
+
224
+ .. class:: Report
225
+
226
+ **Inherits from**: :class:`BaseForm`
227
+
228
+ Collects and manages multiple completed forms.
229
+ Uses Pydantic v2 with ``ConfigDict(extra="allow", arbitrary_types_allowed=True)``.
230
+
231
+ **Attributes**:
232
+
233
+ - **default_form_cls** (*type[Form]*) -- Form class to use (defaults to Form)
234
+ - **completed_forms** (*Pile[Form]*) -- Thread-safe collection of completed forms
235
+ - **form_assignments** (*dict[str, str]*) -- Maps form IDs to assignments
236
+
237
+ **Methods**:
238
+
239
+ .. method:: add_completed_form(form: Form, update_report_fields: bool = False)
240
+
241
+ Add a completed form to the report.
242
+
243
+ Parameters:
244
+ - **form** -- A completed Form instance
245
+ - **update_report_fields** -- If True, copy form's output values to report
246
+
247
+ Raises:
248
+ - ValueError if form is incomplete
249
+
250
+ **Example**::
251
+
252
+ from lionagi.operatives.forms import Report, Form
253
+
254
+ report = Report()
255
+
256
+ # Create and complete forms for a multi-step process
257
+ form1 = Form(assignment="query->embeddings")
258
+ form1.fill_fields(
259
+ query="What's the weather?",
260
+ embeddings=[0.1, 0.2, 0.3]
261
+ )
262
+
263
+ form2 = Form(assignment="embeddings->answer")
264
+ form2.fill_fields(
265
+ embeddings=form1.embeddings,
266
+ answer="Sunny with a high of 75°F"
267
+ )
268
+
269
+ # Add both forms, updating report fields from the final form
270
+ report.add_completed_form(form1)
271
+ report.add_completed_form(form2, update_report_fields=True)
272
+
273
+ print(report.answer) # "Sunny with a high of 75°F"
274
+
275
+ --------------------
276
+ Additional Notes
277
+ --------------------
278
+
279
+ **DSL Format**
280
+
281
+ The forms system uses a simple DSL (Domain Specific Language) for describing
282
+ transformations:
283
+
284
+ - Single step: ``input1, input2 -> output``
285
+ - Multiple steps: ``a,b->c; c->d``
286
+ - Spaces are allowed: ``input1, input2 -> output``
287
+
288
+ The DSL is parsed into either:
289
+
290
+ 1. Simple input/output field lists for :class:`Form`
291
+ 2. A full :class:`FlowDefinition` for multi-step processes
292
+
293
+ **Multi-step Flow Behavior**
294
+
295
+ When using multi-step flows:
296
+
297
+ 1. Each step's outputs become available to later steps as inputs
298
+ 2. The form's output_fields include all produced fields by default
299
+ 3. You can override output_fields to select specific outputs
300
+ 4. Required fields are those needed as inputs but not produced by prior steps
301
+
302
+ **Best Practices**
303
+
304
+ 1. Use :class:`BaseForm` when you only need output validation
305
+ 2. Use :class:`Form` when distinguishing inputs from outputs
306
+ 3. Use :class:`FlowDefinition` for complex multi-step transformations
307
+ 4. Use :class:`Report` to track multiple related forms
308
+ 5. Set none_as_valid=True when fields may legitimately be None
309
+ 6. Provide guidance and task descriptions for better LLM interaction
310
+
311
+ **Type Safety**
312
+
313
+ All form classes use Pydantic v2 for validation. You can create typed forms by
314
+ subclassing and adding type hints::
315
+
316
+ from pydantic import Field
317
+ from lionagi.utils import UNDEFINED
318
+
319
+ class UserForm(Form):
320
+ name: str = Field(default=UNDEFINED)
321
+ age: int = Field(default=UNDEFINED)
322
+ profile: str | None = Field(default=None)
323
+
324
+ model_config = ConfigDict(
325
+ extra="allow",
326
+ arbitrary_types_allowed=True
327
+ )
328
+
329
+ This ensures type safety and proper validation for form fields.
@@ -1,4 +1,4 @@
1
- from typing import Callable
1
+ from collections.abc import Callable
2
2
 
3
3
  from lionagi.protocols._concepts import Manager
4
4
 
@@ -0,0 +1,80 @@
1
+ # forms/base_form.py
2
+
3
+ from typing import Any, Literal
4
+
5
+ from pydantic import ConfigDict, Field
6
+ from pydantic_core import PydanticUndefined
7
+
8
+ from lionagi.protocols.generic.element import Element
9
+ from lionagi.utils import UNDEFINED
10
+
11
+
12
+ class BaseForm(Element):
13
+ """
14
+ A minimal base form class to store fields and define output logic.
15
+ Typically, you'll inherit from this for domain-specific forms.
16
+ """
17
+
18
+ model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
19
+
20
+ # A short "assignment" describing input->output
21
+ assignment: str | None = Field(
22
+ default=None,
23
+ description="A small DSL describing transformation, e.g. 'a,b -> c'.",
24
+ )
25
+ # Which fields are produced as 'final' or 'required' outputs.
26
+ output_fields: list[str] = Field(
27
+ default_factory=list,
28
+ description="Which fields are considered mandatory outputs.",
29
+ )
30
+ # Whether None counts as valid or incomplete
31
+ none_as_valid: bool = Field(
32
+ default=False,
33
+ description="If True, None is accepted as a valid value for completion checks.",
34
+ )
35
+ has_processed: bool = Field(
36
+ default=False,
37
+ description="Marks if the form is considered completed or 'processed'.",
38
+ )
39
+
40
+ def is_completed(self) -> bool:
41
+ """Check if all required output fields are set (and not UNDEFINED/None if not allowed)."""
42
+ missing = self.check_completeness()
43
+ return not missing
44
+
45
+ def check_completeness(
46
+ self, how: Literal["raise", "return_missing"] = "return_missing"
47
+ ) -> list[str]:
48
+ """
49
+ Return a list of any 'required' output fields that are missing or invalid.
50
+ If how='raise', raise an exception if missing any.
51
+ """
52
+ invalid_vals = [UNDEFINED, PydanticUndefined]
53
+ if not self.none_as_valid:
54
+ invalid_vals.append(None)
55
+
56
+ missing = []
57
+ for f in self.output_fields:
58
+ val = getattr(self, f, UNDEFINED)
59
+ if val in invalid_vals:
60
+ missing.append(f)
61
+
62
+ if missing and how == "raise":
63
+ raise ValueError(f"Form missing required fields: {missing}")
64
+ return missing
65
+
66
+ def get_results(self, valid_only: bool = False) -> dict[str, Any]:
67
+ """
68
+ Return a dict of all `output_fields`, optionally skipping invalid/None if `valid_only`.
69
+ """
70
+ results = {}
71
+ invalid_vals = [UNDEFINED, PydanticUndefined]
72
+ if not self.none_as_valid:
73
+ invalid_vals.append(None)
74
+
75
+ for f in self.output_fields:
76
+ val = getattr(self, f, UNDEFINED)
77
+ if valid_only and val in invalid_vals:
78
+ continue
79
+ results[f] = val
80
+ return results
@@ -0,0 +1,74 @@
1
+ # forms/flow.py
2
+ from typing import List
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+
7
+ class FlowStep(BaseModel):
8
+ """
9
+ A minimal 'step' describing one transformation from some input fields to some output fields.
10
+ """
11
+
12
+ model_config = ConfigDict(arbitrary_types_allowed=True)
13
+
14
+ name: str = Field(..., description="Identifier for the step.")
15
+ inputs: list[str] = Field(
16
+ ..., description="Which fields are needed for this step."
17
+ )
18
+ outputs: list[str] = Field(
19
+ ..., description="Which fields are produced by this step."
20
+ )
21
+ description: str | None = None # optional text doc
22
+
23
+
24
+ class FlowDefinition(BaseModel):
25
+ """
26
+ A minimal DSL-based multi-step flow, e.g. 'a,b->c; c->d' to yield two steps.
27
+ """
28
+
29
+ model_config = ConfigDict(arbitrary_types_allowed=True)
30
+
31
+ steps: list[FlowStep] = Field(default_factory=list)
32
+
33
+ def parse_flow_string(self, flow_str: str):
34
+ """
35
+ Parse a string like 'a,b->c; c->d' into multiple FlowSteps.
36
+ We'll store them in self.steps in order.
37
+ """
38
+ if not flow_str:
39
+ return
40
+ segments = [seg.strip() for seg in flow_str.split(";") if seg.strip()]
41
+ for i, seg in enumerate(segments):
42
+ # seg might be like 'a,b->c' or 'a->b, c' etc
43
+ if "->" not in seg:
44
+ raise ValueError(f"Invalid DSL segment (no '->'): '{seg}'")
45
+ ins_str, outs_str = seg.split("->", 1)
46
+ inputs = [x.strip() for x in ins_str.split(",") if x.strip()]
47
+ outputs = [y.strip() for y in outs_str.split(",") if y.strip()]
48
+ step = FlowStep(name=f"step_{i+1}", inputs=inputs, outputs=outputs)
49
+ self.steps.append(step)
50
+
51
+ def get_required_fields(self) -> set[str]:
52
+ """
53
+ Return all fields that are used as inputs in the earliest steps but not produced by prior steps.
54
+ This is a minimal approach; or we can do more advanced logic if needed.
55
+ """
56
+ produced = set()
57
+ required = set()
58
+ for step in self.steps:
59
+ # anything not yet produced is needed
60
+ for i in step.inputs:
61
+ if i not in produced:
62
+ required.add(i)
63
+ for o in step.outputs:
64
+ produced.add(o)
65
+ return required
66
+
67
+ def get_produced_fields(self) -> set[str]:
68
+ """
69
+ Return all fields that eventually get produced by any step.
70
+ """
71
+ result = set()
72
+ for st in self.steps:
73
+ result.update(st.outputs)
74
+ return result
@@ -0,0 +1,82 @@
1
+ # forms/form.py
2
+
3
+ from typing import Any, Optional
4
+
5
+ from pydantic import ConfigDict, Field, model_validator
6
+ from typing_extensions import Self
7
+
8
+ from .base import BaseForm
9
+ from .flow import FlowDefinition
10
+
11
+
12
+ class Form(BaseForm):
13
+ """
14
+ A domain form that can handle either a simple 'a,b->c' assignment
15
+ or a multi-step flow if the assignment string has semicolons, etc.
16
+ """
17
+
18
+ model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
19
+
20
+ flow_definition: FlowDefinition | None = None
21
+ # Possibly some extra fields, e.g. "guidance" or "task"
22
+ guidance: str | None = Field(default=None)
23
+ task: str | None = Field(default=None)
24
+
25
+ @model_validator(mode="before")
26
+ def parse_assignment_into_flow(cls, values):
27
+ """
28
+ If the 'assignment' has semicolons, assume multiple steps, parse into FlowDefinition.
29
+ If it's a single step or no semicolons, we remain in 'simple' mode.
30
+ """
31
+ assignment_str = values.get("assignment")
32
+ if assignment_str and ";" in assignment_str:
33
+ flow = FlowDefinition()
34
+ flow.parse_flow_string(assignment_str)
35
+ values["flow_definition"] = flow
36
+ return values
37
+
38
+ @model_validator(mode="after")
39
+ def compute_output_fields(self) -> Self:
40
+ """
41
+ If in simple mode, we parse something like 'a,b->c' and set output_fields=[c].
42
+ If in multi-step mode, we set output_fields to the final produced fields of the flow.
43
+ """
44
+ if self.flow_definition:
45
+ # multi-step
46
+ produced = self.flow_definition.get_produced_fields()
47
+ if not self.output_fields:
48
+ self.output_fields = list(produced)
49
+ else:
50
+ # single-step
51
+ if self.assignment and "->" in self.assignment:
52
+ # parse the single arrow
53
+ ins_outs = self.assignment.split("->", 1)
54
+ outs_str = ins_outs[1]
55
+ outs = [x.strip() for x in outs_str.split(",") if x.strip()]
56
+ if not self.output_fields:
57
+ self.output_fields = outs
58
+ return self
59
+
60
+ def fill_fields(self, **kwargs) -> None:
61
+ """
62
+ A small helper: fill fields in this form by direct assignment.
63
+ Usually you'd do 'myform(field=val, field2=val2)', but sometimes you want partial updates.
64
+ """
65
+ for k, v in kwargs.items():
66
+ setattr(self, k, v)
67
+
68
+ def to_instructions(self) -> dict[str, Any]:
69
+ """
70
+ Return a small dictionary that an LLM can read as an 'instruction context'.
71
+ """
72
+ return {
73
+ "assignment": self.assignment,
74
+ "flow": (
75
+ self.flow_definition.model_dump()
76
+ if self.flow_definition
77
+ else None
78
+ ),
79
+ "guidance": self.guidance,
80
+ "task": self.task,
81
+ "required_outputs": self.output_fields,
82
+ }
@@ -0,0 +1,45 @@
1
+ # forms/report.py
2
+
3
+ from pydantic import Field
4
+
5
+ from lionagi.protocols.generic.pile import Pile
6
+
7
+ from .base import BaseForm
8
+ from .form import Form
9
+
10
+
11
+ class Report(BaseForm):
12
+ """
13
+ A minimal class that collects multiple completed forms as "sub-tasks."
14
+ If you have a single FlowDefinition that describes the entire multi-step pipeline,
15
+ you can track each step as a separate form in here.
16
+ """
17
+
18
+ default_form_cls: type[Form] = Form
19
+ completed_forms: Pile[Form] = Field(
20
+ default_factory=lambda: Pile(item_type={Form}),
21
+ description="A list of forms that have been completed for this report.",
22
+ )
23
+ form_assignments: dict[str, str] = Field(
24
+ default_factory=dict,
25
+ description="Mapping from form ID -> assignment string",
26
+ )
27
+
28
+ def add_completed_form(
29
+ self, form: Form, update_report_fields: bool = False
30
+ ):
31
+ """
32
+ Add a completed form. Optionally update the report’s fields from the form's output.
33
+ """
34
+ missing = form.check_completeness()
35
+ if missing:
36
+ raise ValueError(
37
+ f"Form {form.id} is incomplete: missing {missing}."
38
+ )
39
+ self.completed_forms.append(form)
40
+ self.form_assignments[form.id] = form.assignment or ""
41
+ # optionally update the report’s own fields
42
+ if update_report_fields:
43
+ for f_ in form.output_fields:
44
+ val = getattr(form, f_, None)
45
+ setattr(self, f_, val)
@@ -10,6 +10,7 @@ from .action.request_response_model import (
10
10
  )
11
11
  from .action.tool import FuncTool, FuncToolRef, Tool, ToolRef
12
12
  from .forms.base import BaseForm
13
+ from .forms.flow import FlowDefinition, FlowStep
13
14
  from .forms.form import Form
14
15
  from .forms.report import Report
15
16
  from .instruct.base import (
@@ -66,4 +67,6 @@ __all__ = (
66
67
  "FuncTool",
67
68
  "FuncToolRef",
68
69
  "FunctionCalling",
70
+ "FlowDefinition",
71
+ "FlowStep",
69
72
  )
@@ -0,0 +1 @@
1
+ __version__ = "0.8.0"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lionagi"
3
- version = "0.7.8"
3
+ version = "0.8.0"
4
4
  description = "An Intelligence Operating System."
5
5
  authors = [
6
6
  { name = "HaiyangLi", email = "quantocean.li@gmail.com" },