lionagi 0.2.1__tar.gz → 0.2.2__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {lionagi-0.2.1 → lionagi-0.2.2}/PKG-INFO +5 -4
- {lionagi-0.2.1 → lionagi-0.2.2}/README.md +4 -3
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/__init__.py +2 -1
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/graph.py +10 -3
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/node.py +5 -1
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/report/base.py +1 -0
- lionagi-0.2.2/lionagi/core/work/work_edge.py +96 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/work/work_function.py +29 -6
- lionagi-0.2.2/lionagi/core/work/work_function_node.py +44 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/work/work_queue.py +20 -18
- lionagi-0.2.2/lionagi/core/work/work_task.py +155 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/work/worker.py +164 -39
- lionagi-0.2.2/lionagi/core/work/worker_engine.py +179 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/work/worklog.py +5 -3
- lionagi-0.2.2/lionagi/tests/test_core/generic/test_structure.py +193 -0
- lionagi-0.2.2/lionagi/tests/test_core/graph/__init__.py +0 -0
- lionagi-0.2.2/lionagi/tests/test_core/graph/test_graph.py +70 -0
- lionagi-0.2.2/lionagi/tests/test_core/graph/test_tree.py +75 -0
- lionagi-0.2.2/lionagi/tests/test_core/mail/__init__.py +0 -0
- lionagi-0.2.2/lionagi/tests/test_core/mail/test_mail.py +62 -0
- lionagi-0.2.2/lionagi/tests/test_core/test_structure/__init__.py +0 -0
- lionagi-0.2.2/lionagi/tests/test_core/test_structure/test_base_structure.py +196 -0
- lionagi-0.2.2/lionagi/tests/test_core/test_structure/test_graph.py +54 -0
- lionagi-0.2.2/lionagi/tests/test_core/test_structure/test_tree.py +48 -0
- lionagi-0.2.2/lionagi/version.py +1 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi.egg-info/PKG-INFO +5 -4
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi.egg-info/SOURCES.txt +15 -1
- lionagi-0.2.1/lionagi/version.py +0 -1
- {lionagi-0.2.1 → lionagi-0.2.2}/LICENSE +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/README.rst +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/_setting/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/_setting/_setting.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/action/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/action/function_calling.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/action/manual.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/action/node.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/action/tool.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/action/tool_manager.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/base_agent.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/eval/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/eval/evaluator.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/eval/vote.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/learn/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/learn/learner.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/plan/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/plan/plan.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/agent/plan/unit_template.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/_logger.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/abc/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/abc/component.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/abc/concepts.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/abc/exceptions.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/abc/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/exchange.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/flow.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/model.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/pile.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/progression.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/collections/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/director/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/director/direct.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/director/director.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/engine/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/engine/branch_engine.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/engine/instruction_map_engine.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/engine/sandbox_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/engine/script_engine.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/executor/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/executor/base_executor.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/executor/graph_executor.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/executor/neo4j_executor.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/edge.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/edge_condition.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/hyperedge.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/tree.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/generic/tree_node.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/mail/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/mail/mail.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/mail/mail_manager.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/mail/package.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/mail/start_mail.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/action_request.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/action_response.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/assistant_response.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/instruction.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/message.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/system.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/message/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/report/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/report/form.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/report/report.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/report/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/_default.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/action.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/base.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/boolean.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/choice.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/mapping.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/number.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/rulebook.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/string.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/rule/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/session/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/session/branch.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/session/directive_mixin.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/session/session.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/structure/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/structure/chain.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/structure/forest.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/structure/graph.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/structure/tree.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/parallel_unit.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/action.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/base.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/plan.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/predict.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/score.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/template/select.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/unit.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/unit_form.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/unit_mixin.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/unit/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/validator/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/validator/validator.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/work/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/core/work/work.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/compressor/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/compressor/base.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/compressor/llm_compressor.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/compressor/llm_summarizer.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/compressor/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/parser/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/parser/base_parser.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/template/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/template/base_template.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/template/schema.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/directive/tokenizer.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/evaluator/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/evaluator/ast_evaluator.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/evaluator/base_evaluator.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/knowledge/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/knowledge/base.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/knowledge/graph.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/memory/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/strategies/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/experimental/strategies/base.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/autogen_/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/autogen_/autogen_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/langchain_/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/langchain_/documents.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/langchain_/langchain_bridge.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/index.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/llama_pack.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/node_parser.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/reader.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/llamaindex_/textnode.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/pydantic_/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/pydantic_/pydantic_bridge.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/transformers_/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/bridge/transformers_/install_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/chunker/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/chunker/chunk.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/config/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/config/mlx_configs.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/config/oai_configs.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/config/ollama_configs.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/config/openrouter_configs.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/loader/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/loader/load.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/loader/load_util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/_mapping.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/litellm.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/mistralai.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/mlx_service.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/oai.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/ollama.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/openrouter.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/services.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/provider/transformers.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/storage/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/storage/neo4j.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/storage/storage_util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/storage/structure_excel.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/storage/to_csv.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/integrations/storage/to_excel.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_api.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_async.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_context.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_convert.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_dataframe.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_func_call.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_image.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_knowledge_graph.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_nested.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_parse.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_queue.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_tokenize.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/ln_validate.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/special_tokens.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/libs/sys_util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/coder/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/coder/add_feature.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/coder/base_prompts.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/coder/code_form.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/coder/coder.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/coder/util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/researcher/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/researcher/data_source/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/researcher/data_source/finhub_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/researcher/data_source/google_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/researcher/data_source/wiki_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/lions/researcher/data_source/yfinance_.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/integrations/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_api.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_convert.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_field_validators.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_func_call.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_nested.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_parse.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_queue.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/libs/test_sys_util.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/collections/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/collections/test_component.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/collections/test_exchange.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/collections/test_flow.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/collections/test_pile.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/collections/test_progression.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/generic/__init__.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/generic/test_edge.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/generic/test_graph.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/generic/test_node.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/generic/test_tree_node.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/test_branch.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/test_form.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/test_report.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi/tests/test_core/test_validator.py +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi.egg-info/dependency_links.txt +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi.egg-info/requires.txt +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/lionagi.egg-info/top_level.txt +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/pyproject.toml +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/setup.cfg +0 -0
- {lionagi-0.2.1 → lionagi-0.2.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lionagi
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.2
|
4
4
|
Summary: Towards automated general intelligence.
|
5
5
|
Author: HaiyangLi
|
6
6
|
Author-email: Haiyang Li <ocean@lionagi.ai>
|
@@ -226,13 +226,14 @@ Requires-Dist: pandas>=2.1.0
|
|
226
226
|
![PyPI - Version](https://img.shields.io/pypi/v/lionagi?labelColor=233476aa&color=231fc935) ![PyPI - Downloads](https://img.shields.io/pypi/dm/lionagi?color=blue)
|
227
227
|
|
228
228
|
|
229
|
-
[PyPI](https://pypi.org/project/lionagi/) | [Documentation](https://ocean-lion.com/Welcome) | [Discord](https://discord.gg/
|
229
|
+
[PyPI](https://pypi.org/project/lionagi/) | [Documentation](https://ocean-lion.com/Welcome) | [Discord](https://discord.gg/aqSJ2v46vu) | [Roadmap](https://trello.com/b/3seomsrI/lionagi)
|
230
230
|
|
231
231
|
|
232
232
|
# Language InterOperable Network - LION
|
233
|
+
### An AGentic Intelligence Operating System
|
233
234
|
|
234
235
|
```
|
235
|
-
|
236
|
+
pip install lionagi==0.2.2
|
236
237
|
```
|
237
238
|
|
238
239
|
**Powerful Intelligent Workflow Automation**
|
@@ -250,7 +251,7 @@ What goes inside of a LLM is more akin to a [black-box](https://pauldeepakraj-r.
|
|
250
251
|
|
251
252
|
### Community
|
252
253
|
|
253
|
-
We encourage contributions to LionAGI and invite you to enrich its features and capabilities. Engage with us and other community members [Join Our Discord](https://discord.gg/
|
254
|
+
We encourage contributions to LionAGI and invite you to enrich its features and capabilities. Engage with us and other community members [Join Our Discord](https://discord.gg/aqSJ2v46vu)
|
254
255
|
|
255
256
|
### Citation
|
256
257
|
|
@@ -1,13 +1,14 @@
|
|
1
1
|
![PyPI - Version](https://img.shields.io/pypi/v/lionagi?labelColor=233476aa&color=231fc935) ![PyPI - Downloads](https://img.shields.io/pypi/dm/lionagi?color=blue)
|
2
2
|
|
3
3
|
|
4
|
-
[PyPI](https://pypi.org/project/lionagi/) | [Documentation](https://ocean-lion.com/Welcome) | [Discord](https://discord.gg/
|
4
|
+
[PyPI](https://pypi.org/project/lionagi/) | [Documentation](https://ocean-lion.com/Welcome) | [Discord](https://discord.gg/aqSJ2v46vu) | [Roadmap](https://trello.com/b/3seomsrI/lionagi)
|
5
5
|
|
6
6
|
|
7
7
|
# Language InterOperable Network - LION
|
8
|
+
### An AGentic Intelligence Operating System
|
8
9
|
|
9
10
|
```
|
10
|
-
|
11
|
+
pip install lionagi==0.2.2
|
11
12
|
```
|
12
13
|
|
13
14
|
**Powerful Intelligent Workflow Automation**
|
@@ -25,7 +26,7 @@ What goes inside of a LLM is more akin to a [black-box](https://pauldeepakraj-r.
|
|
25
26
|
|
26
27
|
### Community
|
27
28
|
|
28
|
-
We encourage contributions to LionAGI and invite you to enrich its features and capabilities. Engage with us and other community members [Join Our Discord](https://discord.gg/
|
29
|
+
We encourage contributions to LionAGI and invite you to enrich its features and capabilities. Engage with us and other community members [Join Our Discord](https://discord.gg/aqSJ2v46vu)
|
29
30
|
|
30
31
|
### Citation
|
31
32
|
|
@@ -27,7 +27,7 @@ from lionagi.core.action import func_to_tool
|
|
27
27
|
from lionagi.core.report import Form, Report
|
28
28
|
from lionagi.core.session.branch import Branch
|
29
29
|
from lionagi.core.session.session import Session
|
30
|
-
from lionagi.core.work.worker import work, Worker
|
30
|
+
from lionagi.core.work.worker import work, Worker, worklink
|
31
31
|
from lionagi.integrations.provider.services import Services
|
32
32
|
from lionagi.integrations.chunker.chunk import chunk
|
33
33
|
from lionagi.integrations.loader.load import load
|
@@ -41,6 +41,7 @@ __all__ = [
|
|
41
41
|
"pile",
|
42
42
|
"iModel",
|
43
43
|
"work",
|
44
|
+
"worklink",
|
44
45
|
"Worker",
|
45
46
|
"Branch",
|
46
47
|
"Session",
|
@@ -44,6 +44,7 @@ class Graph(Node):
|
|
44
44
|
condition: Condition | None = None,
|
45
45
|
bundle=False,
|
46
46
|
label=None,
|
47
|
+
edge_class=Edge,
|
47
48
|
**kwargs,
|
48
49
|
):
|
49
50
|
"""Add an edge between two nodes in the graph."""
|
@@ -61,6 +62,7 @@ class Graph(Node):
|
|
61
62
|
condition=condition,
|
62
63
|
label=label,
|
63
64
|
bundle=bundle,
|
65
|
+
edge_class=edge_class,
|
64
66
|
**kwargs,
|
65
67
|
)
|
66
68
|
|
@@ -184,19 +186,23 @@ class Graph(Node):
|
|
184
186
|
node_info = node.to_dict()
|
185
187
|
node_info.pop("ln_id")
|
186
188
|
node_info.update({"class_name": node.class_name})
|
189
|
+
if hasattr(node, "name"):
|
190
|
+
node_info.update({"name": node.name})
|
187
191
|
g.add_node(node.ln_id, **node_info)
|
188
192
|
|
189
193
|
for _edge in self.internal_edges:
|
190
194
|
edge_info = _edge.to_dict()
|
191
195
|
edge_info.pop("ln_id")
|
192
196
|
edge_info.update({"class_name": _edge.class_name})
|
197
|
+
if hasattr(_edge, "name"):
|
198
|
+
edge_info.update({"name": _edge.name})
|
193
199
|
source_node_id = edge_info.pop("head")
|
194
200
|
target_node_id = edge_info.pop("tail")
|
195
201
|
g.add_edge(source_node_id, target_node_id, **edge_info)
|
196
202
|
|
197
203
|
return g
|
198
204
|
|
199
|
-
def display(self, **kwargs):
|
205
|
+
def display(self, node_label="class_name", edge_label="label", draw_kwargs={}, **kwargs):
|
200
206
|
"""Display the graph using NetworkX and Matplotlib."""
|
201
207
|
from lionagi.libs import SysUtil
|
202
208
|
|
@@ -217,10 +223,11 @@ class Graph(Node):
|
|
217
223
|
node_size=500,
|
218
224
|
node_color="orange",
|
219
225
|
alpha=0.9,
|
220
|
-
labels=nx.get_node_attributes(g,
|
226
|
+
labels=nx.get_node_attributes(g, node_label),
|
227
|
+
**draw_kwargs
|
221
228
|
)
|
222
229
|
|
223
|
-
labels = nx.get_edge_attributes(g,
|
230
|
+
labels = nx.get_edge_attributes(g, edge_label)
|
224
231
|
labels = {k: v for k, v in labels.items() if v}
|
225
232
|
|
226
233
|
if labels:
|
@@ -10,6 +10,7 @@ modifying, and removing edges, and querying related nodes and connections.
|
|
10
10
|
|
11
11
|
from pydantic import Field
|
12
12
|
from pandas import Series
|
13
|
+
from typing import Callable
|
13
14
|
|
14
15
|
from lionagi.libs.ln_convert import to_list
|
15
16
|
|
@@ -122,6 +123,8 @@ class Node(Component, Relatable):
|
|
122
123
|
condition: Condition | None = None,
|
123
124
|
label: str | None = None,
|
124
125
|
bundle: bool = False,
|
126
|
+
edge_class: Callable = Edge,
|
127
|
+
**kwargs
|
125
128
|
) -> None:
|
126
129
|
"""
|
127
130
|
Establish directed relationship from this node to another.
|
@@ -141,12 +144,13 @@ class Node(Component, Relatable):
|
|
141
144
|
f"Invalid value for direction: {direction}, " "must be 'in' or 'out'"
|
142
145
|
)
|
143
146
|
|
144
|
-
edge =
|
147
|
+
edge = edge_class(
|
145
148
|
head=self if direction == "out" else node,
|
146
149
|
tail=node if direction == "out" else self,
|
147
150
|
condition=condition,
|
148
151
|
bundle=bundle,
|
149
152
|
label=label,
|
153
|
+
**kwargs
|
150
154
|
)
|
151
155
|
|
152
156
|
self.relations[direction].include(edge)
|
@@ -0,0 +1,96 @@
|
|
1
|
+
from typing import Callable
|
2
|
+
from pydantic import Field, field_validator
|
3
|
+
import inspect
|
4
|
+
|
5
|
+
from lionagi.core.generic.edge import Edge
|
6
|
+
from lionagi.core.collections.abc.concepts import Progressable
|
7
|
+
|
8
|
+
from lionagi.core.work.worker import Worker
|
9
|
+
|
10
|
+
|
11
|
+
class WorkEdge(Edge, Progressable):
|
12
|
+
"""
|
13
|
+
Represents a directed edge between work tasks, responsible for transforming
|
14
|
+
the result of one task into parameters for the next task.
|
15
|
+
|
16
|
+
Attributes:
|
17
|
+
convert_function (Callable): Function to transform the result of the previous
|
18
|
+
work into parameters for the next work. This function must be decorated
|
19
|
+
with the `worklink` decorator.
|
20
|
+
convert_function_kwargs (dict): Additional parameters for the convert_function
|
21
|
+
other than "from_work" and "from_result".
|
22
|
+
associated_worker (Worker): The worker to which this WorkEdge belongs.
|
23
|
+
"""
|
24
|
+
convert_function: Callable = Field(
|
25
|
+
...,
|
26
|
+
description="Function to transform the result of the previous work into parameters for the next work."
|
27
|
+
)
|
28
|
+
|
29
|
+
convert_function_kwargs: dict = Field(
|
30
|
+
{},
|
31
|
+
description="parameters for the worklink function other than \"from_work\" and \"from_result\""
|
32
|
+
)
|
33
|
+
|
34
|
+
associated_worker: Worker = Field(
|
35
|
+
...,
|
36
|
+
description="The worker to which this WorkEdge belongs."
|
37
|
+
)
|
38
|
+
|
39
|
+
@field_validator("convert_function", mode="before")
|
40
|
+
def _validate_convert_funuction(cls, func):
|
41
|
+
"""
|
42
|
+
Validates that the convert_function is decorated with the worklink decorator.
|
43
|
+
|
44
|
+
Args:
|
45
|
+
func (Callable): The function to validate.
|
46
|
+
|
47
|
+
Returns:
|
48
|
+
Callable: The validated function.
|
49
|
+
|
50
|
+
Raises:
|
51
|
+
ValueError: If the function is not decorated with the worklink decorator.
|
52
|
+
"""
|
53
|
+
try:
|
54
|
+
getattr(func, "_worklink_decorator_params")
|
55
|
+
return func
|
56
|
+
except:
|
57
|
+
raise ValueError("convert_function must be a worklink decorated function")
|
58
|
+
|
59
|
+
@property
|
60
|
+
def name(self):
|
61
|
+
"""
|
62
|
+
Returns the name of the convert_function.
|
63
|
+
|
64
|
+
Returns:
|
65
|
+
str: The name of the convert_function.
|
66
|
+
"""
|
67
|
+
return self.convert_function.__name__
|
68
|
+
|
69
|
+
async def forward(self, task):
|
70
|
+
"""
|
71
|
+
Transforms the result of the current work into parameters for the next work
|
72
|
+
and schedules the next work task.
|
73
|
+
|
74
|
+
Args:
|
75
|
+
task (Task): The task to process.
|
76
|
+
|
77
|
+
Returns:
|
78
|
+
Work: The next work task to be executed.
|
79
|
+
|
80
|
+
Raises:
|
81
|
+
StopIteration: If the task has no available steps left to proceed.
|
82
|
+
"""
|
83
|
+
if task.available_steps == 0:
|
84
|
+
task.status_note = ("Task stopped proceeding further as all available steps have been used up, "
|
85
|
+
"but the task has not yet reached completion.")
|
86
|
+
return
|
87
|
+
func_signature = inspect.signature(self.convert_function)
|
88
|
+
kwargs = self.convert_function_kwargs.copy()
|
89
|
+
if "from_work" in func_signature.parameters:
|
90
|
+
kwargs = {"from_work": task.current_work} | kwargs
|
91
|
+
if "from_result" in func_signature.parameters:
|
92
|
+
kwargs = {"from_result": task.current_work.result} | kwargs
|
93
|
+
|
94
|
+
self.convert_function.auto_schedule = True
|
95
|
+
next_work = await self.convert_function(self=self.associated_worker, **kwargs)
|
96
|
+
return next_work
|
@@ -13,14 +13,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
See the License for the specific language governing permissions and
|
14
14
|
limitations under the License.
|
15
15
|
"""
|
16
|
+
import asyncio
|
16
17
|
import logging
|
17
18
|
|
18
19
|
from lionagi.libs.ln_func_call import rcall
|
19
|
-
from lionagi.libs.ln_parse import ParseUtil
|
20
20
|
from lionagi.core.work.worklog import WorkLog
|
21
21
|
|
22
|
-
from lionagi.core.report.form import Form
|
23
|
-
|
24
22
|
|
25
23
|
class WorkFunction:
|
26
24
|
"""
|
@@ -35,7 +33,7 @@ class WorkFunction:
|
|
35
33
|
"""
|
36
34
|
|
37
35
|
def __init__(
|
38
|
-
self, assignment, function, retry_kwargs=None, guidance=None, capacity=10
|
36
|
+
self, assignment, function, retry_kwargs=None, guidance=None, capacity=10, refresh_time=1
|
39
37
|
):
|
40
38
|
"""
|
41
39
|
Initializes a WorkFunction instance.
|
@@ -47,12 +45,15 @@ class WorkFunction:
|
|
47
45
|
Defaults to None.
|
48
46
|
guidance (str, optional): The guidance or documentation for the function.
|
49
47
|
Defaults to None.
|
50
|
-
capacity (int, optional): The capacity of the work
|
48
|
+
capacity (int, optional): The capacity of the work queue batch processing.
|
49
|
+
Defaults to 10.
|
50
|
+
refresh_time (int, optional): The time interval to refresh the work log queue.
|
51
|
+
Defaults to 1.
|
51
52
|
"""
|
52
53
|
self.assignment = assignment
|
53
54
|
self.function = function
|
54
55
|
self.retry_kwargs = retry_kwargs or {}
|
55
|
-
self.worklog = WorkLog(capacity)
|
56
|
+
self.worklog = WorkLog(capacity, refresh_time=refresh_time)
|
56
57
|
self.guidance = guidance or self.function.__doc__
|
57
58
|
|
58
59
|
@property
|
@@ -65,6 +66,16 @@ class WorkFunction:
|
|
65
66
|
"""
|
66
67
|
return self.function.__name__
|
67
68
|
|
69
|
+
@property
|
70
|
+
def execution_mode(self):
|
71
|
+
"""
|
72
|
+
Gets the execution mode of the work function's queue.
|
73
|
+
|
74
|
+
Returns:
|
75
|
+
bool: The execution mode of the work function's queue.
|
76
|
+
"""
|
77
|
+
return self.worklog.queue.execution_mode
|
78
|
+
|
68
79
|
def is_progressable(self):
|
69
80
|
"""
|
70
81
|
Checks if the work function is progressable.
|
@@ -99,3 +110,15 @@ class WorkFunction:
|
|
99
110
|
Process the first capacity_size works in the work queue.
|
100
111
|
"""
|
101
112
|
await self.worklog.queue.process()
|
113
|
+
|
114
|
+
async def execute(self):
|
115
|
+
"""
|
116
|
+
Starts the execution of the work function's queue.
|
117
|
+
"""
|
118
|
+
asyncio.create_task(self.worklog.queue.execute())
|
119
|
+
|
120
|
+
async def stop(self):
|
121
|
+
"""
|
122
|
+
Stops the execution of the work function's queue.
|
123
|
+
"""
|
124
|
+
await self.worklog.stop()
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from pydantic import Field
|
2
|
+
import asyncio
|
3
|
+
|
4
|
+
from lionagi.core.generic.node import Node
|
5
|
+
from lionagi.core.work.work_function import WorkFunction
|
6
|
+
from lionagi.core.collections import Exchange
|
7
|
+
from lionagi.core.mail.mail import Mail
|
8
|
+
|
9
|
+
|
10
|
+
class WorkFunctionNode(WorkFunction, Node):
|
11
|
+
"""
|
12
|
+
A class representing a work function node, combining the functionality
|
13
|
+
of a WorkFunction and a Node.
|
14
|
+
|
15
|
+
Attributes:
|
16
|
+
assignment (str): The assignment description of the work function.
|
17
|
+
function (Callable): The function to be performed.
|
18
|
+
retry_kwargs (dict): The retry arguments for the function.
|
19
|
+
guidance (str): The guidance or documentation for the function.
|
20
|
+
capacity (int): The capacity of the work queue batch processing.
|
21
|
+
refresh_time (int): The time interval to refresh the work log queue.
|
22
|
+
"""
|
23
|
+
|
24
|
+
def __init__(self, assignment, function, retry_kwargs=None, guidance=None, capacity=10, refresh_time=1, **kwargs):
|
25
|
+
"""
|
26
|
+
Initializes a WorkFunctionNode instance.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
assignment (str): The assignment description of the work function.
|
30
|
+
function (Callable): The function to be performed.
|
31
|
+
retry_kwargs (dict, optional): The retry arguments for the function. Defaults to None.
|
32
|
+
guidance (str, optional): The guidance or documentation for the function. Defaults to None.
|
33
|
+
capacity (int, optional): The capacity of the work queue batch processing. Defaults to 10.
|
34
|
+
refresh_time (int, optional): The time interval to refresh the work log queue. Defaults to 1.
|
35
|
+
**kwargs: Additional keyword arguments for the Node initialization.
|
36
|
+
"""
|
37
|
+
Node.__init__(self, **kwargs)
|
38
|
+
WorkFunction.__init__(self,
|
39
|
+
assignment=assignment,
|
40
|
+
function=function,
|
41
|
+
retry_kwargs=retry_kwargs,
|
42
|
+
guidance=guidance,
|
43
|
+
capacity=capacity,
|
44
|
+
refresh_time=refresh_time)
|
@@ -25,19 +25,33 @@ class WorkQueue:
|
|
25
25
|
Attributes:
|
26
26
|
capacity (int): The maximum number of tasks the queue can handle.
|
27
27
|
queue (asyncio.Queue): The queue holding the tasks.
|
28
|
-
_stop_event (asyncio.Event): Event to signal stopping
|
28
|
+
_stop_event (asyncio.Event): Event to signal stopping the execution of the queue.
|
29
29
|
available_capacity (int): The remaining number of tasks the queue can handle.
|
30
30
|
execution_mode (bool): If `execute` is running.
|
31
|
+
refresh_time (int): The time interval between task processing.
|
31
32
|
"""
|
32
33
|
|
33
|
-
def __init__(self, capacity=5):
|
34
|
+
def __init__(self, capacity=5, refresh_time=1):
|
35
|
+
"""
|
36
|
+
Initializes a new instance of WorkQueue.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
capacity (int): The maximum number of tasks the queue can handle.
|
40
|
+
refresh_time (int): The time interval between task processing.
|
41
|
+
|
42
|
+
Raises:
|
43
|
+
ValueError: If capacity is less than 0 or refresh_time is negative.
|
44
|
+
"""
|
34
45
|
if capacity < 0:
|
35
46
|
raise ValueError("initial capacity must be >= 0")
|
47
|
+
if refresh_time < 0:
|
48
|
+
raise ValueError("refresh time for execution can not be negative")
|
36
49
|
self.capacity = capacity
|
37
50
|
self.queue = asyncio.Queue()
|
38
51
|
self._stop_event = asyncio.Event()
|
39
52
|
self.available_capacity = capacity
|
40
53
|
self.execution_mode = False
|
54
|
+
self.refresh_time = refresh_time
|
41
55
|
|
42
56
|
async def enqueue(self, work) -> None:
|
43
57
|
"""Enqueue a work item."""
|
@@ -60,20 +74,6 @@ class WorkQueue:
|
|
60
74
|
"""Return whether the queue has been stopped."""
|
61
75
|
return self._stop_event.is_set()
|
62
76
|
|
63
|
-
# async def process(self):
|
64
|
-
# async def _parse_work(work):
|
65
|
-
# async with self.semaphore:
|
66
|
-
# await work.perform()
|
67
|
-
#
|
68
|
-
# tasks = set()
|
69
|
-
# while self.queue.qsize() > 0:
|
70
|
-
# next = await self.dequeue()
|
71
|
-
# next.status = WorkStatus.IN_PROGRESS
|
72
|
-
# task = asyncio.create_task(_parse_work(next))
|
73
|
-
# tasks.add(task)
|
74
|
-
#
|
75
|
-
# await asyncio.wait(tasks)
|
76
|
-
|
77
77
|
async def process(self) -> None:
|
78
78
|
"""Process the work items in the queue."""
|
79
79
|
tasks = set()
|
@@ -88,7 +88,7 @@ class WorkQueue:
|
|
88
88
|
await asyncio.wait(tasks)
|
89
89
|
self.available_capacity = self.capacity
|
90
90
|
|
91
|
-
async def execute(self
|
91
|
+
async def execute(self):
|
92
92
|
"""
|
93
93
|
Continuously executes the process method at a specified refresh interval.
|
94
94
|
|
@@ -97,7 +97,9 @@ class WorkQueue:
|
|
97
97
|
successive calls to `process`. Defaults to 1.
|
98
98
|
"""
|
99
99
|
self.execution_mode = True
|
100
|
+
self._stop_event.clear()
|
101
|
+
|
100
102
|
while not self.stopped:
|
101
103
|
await self.process()
|
102
|
-
await asyncio.sleep(refresh_time)
|
104
|
+
await asyncio.sleep(self.refresh_time)
|
103
105
|
self.execution_mode = False
|
@@ -0,0 +1,155 @@
|
|
1
|
+
import inspect
|
2
|
+
from typing import Any, Callable
|
3
|
+
from pydantic import Field, field_validator, model_validator
|
4
|
+
|
5
|
+
from lionagi.core.collections.abc.component import Component
|
6
|
+
from lionagi.core.work.work import WorkStatus, Work
|
7
|
+
from collections.abc import Coroutine
|
8
|
+
|
9
|
+
|
10
|
+
class WorkTask(Component):
|
11
|
+
"""
|
12
|
+
A class representing a work task that can be processed in multiple steps.
|
13
|
+
|
14
|
+
Attributes:
|
15
|
+
name (str | None): The name of the task.
|
16
|
+
status (WorkStatus): The current status of the task.
|
17
|
+
status_note (str): A note for the task's current status.
|
18
|
+
work_history (list[Work]): A list of works processed in this task.
|
19
|
+
max_steps (int | None): The maximum number of works allowed in this task.
|
20
|
+
current_work (Work | None): The current work in progress.
|
21
|
+
post_processing (Callable | None): The post-processing function to be executed after the entire task is successfully completed.
|
22
|
+
"""
|
23
|
+
name: str | None = Field(
|
24
|
+
None,
|
25
|
+
description="Name of the task"
|
26
|
+
)
|
27
|
+
|
28
|
+
status: WorkStatus = Field(
|
29
|
+
WorkStatus.PENDING,
|
30
|
+
description="The current status of the task"
|
31
|
+
)
|
32
|
+
|
33
|
+
status_note: str = Field(
|
34
|
+
None,
|
35
|
+
description="Note for tasks current status"
|
36
|
+
)
|
37
|
+
|
38
|
+
work_history: list[Work] = Field(
|
39
|
+
[],
|
40
|
+
description="List of works processed"
|
41
|
+
)
|
42
|
+
|
43
|
+
max_steps: int | None = Field(
|
44
|
+
10,
|
45
|
+
description="Maximum number of works allowed"
|
46
|
+
)
|
47
|
+
|
48
|
+
current_work: Work | None = Field(
|
49
|
+
None,
|
50
|
+
description="The current work in progress"
|
51
|
+
)
|
52
|
+
|
53
|
+
post_processing: Callable | None = Field(
|
54
|
+
None,
|
55
|
+
description="The post-processing function to be executed after the entire task has been successfully completed."
|
56
|
+
)
|
57
|
+
|
58
|
+
@field_validator("max_steps", mode="before")
|
59
|
+
def _validate_max_steps(cls, value):
|
60
|
+
"""
|
61
|
+
Validates that max_steps is a positive integer.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
value (int): The value to validate.
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
int: The validated value.
|
68
|
+
|
69
|
+
Raises:
|
70
|
+
ValueError: If value is not a positive integer.
|
71
|
+
"""
|
72
|
+
if value <= 0:
|
73
|
+
raise ValueError("Invalid value: max_steps must be a positive integer.")
|
74
|
+
return value
|
75
|
+
|
76
|
+
@field_validator("post_processing", mode="before")
|
77
|
+
def _validate_prost_processing(cls, value):
|
78
|
+
"""
|
79
|
+
Validates that post_processing is an asynchronous function.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
value (Callable): The value to validate.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
Callable: The validated value.
|
86
|
+
|
87
|
+
Raises:
|
88
|
+
ValueError: If value is not an asynchronous function.
|
89
|
+
"""
|
90
|
+
if value is not None and not inspect.iscoroutinefunction((value)):
|
91
|
+
raise ValueError("post_processing must be a async function")
|
92
|
+
return value
|
93
|
+
|
94
|
+
@property
|
95
|
+
def available_steps(self):
|
96
|
+
"""
|
97
|
+
Calculates the number of available steps left in the task.
|
98
|
+
|
99
|
+
Returns:
|
100
|
+
int: The number of available steps.
|
101
|
+
"""
|
102
|
+
return max(0, self.max_steps - len(self.work_history))
|
103
|
+
|
104
|
+
def clone(self):
|
105
|
+
"""
|
106
|
+
Creates a clone of the current WorkTask instance.
|
107
|
+
|
108
|
+
Returns:
|
109
|
+
WorkTask: A new instance of WorkTask with the same attributes.
|
110
|
+
"""
|
111
|
+
new_worktask = WorkTask(name=self.name, status=self.status, max_steps=self.max_steps, current_work=self.current_work)
|
112
|
+
for work in self.work_history:
|
113
|
+
new_worktask.work_history.append(work)
|
114
|
+
return new_worktask
|
115
|
+
|
116
|
+
async def process(self, current_func_node):
|
117
|
+
"""
|
118
|
+
Processes the current work function node.
|
119
|
+
|
120
|
+
Args:
|
121
|
+
current_func_node (WorkFunctionNode): The current function node being processed.
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
str | list[WorkTask]: Returns "COMPLETED", "FAILED", or a list of new WorkTask instances if there are next works to process.
|
125
|
+
"""
|
126
|
+
if self.current_work.status == WorkStatus.FAILED:
|
127
|
+
self.status = WorkStatus.FAILED
|
128
|
+
self.status_note = f"Work {self.current_work.ln_id} failed. Error: {self.current_work.error}"
|
129
|
+
self.current_work = None
|
130
|
+
return "FAILED"
|
131
|
+
elif self.current_work.status == WorkStatus.COMPLETED:
|
132
|
+
next_works = []
|
133
|
+
if not current_func_node.relations["out"].is_empty():
|
134
|
+
for workedge in current_func_node.relations["out"]:
|
135
|
+
next_work = await workedge.forward(self)
|
136
|
+
if next_work is not None:
|
137
|
+
next_works.append(next_work)
|
138
|
+
if len(next_works) == 0:
|
139
|
+
self.current_work = None
|
140
|
+
self.status = WorkStatus.COMPLETED
|
141
|
+
if self.post_processing:
|
142
|
+
await self.post_processing(self)
|
143
|
+
return "COMPLETED"
|
144
|
+
else:
|
145
|
+
return_tasks = []
|
146
|
+
for i in reversed(range(len(next_works))):
|
147
|
+
if i == 0:
|
148
|
+
self.current_work = next_works[i]
|
149
|
+
self.work_history.append(next_works[i])
|
150
|
+
else:
|
151
|
+
clone_task = self.clone()
|
152
|
+
clone_task.current_work = next_works[i]
|
153
|
+
clone_task.work_history.append(next_works[i])
|
154
|
+
return_tasks.append(clone_task)
|
155
|
+
return return_tasks
|