ldp 0.32.1__tar.gz → 0.33.0.dev0__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 (219) hide show
  1. {ldp-0.32.1 → ldp-0.33.0.dev0}/.github/workflows/tests.yml +6 -0
  2. {ldp-0.32.1 → ldp-0.33.0.dev0}/PKG-INFO +15 -5
  3. {ldp-0.32.1 → ldp-0.33.0.dev0}/README.md +9 -1
  4. {ldp-0.32.1 → ldp-0.33.0.dev0}/pyproject.toml +6 -3
  5. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/algorithms.py +5 -2
  6. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/data_structures.py +8 -4
  7. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/common_ops.py +15 -6
  8. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/memory.py +10 -2
  9. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/op_utils.py +23 -0
  10. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/ops.py +24 -10
  11. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/version.py +3 -3
  12. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp.egg-info/PKG-INFO +15 -5
  13. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp.egg-info/SOURCES.txt +1 -0
  14. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp.egg-info/requires.txt +6 -3
  15. ldp-0.33.0.dev0/tests/test_readme.py +212 -0
  16. {ldp-0.32.1 → ldp-0.33.0.dev0}/uv.lock +14 -7
  17. {ldp-0.32.1 → ldp-0.33.0.dev0}/.github/renovate.json5 +0 -0
  18. {ldp-0.32.1 → ldp-0.33.0.dev0}/.github/workflows/docs.yml +0 -0
  19. {ldp-0.32.1 → ldp-0.33.0.dev0}/.github/workflows/publish.yml +0 -0
  20. {ldp-0.32.1 → ldp-0.33.0.dev0}/.gitignore +0 -0
  21. {ldp-0.32.1 → ldp-0.33.0.dev0}/.mailmap +0 -0
  22. {ldp-0.32.1 → ldp-0.33.0.dev0}/.pre-commit-config.yaml +0 -0
  23. {ldp-0.32.1 → ldp-0.33.0.dev0}/.python-version +0 -0
  24. {ldp-0.32.1 → ldp-0.33.0.dev0}/.secrets.allowlist +0 -0
  25. {ldp-0.32.1 → ldp-0.33.0.dev0}/CITATION.cff +0 -0
  26. {ldp-0.32.1 → ldp-0.33.0.dev0}/LICENSE +0 -0
  27. {ldp-0.32.1 → ldp-0.33.0.dev0}/citation.bib +0 -0
  28. {ldp-0.32.1 → ldp-0.33.0.dev0}/docs/assets/Aviary.png +0 -0
  29. {ldp-0.32.1 → ldp-0.33.0.dev0}/docs/assets/ldp_chessboard.png +0 -0
  30. {ldp-0.32.1 → ldp-0.33.0.dev0}/docs/assets/ldp_definition.png +0 -0
  31. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/LICENSE +0 -0
  32. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/README.md +0 -0
  33. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/pyproject.toml +0 -0
  34. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/__init__.py +0 -0
  35. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/constants.py +0 -0
  36. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/cost_tracker.py +0 -0
  37. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/embeddings.py +0 -0
  38. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/exceptions.py +0 -0
  39. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/llms.py +0 -0
  40. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/py.typed +0 -0
  41. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/rate_limiter.py +0 -0
  42. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/types.py +0 -0
  43. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/src/lmi/utils.py +0 -0
  44. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/__init__.py +0 -0
  45. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMEmbeddingModel.test_caching.yaml +0 -0
  46. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMEmbeddingModel.test_embedding_batches.yaml +0 -0
  47. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMEmbeddingModel.test_router_usage[with-router].yaml +0 -0
  48. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMEmbeddingModel.test_router_usage[without-router].yaml +0 -0
  49. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_call[Anthropic-model].yaml +0 -0
  50. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_call[OpenAI-model].yaml +0 -0
  51. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_call_single[with-router].yaml +0 -0
  52. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_call_single[without-router].yaml +0 -0
  53. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_call_w_multiple_models[multiple-models].yaml +0 -0
  54. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_cost_call[Anthropic-model].yaml +0 -0
  55. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_cost_call[OpenAI-model].yaml +0 -0
  56. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_cost_call_single[with-router].yaml +0 -0
  57. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_cost_call_single[without-router].yaml +0 -0
  58. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_max_token_truncation[with-router].yaml +0 -0
  59. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestLiteLLMModel.test_max_token_truncation[without-router].yaml +0 -0
  60. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_model[gpt-3.5-turbo-0125].yaml +0 -0
  61. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_multiple_completion[openai].yaml +0 -0
  62. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_output_schema[json-mode-base-model].yaml +0 -0
  63. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_output_schema[json-mode-type-adapter].yaml +0 -0
  64. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_output_schema[structured-outputs].yaml +0 -0
  65. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_parameterizing_tool_from_arg_union.yaml +0 -0
  66. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_single_completion[claude-3-5-haiku-20241022].yaml +0 -0
  67. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_single_completion[gpt-3.5-turbo-0125].yaml +0 -0
  68. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestMultipleCompletion.test_text_image_message[gpt-4o-mini-2024-07-18].yaml +0 -0
  69. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestReasoning.test_anthropic_model.yaml +0 -0
  70. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestReasoning.test_deepseek_model[deepseek-reasoner].yaml +0 -0
  71. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestReasoning.test_deepseek_model[openrouter-deepseek].yaml +0 -0
  72. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestTooling.test_empty_tools[Anthropic-empty-tools].yaml +0 -0
  73. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestTooling.test_empty_tools[Anthropic-no-tools].yaml +0 -0
  74. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestTooling.test_empty_tools[OpenAI-empty-tools].yaml +0 -0
  75. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestTooling.test_empty_tools[OpenAI-no-tools].yaml +0 -0
  76. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestTooling.test_multi_response_validation.yaml +0 -0
  77. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/cassettes/TestTooling.test_tool_selection.yaml +0 -0
  78. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/conftest.py +0 -0
  79. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/test_cost_tracking.py +0 -0
  80. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/test_embeddings.py +0 -0
  81. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/test_llms.py +0 -0
  82. {ldp-0.32.1 → ldp-0.33.0.dev0}/packages/lmi/tests/test_rate_limiter.py +0 -0
  83. {ldp-0.32.1 → ldp-0.33.0.dev0}/setup.cfg +0 -0
  84. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/__init__.py +0 -0
  85. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/__init__.py +0 -0
  86. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/agent.py +0 -0
  87. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/agent_client.py +0 -0
  88. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/interactive_agent.py +0 -0
  89. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/memory_agent.py +0 -0
  90. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/react_agent.py +0 -0
  91. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/simple_agent.py +0 -0
  92. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/agent/tree_of_thoughts_agent.py +0 -0
  93. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/__init__.py +0 -0
  94. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/beam_search.py +0 -0
  95. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/callbacks.py +0 -0
  96. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/datasets.py +0 -0
  97. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/optimizer/__init__.py +0 -0
  98. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/optimizer/ape.py +0 -0
  99. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/optimizer/memory.py +0 -0
  100. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/optimizer/opt.py +0 -0
  101. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/optimizer/replay_buffers.py +0 -0
  102. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/rollout.py +0 -0
  103. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/runners.py +0 -0
  104. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/alg/tree_search.py +0 -0
  105. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/__init__.py +0 -0
  106. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/async_torch.py +0 -0
  107. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/gradient_estimators.py +0 -0
  108. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/loss_ops.py +0 -0
  109. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/modules/__init__.py +0 -0
  110. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/modules/llm_call.py +0 -0
  111. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/modules/react.py +0 -0
  112. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/modules/reflect.py +0 -0
  113. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/modules/thought.py +0 -0
  114. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/graph/torch_ops.py +0 -0
  115. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/llms/__init__.py +0 -0
  116. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/llms/prompts.py +0 -0
  117. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/main.py +0 -0
  118. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/__init__.py +0 -0
  119. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/agent/simple_local_agent.py +0 -0
  120. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/README.md +0 -0
  121. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/llama2_chat_template_ori.jinja +0 -0
  122. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/llama3.1_chat_template_hf.jinja +0 -0
  123. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/llama3.1_chat_template_nothought.jinja +0 -0
  124. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/llama3.1_chat_template_thought.jinja +0 -0
  125. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/llama3.1_chat_template_vllm.jinja +0 -0
  126. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/chat_templates/llama3_chat_template_ori.jinja +0 -0
  127. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/generation/__init__.py +0 -0
  128. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/generation/base.py +0 -0
  129. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/graph/llm_call_op.py +0 -0
  130. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/handlers/chunking.py +0 -0
  131. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/handlers/module_handler.py +0 -0
  132. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/handlers/transformer_handler.py +0 -0
  133. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/lm_config.py +0 -0
  134. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/nn/utils.py +0 -0
  135. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/py.typed +0 -0
  136. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/shims.py +0 -0
  137. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp/utils.py +0 -0
  138. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp.egg-info/dependency_links.txt +0 -0
  139. {ldp-0.32.1 → ldp-0.33.0.dev0}/src/ldp.egg-info/top_level.txt +0 -0
  140. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/.gitignore +0 -0
  141. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/__init__.py +0 -0
  142. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestAgentState.test_no_state_mutation[agent0].yaml +0 -0
  143. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestAgentState.test_no_state_mutation[agent1].yaml +0 -0
  144. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestAgentState.test_no_state_mutation[agent2].yaml +0 -0
  145. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestHTTPAgentClient.test_lifecycle.yaml +0 -0
  146. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestLLMCallOp.test_compute_logprob[0.0].yaml +0 -0
  147. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestLLMCallOp.test_compute_logprob[0.5].yaml +0 -0
  148. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestLLMCallOp.test_compute_logprob[1.0].yaml +0 -0
  149. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestLLMCallOp.test_cost_tracking.yaml +0 -0
  150. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestLLMCallOp.test_empty_tools.yaml +0 -0
  151. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestLLMCallOp.test_validation.yaml +0 -0
  152. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestMemoryAgent.test_agent_grad.yaml +0 -0
  153. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestMemoryAgent.test_dummyenv[gpt-4o-mini-2024-07-18].yaml +0 -0
  154. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestMemoryOpt.test_lessons_memory_optimizer.yaml +0 -0
  155. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestNoToolsSimpleAgent.test_dummyenv[claude-3-5-haiku-20241022].yaml +0 -0
  156. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestNoToolsSimpleAgent.test_dummyenv[gpt-4o-mini-2024-07-18].yaml +0 -0
  157. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestParallelism.test_SimpleAgent_can_parallel_call.yaml +0 -0
  158. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_agent_grad[False-claude-3-5-haiku-20241022].yaml +0 -0
  159. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_agent_grad[False-gpt-4o].yaml +0 -0
  160. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_agent_grad[True-claude-3-5-haiku-20241022].yaml +0 -0
  161. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_agent_grad[True-gpt-4-turbo].yaml +0 -0
  162. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_multi_step[False].yaml +0 -0
  163. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_multi_step[True].yaml +0 -0
  164. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_react_dummyenv[False-claude-3-5-haiku-20241022].yaml +0 -0
  165. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_react_dummyenv[False-gpt-4o].yaml +0 -0
  166. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_react_dummyenv[True-claude-3-5-haiku-20241022].yaml +0 -0
  167. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestReActAgent.test_react_dummyenv[True-gpt-4-turbo].yaml +0 -0
  168. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestSimpleAgent.test_agent_grad[claude-3-5-haiku-20241022].yaml +0 -0
  169. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestSimpleAgent.test_agent_grad[gpt-4o-mini-2024-07-18].yaml +0 -0
  170. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestSimpleAgent.test_dummyenv[claude-3-5-haiku-20241022].yaml +0 -0
  171. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestSimpleAgent.test_dummyenv[gpt-4o-mini-2024-07-18].yaml +0 -0
  172. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestSimpleAgent.test_hide_old_action_content.yaml +0 -0
  173. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/TestSimpleAgent.test_hide_old_env_states.yaml +0 -0
  174. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_beam_search.yaml +0 -0
  175. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-large-0-256].yaml +0 -0
  176. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-large-0-512].yaml +0 -0
  177. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-large-32-256].yaml +0 -0
  178. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-large-32-512].yaml +0 -0
  179. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-large-64-256].yaml +0 -0
  180. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-large-64-512].yaml +0 -0
  181. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-small-0-256].yaml +0 -0
  182. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-small-0-512].yaml +0 -0
  183. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-small-32-256].yaml +0 -0
  184. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-small-32-512].yaml +0 -0
  185. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-small-64-256].yaml +0 -0
  186. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_embedding_op[text-embedding-3-small-64-512].yaml +0 -0
  187. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_fallbacks_working[False].yaml +0 -0
  188. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_fallbacks_working[True].yaml +0 -0
  189. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_llm_call_graph.yaml +0 -0
  190. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_offline_trainer[False].yaml +0 -0
  191. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_offline_trainer[True].yaml +0 -0
  192. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_online_trainer[False].yaml +0 -0
  193. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_online_trainer[True].yaml +0 -0
  194. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_reflect_module.yaml +0 -0
  195. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_rollout[False].yaml +0 -0
  196. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/cassettes/test_rollout[True].yaml +0 -0
  197. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/conftest.py +0 -0
  198. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_agents.py +0 -0
  199. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_algorithms.py +0 -0
  200. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_buffers.py +0 -0
  201. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_context_managers.py +0 -0
  202. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_data_structures.py +0 -0
  203. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_envs.py +0 -0
  204. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_gradients.py +0 -0
  205. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_loss_ops.py +0 -0
  206. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_memory.py +0 -0
  207. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_modules.py +0 -0
  208. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_nn_models.py +0 -0
  209. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_nn_ops.py +0 -0
  210. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_ops.py +0 -0
  211. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_optimizer.py +0 -0
  212. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_prompts.py +0 -0
  213. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_rollouts.py +0 -0
  214. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_runners.py +0 -0
  215. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_shims.py +0 -0
  216. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_torch_ops.py +0 -0
  217. {ldp-0.32.1 → ldp-0.33.0.dev0}/tests/test_utils.py +0 -0
  218. {ldp-0.32.1 → ldp-0.33.0.dev0}/tutorials/creating_a_language_agent.ipynb +0 -0
  219. {ldp-0.32.1 → ldp-0.33.0.dev0}/tutorials/evaluating_a_llama_agent.ipynb +0 -0
@@ -59,6 +59,12 @@ jobs:
59
59
  env:
60
60
  OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
61
61
  ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
62
+ - run:
63
+ | # this is to check that we can run README examples with lazily imported dependencies (the [scg] subpackage)
64
+ uv pip uninstall dm-tree usearch networkx && uv run --no-sync pytest --noconftest tests/test_readme.py
65
+ env:
66
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
67
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
62
68
  test-lmi:
63
69
  runs-on: ubuntu-latest
64
70
  steps:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ldp
3
- Version: 0.32.1
3
+ Version: 0.33.0.dev0
4
4
  Summary: Agent framework for constructing language model agents and training on constructive tasks.
5
5
  Author-email: FutureHouse technical staff <hello@futurehouse.org>
6
6
  License: Apache License
@@ -220,18 +220,15 @@ Requires-Python: >=3.11
220
220
  Description-Content-Type: text/markdown
221
221
  License-File: LICENSE
222
222
  Requires-Dist: aiofiles
223
- Requires-Dist: dm-tree
224
223
  Requires-Dist: fhaviary>=0.20.0
225
224
  Requires-Dist: fhlmi
226
225
  Requires-Dist: httpx
227
- Requires-Dist: networkx[default]~=3.4
228
226
  Requires-Dist: numpy>=1.20
229
227
  Requires-Dist: pydantic~=2.0
230
228
  Requires-Dist: tenacity
231
229
  Requires-Dist: tiktoken
232
230
  Requires-Dist: tqdm
233
231
  Requires-Dist: typing-extensions; python_version <= "3.11"
234
- Requires-Dist: usearch>=2.13
235
232
  Provides-Extra: dev
236
233
  Requires-Dist: fhaviary[xml]>=0.19; extra == "dev"
237
234
  Requires-Dist: fhlmi[dev]; extra == "dev"
@@ -254,6 +251,7 @@ Requires-Dist: pytest-timer[colorama]; extra == "dev"
254
251
  Requires-Dist: pytest-xdist; extra == "dev"
255
252
  Requires-Dist: pytest>=8; extra == "dev"
256
253
  Requires-Dist: refurb>=2; extra == "dev"
254
+ Requires-Dist: usearch>=2.13; extra == "dev"
257
255
  Requires-Dist: vcrpy>=6; extra == "dev"
258
256
  Provides-Extra: monitor
259
257
  Requires-Dist: wandb; extra == "monitor"
@@ -262,6 +260,7 @@ Requires-Dist: accelerate; extra == "nn"
262
260
  Requires-Dist: dask-cuda>=24.8.2; extra == "nn"
263
261
  Requires-Dist: dask-jobqueue; extra == "nn"
264
262
  Requires-Dist: dask[distributed]; extra == "nn"
263
+ Requires-Dist: ldp[scg]; extra == "nn"
265
264
  Requires-Dist: tokenizers>0.20; extra == "nn"
266
265
  Requires-Dist: torch<2.6,>=2.5; extra == "nn"
267
266
  Requires-Dist: transformers<4.51,>=4.46; extra == "nn"
@@ -269,6 +268,9 @@ Requires-Dist: wandb; extra == "nn"
269
268
  Provides-Extra: rich
270
269
  Requires-Dist: rich; extra == "rich"
271
270
  Requires-Dist: tqdm>=4.56; extra == "rich"
271
+ Provides-Extra: scg
272
+ Requires-Dist: dm-tree; extra == "scg"
273
+ Requires-Dist: networkx[default]~=3.4; extra == "scg"
272
274
  Provides-Extra: server
273
275
  Requires-Dist: fastapi>=0.109; extra == "server"
274
276
  Provides-Extra: typing
@@ -465,7 +467,15 @@ which just converts the action constructed by plain python into a node in a comp
465
467
 
466
468
  For more advanced use-cases, LDP features a stochastic computation graph [^2]
467
469
  which enables differentiatiation with respect to agent parameters
468
- (including the weights of the LLM). The example computation graph below illustrates the functionality
470
+ (including the weights of the LLM).
471
+
472
+ You should install the `scg` subpackage to work with it:
473
+
474
+ ```bash
475
+ pip install ldp[scg]
476
+ ```
477
+
478
+ The example computation graph below illustrates the functionality
469
479
 
470
480
  ```py
471
481
  from ldp.graph import FxnOp, LLMCallOp, PromptOp, compute_graph
@@ -185,7 +185,15 @@ which just converts the action constructed by plain python into a node in a comp
185
185
 
186
186
  For more advanced use-cases, LDP features a stochastic computation graph [^2]
187
187
  which enables differentiatiation with respect to agent parameters
188
- (including the weights of the LLM). The example computation graph below illustrates the functionality
188
+ (including the weights of the LLM).
189
+
190
+ You should install the `scg` subpackage to work with it:
191
+
192
+ ```bash
193
+ pip install ldp[scg]
194
+ ```
195
+
196
+ The example computation graph below illustrates the functionality
189
197
 
190
198
  ```py
191
199
  from ldp.graph import FxnOp, LLMCallOp, PromptOp, compute_graph
@@ -23,18 +23,15 @@ classifiers = [
23
23
  ]
24
24
  dependencies = [
25
25
  "aiofiles",
26
- "dm-tree",
27
26
  "fhaviary>=0.20.0", # For Environment.get_id
28
27
  "fhlmi", # For new LLM client interface
29
28
  "httpx",
30
- "networkx[default]~=3.4", # Pin for pydot fix
31
29
  "numpy>=1.20", # For numpy.typing
32
30
  "pydantic~=2.0",
33
31
  "tenacity",
34
32
  "tiktoken",
35
33
  "tqdm",
36
34
  "typing-extensions; python_version <= '3.11'", # for typing.override
37
- "usearch>=2.13", # For py.typed
38
35
  ]
39
36
  description = "Agent framework for constructing language model agents and training on constructive tasks."
40
37
  dynamic = ["version"]
@@ -66,6 +63,7 @@ dev = [
66
63
  "pytest-xdist",
67
64
  "pytest>=8", # Pin to keep recent
68
65
  "refurb>=2", # Pin to keep recent
66
+ "usearch>=2.13", # For py.typed
69
67
  "vcrpy>=6", # Pin for https://github.com/kevin1024/vcrpy/issues/884
70
68
  ]
71
69
  monitor = [
@@ -76,6 +74,7 @@ nn = [
76
74
  "dask-cuda>=24.8.2",
77
75
  "dask-jobqueue",
78
76
  "dask[distributed]",
77
+ "ldp[scg]",
79
78
  "tokenizers>0.20",
80
79
  "torch>=2.5,<2.6", # Temporarily pin <2.6 until someone fixes our CI with newer versions
81
80
  "transformers>=4.46,<4.51", # Temporarily pin <4.51 until someone fixes our CI with newer versions, and also https://github.com/huggingface/transformers/issues/37339
@@ -85,6 +84,10 @@ rich = [
85
84
  "rich",
86
85
  "tqdm>=4.56", # When tqdm.rich was created
87
86
  ]
87
+ scg = [
88
+ "dm-tree",
89
+ "networkx[default]~=3.4", # Pin for pydot fix
90
+ ]
88
91
  server = [
89
92
  "fastapi>=0.109", # For Python 3.12 support
90
93
  ]
@@ -4,13 +4,15 @@ import inspect
4
4
  import itertools
5
5
  import random
6
6
  from collections.abc import Awaitable, Callable, Hashable, Iterable, Sequence
7
- from typing import Any, Literal, TypeVar
7
+ from typing import TYPE_CHECKING, Any, Literal, TypeVar
8
8
 
9
- import networkx as nx
9
+ if TYPE_CHECKING:
10
+ import networkx as nx
10
11
  import numpy as np
11
12
  from aviary.core import Message, Tool, ToolRequestMessage, join
12
13
 
13
14
  from ldp.graph import OpResult
15
+ from ldp.graph.op_utils import _lazy_import_networkx
14
16
  from ldp.graph.ops import GradOutType
15
17
 
16
18
 
@@ -36,6 +38,7 @@ def to_network( # noqa: C901
36
38
  Returns:
37
39
  Populated a NetworkX multi-edge directed graph.
38
40
  """
41
+ nx = _lazy_import_networkx()
39
42
 
40
43
  def gvizify(x: Any) -> str:
41
44
  """Stringify and then escape colons for Graphviz labels."""
@@ -9,16 +9,17 @@ from typing import TYPE_CHECKING, Any, ClassVar, Self, cast
9
9
  from uuid import UUID
10
10
 
11
11
  import aiofiles
12
- import networkx as nx
13
12
  from aviary.core import Message, ToolRequestMessage, ToolResponseMessage, join
14
13
  from pydantic import BaseModel, ConfigDict, Field, JsonValue, field_validator
15
14
 
16
15
  from ldp.graph import OpResult
16
+ from ldp.graph.op_utils import _lazy_import_networkx
17
17
  from ldp.utils import discounted_returns
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from aviary.core import Environment
21
21
 
22
+
22
23
  logger = logging.getLogger(__name__)
23
24
 
24
25
 
@@ -180,6 +181,7 @@ class TransitionTree:
180
181
  """
181
182
  self.root_id = str(root_id)
182
183
 
184
+ nx = _lazy_import_networkx()
183
185
  self.tree = nx.DiGraph() # the actual tree
184
186
  self.rev_tree = nx.DiGraph() # the same as self.tree, but with reversed edges
185
187
 
@@ -292,7 +294,7 @@ class TransitionTree:
292
294
  discount_factor: The discount factor to use when computing cumulative
293
295
  future rewards.
294
296
  """
295
- for step_id in nx.topological_sort(self.rev_tree):
297
+ for step_id in _lazy_import_networkx().topological_sort(self.rev_tree):
296
298
  step: Transition | None = self.tree.nodes[step_id]["transition"]
297
299
  if step is None:
298
300
  continue
@@ -324,7 +326,9 @@ class TransitionTree:
324
326
  """
325
327
  state_values: dict[str, float] = {}
326
328
 
327
- for step_id in cast("Iterable[str]", nx.topological_sort(self.tree)):
329
+ for step_id in cast(
330
+ "Iterable[str]", _lazy_import_networkx().topological_sort(self.tree)
331
+ ):
328
332
  # topological sort means we will update a parent node in-place before
329
333
  # descending to its children
330
334
 
@@ -412,7 +416,7 @@ class TransitionTree:
412
416
  # old step ID -> new step ID
413
417
  node_remap: dict[str, str] = {self.root_id: self.root_id}
414
418
 
415
- for step_id in nx.topological_sort(self.tree):
419
+ for step_id in _lazy_import_networkx().topological_sort(self.tree):
416
420
  step: Transition | None = self.tree.nodes[step_id]["transition"]
417
421
  if step is None:
418
422
  continue
@@ -8,11 +8,10 @@ import inspect
8
8
  import logging
9
9
  from collections.abc import Awaitable, Callable
10
10
  from functools import lru_cache
11
- from typing import Generic, TypeVar, cast, overload
11
+ from typing import TYPE_CHECKING, Generic, TypeVar, cast, overload
12
12
 
13
13
  import numpy as np
14
14
  import tenacity
15
- import tree
16
15
  from aviary.core import Message, Tool, ToolRequestMessage, is_coroutine_callable
17
16
  from lmi import (
18
17
  EmbeddingModel,
@@ -24,11 +23,13 @@ from lmi import (
24
23
  from lmi import LiteLLMModel as LLMModel
25
24
  from pydantic import BaseModel
26
25
 
27
- from .gradient_estimators import assign_constant_grads
28
26
  from .memory import Memory, MemoryModel, UIndexMemoryModel
29
- from .op_utils import CallID, get_call_id, get_training_mode
27
+ from .op_utils import CallID, _lazy_import_tree, get_call_id, get_training_mode
30
28
  from .ops import GradInType, Op, OpCtx, ResultOrValue, TOutput_co
31
29
 
30
+ if TYPE_CHECKING:
31
+ import tree
32
+
32
33
  logger = logging.getLogger(__name__)
33
34
 
34
35
 
@@ -76,6 +77,8 @@ class StopGradOp(IdentityOp[TOutput_co]):
76
77
  grad_output: tree.Structure,
77
78
  call_id: CallID,
78
79
  ) -> GradInType:
80
+ from .gradient_estimators import assign_constant_grads
81
+
79
82
  return assign_constant_grads(input_args, input_kwargs, None)
80
83
 
81
84
 
@@ -101,7 +104,7 @@ class ConfigOp(Op[TConfig], Generic[TConfig]):
101
104
  call_id: CallID,
102
105
  ) -> GradInType:
103
106
  # Check that the grad_output structure is consistent with our config
104
- tree.assert_same_structure(
107
+ _lazy_import_tree().assert_same_structure(
105
108
  grad_output, ctx.get(call_id, "output").value, check_types=False
106
109
  )
107
110
 
@@ -186,6 +189,8 @@ class FxnOp(Op[TOutput_co]):
186
189
  grad_output: tree.Structure,
187
190
  call_id: CallID,
188
191
  ) -> GradInType:
192
+ from .gradient_estimators import assign_constant_grads
193
+
189
194
  return assign_constant_grads(input_args, input_kwargs, 0.0)
190
195
 
191
196
 
@@ -397,7 +402,9 @@ class LLMCallOp(Op[Message]):
397
402
  # but not necessarily each message or tool.
398
403
 
399
404
  # tree.map_structure allows us to assign a gradient of 0 to all fields of config
400
- grad_config = tree.map_structure(lambda _: 0.0, input_kwargs["config"])
405
+ grad_config = _lazy_import_tree().map_structure(
406
+ lambda _: 0.0, input_kwargs["config"]
407
+ )
401
408
  grad_kwargs = {"config": grad_config}
402
409
  for arg in ("msgs", "tools", "tool_choice"):
403
410
  if arg in input_kwargs:
@@ -472,6 +479,8 @@ class MemoryOp(Op[list[Memory]]):
472
479
  call_id: CallID,
473
480
  ) -> GradInType:
474
481
  """Backward pass for memory retrieval - goes back to item."""
482
+ from .gradient_estimators import assign_constant_grads
483
+
475
484
  return assign_constant_grads(input_args, input_kwargs, 0.0)
476
485
 
477
486
 
@@ -17,9 +17,10 @@ from pydantic import (
17
17
  field_validator,
18
18
  model_validator,
19
19
  )
20
- from usearch.index import Index
21
20
 
22
21
  if TYPE_CHECKING:
22
+ from usearch.index import Index # noqa: F401
23
+
23
24
  from .common_ops import MemoryOp
24
25
  from .op_utils import CallID
25
26
  from .ops import Op, OpResult, TOutput_co
@@ -164,13 +165,20 @@ class MemoryModel(BaseModel, ABC, Generic[TIndex]):
164
165
  """Search the internal Index, returning a 'matches' amount of Memories."""
165
166
 
166
167
 
167
- class UIndexMemoryModel(MemoryModel[Index]):
168
+ class UIndexMemoryModel(MemoryModel["Index"]):
168
169
  """Memory model using a U-Search index."""
169
170
 
170
171
  def __init__(self, **kwargs):
171
172
  super().__init__(**kwargs)
172
173
  if not self.embedding_model.ndim:
173
174
  raise TypeError("Specify dimensions to the embedding model.")
175
+ try:
176
+ from usearch.index import Index
177
+ except ImportError as e:
178
+ raise ImportError(
179
+ "U-Search library not found. Unable to use UIndexMemoryModel."
180
+ " To install U-Search dependencies, please run `pip install usearch`."
181
+ ) from e
174
182
  self._index = Index(ndim=self.embedding_model.ndim)
175
183
 
176
184
  async def _add_to_index(self, embedding: np.ndarray) -> int:
@@ -1,12 +1,35 @@
1
1
  import contextvars
2
2
  from collections.abc import AsyncIterator
3
3
  from contextlib import asynccontextmanager
4
+ from types import ModuleType
4
5
  from uuid import UUID, uuid4
5
6
 
6
7
  from aviary.core import is_coroutine_callable
7
8
  from pydantic import BaseModel, field_serializer, field_validator
8
9
 
9
10
 
11
+ def _lazy_import_networkx() -> ModuleType:
12
+ try:
13
+ import networkx as nx
14
+ except ImportError as e:
15
+ raise ImportError(
16
+ "networkx is required for compute graph operations. "
17
+ "Please install it with: pip install ldp[scg]"
18
+ ) from e
19
+ return nx
20
+
21
+
22
+ def _lazy_import_tree() -> ModuleType:
23
+ try:
24
+ import tree
25
+ except ImportError as e:
26
+ raise ImportError(
27
+ "tree is required for compute graph operations. "
28
+ "Please install it with: pip install ldp[scg]"
29
+ ) from e
30
+ return tree
31
+
32
+
10
33
  class CallID(BaseModel):
11
34
  run_id: UUID
12
35
  fwd_id: UUID
@@ -9,23 +9,34 @@ import secrets
9
9
  from abc import ABC, abstractmethod
10
10
  from collections import defaultdict
11
11
  from collections.abc import Callable, Collection, Iterable, Iterator, Mapping, Sequence
12
- from typing import Any, ClassVar, Generic, TypeAlias, TypeVar
12
+ from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypeAlias, TypeVar
13
13
  from uuid import UUID
14
14
 
15
- import networkx as nx
16
- import tree
15
+ if TYPE_CHECKING:
16
+ import networkx as nx
17
+ import tree
17
18
  from pydantic import BaseModel, Field
18
19
 
19
- from .op_utils import CallID, compute_graph, get_call_id, get_training_mode, op_call
20
+ from .op_utils import (
21
+ CallID,
22
+ _lazy_import_networkx,
23
+ _lazy_import_tree,
24
+ compute_graph,
25
+ get_call_id,
26
+ get_training_mode,
27
+ op_call,
28
+ )
20
29
 
21
30
  logger = logging.getLogger(__name__)
22
31
 
23
32
 
24
- GradOutType: TypeAlias = tree.Structure | None # None means the gradient has terminated
33
+ GradOutType: TypeAlias = (
34
+ "tree.Structure | None" # None means the gradient has terminated
35
+ )
25
36
  GradInType: TypeAlias = tuple[Sequence[GradOutType], Mapping[str, GradOutType]]
26
37
  BackwardsType: TypeAlias = Callable[
27
38
  # Call signature of Op.backward
28
- ["OpCtx", list, dict, tree.Structure, CallID],
39
+ ["OpCtx", list, dict, "tree.Structure", CallID],
29
40
  GradInType,
30
41
  ]
31
42
  TOutput_co = TypeVar("TOutput_co", covariant=True)
@@ -93,8 +104,11 @@ class OpResult(Generic[TOutput_co]):
93
104
  (a) define the backward computation
94
105
  (b) store internal gradients for optimizer updates.
95
106
  """
96
- # call ID -> [d op(x) / d x] for each op that consumes x
97
- grad_outputs: dict[CallID, list[tree.Structure]] = defaultdict(list)
107
+ tree = _lazy_import_tree()
108
+
109
+ # call ID -> [d op(x) / d x] for each op that consumes x[
110
+ # due to interaction between ruff and mypy, we need type ignore
111
+ grad_outputs: dict[CallID, list[tree.Structure]] = defaultdict(list) # type: ignore[name-defined]
98
112
 
99
113
  # grad_outputs stores a list of output grads (corresponding to each consuming op call).
100
114
  # Since the root node is not consumed by any other node, we create a singleton list here.
@@ -212,7 +226,7 @@ class OpResult(Generic[TOutput_co]):
212
226
  graph.add_edge(*edge)
213
227
  add_edges(graph, x)
214
228
 
215
- graph = nx.DiGraph()
229
+ graph = _lazy_import_networkx().DiGraph()
216
230
  graph.add_node(self)
217
231
  add_edges(graph, self)
218
232
 
@@ -251,7 +265,7 @@ class OpResult(Generic[TOutput_co]):
251
265
  """
252
266
  if topological_order:
253
267
  G = self.get_compute_graph()
254
- for node in nx.topological_sort(G):
268
+ for node in _lazy_import_networkx().topological_sort(G):
255
269
  if filter_fn(node):
256
270
  yield node
257
271
 
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.32.1'
32
- __version_tuple__ = version_tuple = (0, 32, 1)
31
+ __version__ = version = '0.33.0.dev0'
32
+ __version_tuple__ = version_tuple = (0, 33, 0, 'dev0')
33
33
 
34
- __commit_id__ = commit_id = 'g961bf8a42'
34
+ __commit_id__ = commit_id = 'g502c50c50'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ldp
3
- Version: 0.32.1
3
+ Version: 0.33.0.dev0
4
4
  Summary: Agent framework for constructing language model agents and training on constructive tasks.
5
5
  Author-email: FutureHouse technical staff <hello@futurehouse.org>
6
6
  License: Apache License
@@ -220,18 +220,15 @@ Requires-Python: >=3.11
220
220
  Description-Content-Type: text/markdown
221
221
  License-File: LICENSE
222
222
  Requires-Dist: aiofiles
223
- Requires-Dist: dm-tree
224
223
  Requires-Dist: fhaviary>=0.20.0
225
224
  Requires-Dist: fhlmi
226
225
  Requires-Dist: httpx
227
- Requires-Dist: networkx[default]~=3.4
228
226
  Requires-Dist: numpy>=1.20
229
227
  Requires-Dist: pydantic~=2.0
230
228
  Requires-Dist: tenacity
231
229
  Requires-Dist: tiktoken
232
230
  Requires-Dist: tqdm
233
231
  Requires-Dist: typing-extensions; python_version <= "3.11"
234
- Requires-Dist: usearch>=2.13
235
232
  Provides-Extra: dev
236
233
  Requires-Dist: fhaviary[xml]>=0.19; extra == "dev"
237
234
  Requires-Dist: fhlmi[dev]; extra == "dev"
@@ -254,6 +251,7 @@ Requires-Dist: pytest-timer[colorama]; extra == "dev"
254
251
  Requires-Dist: pytest-xdist; extra == "dev"
255
252
  Requires-Dist: pytest>=8; extra == "dev"
256
253
  Requires-Dist: refurb>=2; extra == "dev"
254
+ Requires-Dist: usearch>=2.13; extra == "dev"
257
255
  Requires-Dist: vcrpy>=6; extra == "dev"
258
256
  Provides-Extra: monitor
259
257
  Requires-Dist: wandb; extra == "monitor"
@@ -262,6 +260,7 @@ Requires-Dist: accelerate; extra == "nn"
262
260
  Requires-Dist: dask-cuda>=24.8.2; extra == "nn"
263
261
  Requires-Dist: dask-jobqueue; extra == "nn"
264
262
  Requires-Dist: dask[distributed]; extra == "nn"
263
+ Requires-Dist: ldp[scg]; extra == "nn"
265
264
  Requires-Dist: tokenizers>0.20; extra == "nn"
266
265
  Requires-Dist: torch<2.6,>=2.5; extra == "nn"
267
266
  Requires-Dist: transformers<4.51,>=4.46; extra == "nn"
@@ -269,6 +268,9 @@ Requires-Dist: wandb; extra == "nn"
269
268
  Provides-Extra: rich
270
269
  Requires-Dist: rich; extra == "rich"
271
270
  Requires-Dist: tqdm>=4.56; extra == "rich"
271
+ Provides-Extra: scg
272
+ Requires-Dist: dm-tree; extra == "scg"
273
+ Requires-Dist: networkx[default]~=3.4; extra == "scg"
272
274
  Provides-Extra: server
273
275
  Requires-Dist: fastapi>=0.109; extra == "server"
274
276
  Provides-Extra: typing
@@ -465,7 +467,15 @@ which just converts the action constructed by plain python into a node in a comp
465
467
 
466
468
  For more advanced use-cases, LDP features a stochastic computation graph [^2]
467
469
  which enables differentiatiation with respect to agent parameters
468
- (including the weights of the LLM). The example computation graph below illustrates the functionality
470
+ (including the weights of the LLM).
471
+
472
+ You should install the `scg` subpackage to work with it:
473
+
474
+ ```bash
475
+ pip install ldp[scg]
476
+ ```
477
+
478
+ The example computation graph below illustrates the functionality
469
479
 
470
480
  ```py
471
481
  from ldp.graph import FxnOp, LLMCallOp, PromptOp, compute_graph
@@ -152,6 +152,7 @@ tests/test_nn_ops.py
152
152
  tests/test_ops.py
153
153
  tests/test_optimizer.py
154
154
  tests/test_prompts.py
155
+ tests/test_readme.py
155
156
  tests/test_rollouts.py
156
157
  tests/test_runners.py
157
158
  tests/test_shims.py
@@ -1,15 +1,12 @@
1
1
  aiofiles
2
- dm-tree
3
2
  fhaviary>=0.20.0
4
3
  fhlmi
5
4
  httpx
6
- networkx[default]~=3.4
7
5
  numpy>=1.20
8
6
  pydantic~=2.0
9
7
  tenacity
10
8
  tiktoken
11
9
  tqdm
12
- usearch>=2.13
13
10
 
14
11
  [:python_version <= "3.11"]
15
12
  typing-extensions
@@ -36,6 +33,7 @@ pytest-timer[colorama]
36
33
  pytest-xdist
37
34
  pytest>=8
38
35
  refurb>=2
36
+ usearch>=2.13
39
37
  vcrpy>=6
40
38
 
41
39
  [monitor]
@@ -46,6 +44,7 @@ accelerate
46
44
  dask-cuda>=24.8.2
47
45
  dask-jobqueue
48
46
  dask[distributed]
47
+ ldp[scg]
49
48
  tokenizers>0.20
50
49
  torch<2.6,>=2.5
51
50
  transformers<4.51,>=4.46
@@ -55,6 +54,10 @@ wandb
55
54
  rich
56
55
  tqdm>=4.56
57
56
 
57
+ [scg]
58
+ dm-tree
59
+ networkx[default]~=3.4
60
+
58
61
  [server]
59
62
  fastapi>=0.109
60
63