agentforge-py 0.2.4__tar.gz → 0.3.1__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 (239) hide show
  1. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/.gitignore +10 -0
  2. agentforge_py-0.3.1/PKG-INFO +158 -0
  3. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/pyproject.toml +66 -66
  4. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/__init__.py +9 -1
  5. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/_build.py +59 -7
  6. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/config_cmd.py +9 -0
  7. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/db_cmd.py +1 -1
  8. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/debug_cmd.py +1 -1
  9. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/health_cmd.py +3 -0
  10. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/main.py +1 -1
  11. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/module_cmd.py +52 -4
  12. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/run_cmd.py +28 -3
  13. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/AGENTS.md.tmpl +3 -2
  14. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/13-configure-multi-provider.md +39 -0
  15. agentforge_py-0.3.1/tests/conftest.py +25 -0
  16. agentforge_py-0.3.1/tests/integration/test_add_module_uv_live.py +101 -0
  17. agentforge_py-0.3.1/tests/integration/test_configured_runtime_e2e.py +107 -0
  18. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_build.py +136 -6
  19. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_config.py +56 -0
  20. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_run.py +46 -0
  21. agentforge_py-0.3.1/tests/unit/test_cli_version.py +39 -0
  22. agentforge_py-0.3.1/tests/unit/test_example_swap_smoke.py +35 -0
  23. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_module_cmd.py +85 -0
  24. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_new_cmd.py +1 -1
  25. agentforge_py-0.2.4/PKG-INFO +0 -158
  26. agentforge_py-0.2.4/tests/conftest.py +0 -3
  27. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/LICENSE +0 -0
  28. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/README.md +0 -0
  29. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_testing/__init__.py +0 -0
  30. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_testing/fake_llm.py +0 -0
  31. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_testing/fake_tool.py +0 -0
  32. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_tools/__init__.py +0 -0
  33. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_tools/calculator.py +0 -0
  34. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_tools/decorator.py +0 -0
  35. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_tools/file_read.py +0 -0
  36. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_tools/shell.py +0 -0
  37. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/_tools/web_search.py +0 -0
  38. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/agent.py +0 -0
  39. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/auth.py +0 -0
  40. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/__init__.py +0 -0
  41. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/_scaffold_state.py +0 -0
  42. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/_shared_scaffold.py +0 -0
  43. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/docs_cmd.py +0 -0
  44. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/eval_cmd.py +0 -0
  45. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/list_modules.py +0 -0
  46. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/manifest_apply.py +0 -0
  47. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/new_cmd.py +0 -0
  48. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/cli/upgrade_cmd.py +0 -0
  49. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/config/__init__.py +0 -0
  50. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/eval/__init__.py +0 -0
  51. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/eval/consistency.py +0 -0
  52. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/eval/coverage.py +0 -0
  53. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/eval/format_compliance.py +0 -0
  54. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/eval/regression.py +0 -0
  55. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/findings.py +0 -0
  56. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/guardrails/__init__.py +0 -0
  57. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/guardrails/allowlist.py +0 -0
  58. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/guardrails/capability_check.py +0 -0
  59. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/guardrails/engine.py +0 -0
  60. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/guardrails/pii_redact_basic.py +0 -0
  61. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/guardrails/prompt_injection_basic.py +0 -0
  62. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/memory/__init__.py +0 -0
  63. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/memory/in_memory.py +0 -0
  64. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/memory/in_memory_graph.py +0 -0
  65. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/memory/in_memory_vector.py +0 -0
  66. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/pipeline/__init__.py +0 -0
  67. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/pipeline/engine.py +0 -0
  68. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/pipeline/errors.py +0 -0
  69. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/pipeline/tool.py +0 -0
  70. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/py.typed +0 -0
  71. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/recording.py +0 -0
  72. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/__init__.py +0 -0
  73. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/_defaults.py +0 -0
  74. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/markdown.py +0 -0
  75. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/patch_applier.py +0 -0
  76. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/registry.py +0 -0
  77. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/scorecard.py +0 -0
  78. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/renderers/span_table.py +0 -0
  79. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/replay.py +0 -0
  80. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/resolver_register.py +0 -0
  81. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/retrieval.py +0 -0
  82. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/runtime.py +0 -0
  83. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/__init__.py +0 -0
  84. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/_base.py +0 -0
  85. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/_plan.py +0 -0
  86. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/multi_agent.py +0 -0
  87. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/plan_execute.py +0 -0
  88. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/react.py +0 -0
  89. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/strategies/tot.py +0 -0
  90. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/.cursorrules +0 -0
  91. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/.github/copilot-instructions.md +0 -0
  92. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/.gitkeep +0 -0
  93. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/CLAUDE.md +0 -0
  94. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/01-set-up-new-agent.md.tmpl +0 -0
  95. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/02-add-a-tool.md +0 -0
  96. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/03-add-a-pipeline-task.md +0 -0
  97. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/04-pick-reasoning-strategy.md +0 -0
  98. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/05-write-prompts.md +0 -0
  99. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/06-test-your-agent.md +0 -0
  100. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/07-debug-a-run.md +0 -0
  101. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/08-add-memory.md +0 -0
  102. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/09-add-mcp.md +0 -0
  103. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/10-add-evaluators.md +0 -0
  104. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/11-add-safety-guardrails.md +0 -0
  105. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/12-add-observability.md +0 -0
  106. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/14-deploy-your-agent.md +0 -0
  107. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/15-upgrade-your-agent.md +0 -0
  108. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/16-configuration-reference.md +0 -0
  109. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/17-add-reranker.md +0 -0
  110. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/18-add-hybrid-search.md +0 -0
  111. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/19-add-graphrag.md +0 -0
  112. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/20-apply-schema-migrations.md +0 -0
  113. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/21-use-streaming-guardrails.md +0 -0
  114. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/_shared/docs/runbooks/README.md.tmpl +0 -0
  115. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/.env.example +0 -0
  116. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/.gitignore +0 -0
  117. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/README.md +0 -0
  118. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/agentforge.yaml +0 -0
  119. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/copier.yml +0 -0
  120. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/pyproject.toml +0 -0
  121. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/src/{{project_slug.replace('-', '_')}}/__init__.py +0 -0
  122. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/code-reviewer/src/{{project_slug.replace('-', '_')}}/main.py +0 -0
  123. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/.env.example +0 -0
  124. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/.gitignore +0 -0
  125. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/README.md +0 -0
  126. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/agentforge.yaml +0 -0
  127. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/copier.yml +0 -0
  128. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/pyproject.toml +0 -0
  129. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/src/{{project_slug.replace('-', '_')}}/__init__.py +0 -0
  130. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/docs-qa/src/{{project_slug.replace('-', '_')}}/main.py +0 -0
  131. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/.env.example +0 -0
  132. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/.gitignore +0 -0
  133. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/README.md +0 -0
  134. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/agentforge.yaml +0 -0
  135. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/copier.yml +0 -0
  136. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/pyproject.toml +0 -0
  137. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/src/{{project_slug.replace('-', '_')}}/__init__.py +0 -0
  138. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/minimal/src/{{project_slug.replace('-', '_')}}/main.py +0 -0
  139. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/.env.example +0 -0
  140. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/.gitignore +0 -0
  141. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/README.md +0 -0
  142. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/agentforge.yaml +0 -0
  143. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/copier.yml +0 -0
  144. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/pyproject.toml +0 -0
  145. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/src/{{project_slug.replace('-', '_')}}/__init__.py +0 -0
  146. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/patch-bot/src/{{project_slug.replace('-', '_')}}/main.py +0 -0
  147. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/.env.example +0 -0
  148. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/.gitignore +0 -0
  149. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/README.md +0 -0
  150. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/agentforge.yaml +0 -0
  151. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/copier.yml +0 -0
  152. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/pyproject.toml +0 -0
  153. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/src/{{project_slug.replace('-', '_')}}/__init__.py +0 -0
  154. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/research/src/{{project_slug.replace('-', '_')}}/main.py +0 -0
  155. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/.env.example +0 -0
  156. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/.gitignore +0 -0
  157. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/README.md +0 -0
  158. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/agentforge.yaml +0 -0
  159. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/copier.yml +0 -0
  160. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/pyproject.toml +0 -0
  161. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/src/{{project_slug.replace('-', '_')}}/__init__.py +0 -0
  162. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/templates/triage/src/{{project_slug.replace('-', '_')}}/main.py +0 -0
  163. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/testing/__init__.py +0 -0
  164. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/testing/conformance.py +0 -0
  165. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/testing/factory.py +0 -0
  166. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/testing/fixtures.py +0 -0
  167. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/testing/llm.py +0 -0
  168. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/testing/recording.py +0 -0
  169. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/src/agentforge/tools/__init__.py +0 -0
  170. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/integration/test_web_search_live.py +0 -0
  171. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/.gitkeep +0 -0
  172. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent.py +0 -0
  173. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent_evaluators.py +0 -0
  174. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent_fallback_chain.py +0 -0
  175. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent_graph_store.py +0 -0
  176. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent_hooks.py +0 -0
  177. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent_pipeline.py +0 -0
  178. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_agent_retriever.py +0 -0
  179. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_build_retriever.py +0 -0
  180. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_build_pipeline.py +0 -0
  181. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_db.py +0 -0
  182. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_debug.py +0 -0
  183. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_docs.py +0 -0
  184. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_eval.py +0 -0
  185. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_health.py +0 -0
  186. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_cli_list_modules.py +0 -0
  187. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_config.py +0 -0
  188. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_env_bearer_auth.py +0 -0
  189. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_eval_consistency.py +0 -0
  190. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_eval_coverage.py +0 -0
  191. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_eval_format_compliance.py +0 -0
  192. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_eval_regression.py +0 -0
  193. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_extras_chain.py +0 -0
  194. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_fake_tool.py +0 -0
  195. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_findings.py +0 -0
  196. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_graph_store_properties.py +0 -0
  197. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_guardrails_builtins.py +0 -0
  198. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_guardrails_conformance.py +0 -0
  199. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_guardrails_engine.py +0 -0
  200. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_in_memory_graph_store.py +0 -0
  201. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_in_memory_store.py +0 -0
  202. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_in_memory_vector_store.py +0 -0
  203. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_manifest_apply.py +0 -0
  204. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_multi_agent_stream.py +0 -0
  205. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_pipeline_engine.py +0 -0
  206. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_plan.py +0 -0
  207. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_plan_execute_stream.py +0 -0
  208. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_react_stream.py +0 -0
  209. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_recording.py +0 -0
  210. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_renderer_pipeline_findings.py +0 -0
  211. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_renderer_registry.py +0 -0
  212. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_renderers_builtin.py +0 -0
  213. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_replay.py +0 -0
  214. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_retrieval.py +0 -0
  215. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_retrieval_rerank.py +0 -0
  216. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_retriever_graphrag.py +0 -0
  217. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_retriever_hybrid.py +0 -0
  218. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_runtime.py +0 -0
  219. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_scaffold_state.py +0 -0
  220. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_shared_scaffold.py +0 -0
  221. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_base.py +0 -0
  222. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_budget_properties.py +0 -0
  223. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_dispatch_tool.py +0 -0
  224. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_multi_agent.py +0 -0
  225. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_plan_execute.py +0 -0
  226. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_react.py +0 -0
  227. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_strategies_tot.py +0 -0
  228. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_testing_factory.py +0 -0
  229. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_testing_fake_llm.py +0 -0
  230. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_testing_mock_llm.py +0 -0
  231. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_testing_recording.py +0 -0
  232. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_three_section_format.py +0 -0
  233. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_tool_decorator.py +0 -0
  234. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_tools_calculator.py +0 -0
  235. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_tools_file_read.py +0 -0
  236. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_tools_shell.py +0 -0
  237. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_tools_web_search.py +0 -0
  238. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_tot_stream.py +0 -0
  239. {agentforge_py-0.2.4 → agentforge_py-0.3.1}/tests/unit/test_vector_store_properties.py +0 -0
@@ -47,3 +47,13 @@ Thumbs.db
47
47
  # Project-local
48
48
  *.local
49
49
  .agentforge-state/.session-cache
50
+
51
+ # AI-assistant working state — local session tracking, not part of
52
+ # the published project. The process docs under .claude/ (standards,
53
+ # checklists, CLAUDE.md) are intentionally kept tracked; only the
54
+ # churny per-session state files are ignored.
55
+ .claude/state/
56
+
57
+ # Launch / go-to-market drafts — local-only marketing material,
58
+ # never published to the repo.
59
+ launch/
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentforge-py
3
+ Version: 0.3.1
4
+ Summary: AgentForge — open-source plug-and-play framework for production AI agents
5
+ Project-URL: Homepage, https://github.com/Scaffoldic/agentforge-py
6
+ Project-URL: Repository, https://github.com/Scaffoldic/agentforge-py
7
+ Project-URL: Documentation, https://github.com/Scaffoldic/agentforge-py
8
+ Project-URL: Changelog, https://github.com/Scaffoldic/agentforge-py/blob/main/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/Scaffoldic/agentforge-py/issues
10
+ Author: The AgentForge Authors
11
+ License-Expression: Apache-2.0
12
+ License-File: LICENSE
13
+ Keywords: agent,agentic,ai,framework,llm,react,tools
14
+ Classifier: Development Status :: 2 - Pre-Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.13
23
+ Requires-Dist: agentforge-core~=0.3.1
24
+ Requires-Dist: copier>=9.4
25
+ Requires-Dist: pydantic>=2.10
26
+ Requires-Dist: pyyaml>=6.0
27
+ Requires-Dist: typer>=0.15
28
+ Provides-Extra: a2a
29
+ Requires-Dist: agentforge-a2a~=0.3.1; extra == 'a2a'
30
+ Provides-Extra: all
31
+ Requires-Dist: agentforge-a2a~=0.3.1; extra == 'all'
32
+ Requires-Dist: agentforge-anthropic[anthropic]~=0.3.1; extra == 'all'
33
+ Requires-Dist: agentforge-bedrock~=0.3.1; extra == 'all'
34
+ Requires-Dist: agentforge-chat-history-postgres~=0.3.1; extra == 'all'
35
+ Requires-Dist: agentforge-chat-history-redis~=0.3.1; extra == 'all'
36
+ Requires-Dist: agentforge-chat-http~=0.3.1; extra == 'all'
37
+ Requires-Dist: agentforge-chat-slack~=0.3.1; extra == 'all'
38
+ Requires-Dist: agentforge-chat~=0.3.1; extra == 'all'
39
+ Requires-Dist: agentforge-eval-geval~=0.3.1; extra == 'all'
40
+ Requires-Dist: agentforge-evidently[evidently]~=0.3.1; extra == 'all'
41
+ Requires-Dist: agentforge-guard-llamaguard~=0.3.1; extra == 'all'
42
+ Requires-Dist: agentforge-guard-llmguard~=0.3.1; extra == 'all'
43
+ Requires-Dist: agentforge-guard-nemo~=0.3.1; extra == 'all'
44
+ Requires-Dist: agentforge-guard-presidio~=0.3.1; extra == 'all'
45
+ Requires-Dist: agentforge-langfuse[langfuse]~=0.3.1; extra == 'all'
46
+ Requires-Dist: agentforge-litellm[litellm]~=0.3.1; extra == 'all'
47
+ Requires-Dist: agentforge-mcp[mcp]~=0.3.1; extra == 'all'
48
+ Requires-Dist: agentforge-memory-neo4j~=0.3.1; extra == 'all'
49
+ Requires-Dist: agentforge-memory-postgres~=0.3.1; extra == 'all'
50
+ Requires-Dist: agentforge-memory-sqlite~=0.3.1; extra == 'all'
51
+ Requires-Dist: agentforge-memory-surrealdb~=0.3.1; extra == 'all'
52
+ Requires-Dist: agentforge-ollama[ollama]~=0.3.1; extra == 'all'
53
+ Requires-Dist: agentforge-openai[openai]~=0.3.1; extra == 'all'
54
+ Requires-Dist: agentforge-otel~=0.3.1; extra == 'all'
55
+ Requires-Dist: agentforge-phoenix[phoenix]~=0.3.1; extra == 'all'
56
+ Requires-Dist: agentforge-reranker-cohere[cohere]~=0.3.1; extra == 'all'
57
+ Requires-Dist: agentforge-reranker-mixedbread[mixedbread]~=0.3.1; extra == 'all'
58
+ Requires-Dist: agentforge-reranker-sentence-transformers[sentence-transformers]~=0.3.1; extra == 'all'
59
+ Requires-Dist: agentforge-reranker-voyage[voyage]~=0.3.1; extra == 'all'
60
+ Requires-Dist: agentforge-statsd[statsd]~=0.3.1; extra == 'all'
61
+ Requires-Dist: agentforge-testing~=0.3.1; extra == 'all'
62
+ Requires-Dist: agentforge-voyage[voyage]~=0.3.1; extra == 'all'
63
+ Provides-Extra: anthropic
64
+ Requires-Dist: agentforge-anthropic[anthropic]~=0.3.1; extra == 'anthropic'
65
+ Provides-Extra: bedrock
66
+ Requires-Dist: agentforge-bedrock~=0.3.1; extra == 'bedrock'
67
+ Provides-Extra: chat
68
+ Requires-Dist: agentforge-chat~=0.3.1; extra == 'chat'
69
+ Provides-Extra: chat-history-postgres
70
+ Requires-Dist: agentforge-chat-history-postgres~=0.3.1; extra == 'chat-history-postgres'
71
+ Provides-Extra: chat-history-redis
72
+ Requires-Dist: agentforge-chat-history-redis~=0.3.1; extra == 'chat-history-redis'
73
+ Provides-Extra: chat-http
74
+ Requires-Dist: agentforge-chat-http~=0.3.1; extra == 'chat-http'
75
+ Provides-Extra: chat-slack
76
+ Requires-Dist: agentforge-chat-slack~=0.3.1; extra == 'chat-slack'
77
+ Provides-Extra: eval
78
+ Requires-Dist: agentforge-eval-geval~=0.3.1; extra == 'eval'
79
+ Provides-Extra: evidently
80
+ Requires-Dist: agentforge-evidently[evidently]~=0.3.1; extra == 'evidently'
81
+ Provides-Extra: guard-llamaguard
82
+ Requires-Dist: agentforge-guard-llamaguard~=0.3.1; extra == 'guard-llamaguard'
83
+ Provides-Extra: guard-llmguard
84
+ Requires-Dist: agentforge-guard-llmguard~=0.3.1; extra == 'guard-llmguard'
85
+ Provides-Extra: guard-nemo
86
+ Requires-Dist: agentforge-guard-nemo~=0.3.1; extra == 'guard-nemo'
87
+ Provides-Extra: guard-presidio
88
+ Requires-Dist: agentforge-guard-presidio~=0.3.1; extra == 'guard-presidio'
89
+ Provides-Extra: langfuse
90
+ Requires-Dist: agentforge-langfuse[langfuse]~=0.3.1; extra == 'langfuse'
91
+ Provides-Extra: litellm
92
+ Requires-Dist: agentforge-litellm[litellm]~=0.3.1; extra == 'litellm'
93
+ Provides-Extra: mcp
94
+ Requires-Dist: agentforge-mcp[mcp]~=0.3.1; extra == 'mcp'
95
+ Provides-Extra: memory-neo4j
96
+ Requires-Dist: agentforge-memory-neo4j~=0.3.1; extra == 'memory-neo4j'
97
+ Provides-Extra: memory-postgres
98
+ Requires-Dist: agentforge-memory-postgres~=0.3.1; extra == 'memory-postgres'
99
+ Provides-Extra: memory-sqlite
100
+ Requires-Dist: agentforge-memory-sqlite~=0.3.1; extra == 'memory-sqlite'
101
+ Provides-Extra: memory-surrealdb
102
+ Requires-Dist: agentforge-memory-surrealdb~=0.3.1; extra == 'memory-surrealdb'
103
+ Provides-Extra: ollama
104
+ Requires-Dist: agentforge-ollama[ollama]~=0.3.1; extra == 'ollama'
105
+ Provides-Extra: openai
106
+ Requires-Dist: agentforge-openai[openai]~=0.3.1; extra == 'openai'
107
+ Provides-Extra: otel
108
+ Requires-Dist: agentforge-otel~=0.3.1; extra == 'otel'
109
+ Provides-Extra: phoenix
110
+ Requires-Dist: agentforge-phoenix[phoenix]~=0.3.1; extra == 'phoenix'
111
+ Provides-Extra: reranker-cohere
112
+ Requires-Dist: agentforge-reranker-cohere[cohere]~=0.3.1; extra == 'reranker-cohere'
113
+ Provides-Extra: reranker-mixedbread
114
+ Requires-Dist: agentforge-reranker-mixedbread[mixedbread]~=0.3.1; extra == 'reranker-mixedbread'
115
+ Provides-Extra: reranker-sentence-transformers
116
+ Requires-Dist: agentforge-reranker-sentence-transformers[sentence-transformers]~=0.3.1; extra == 'reranker-sentence-transformers'
117
+ Provides-Extra: reranker-voyage
118
+ Requires-Dist: agentforge-reranker-voyage[voyage]~=0.3.1; extra == 'reranker-voyage'
119
+ Provides-Extra: statsd
120
+ Requires-Dist: agentforge-statsd[statsd]~=0.3.1; extra == 'statsd'
121
+ Provides-Extra: testing
122
+ Requires-Dist: agentforge-testing~=0.3.1; extra == 'testing'
123
+ Provides-Extra: voyage
124
+ Requires-Dist: agentforge-voyage[voyage]~=0.3.1; extra == 'voyage'
125
+ Description-Content-Type: text/markdown
126
+
127
+ # agentforge
128
+
129
+ The default runtime for the AgentForge framework — `Agent`, `ReActLoop`,
130
+ default tools, `SimpleFinding`, in-memory store, basic safety defaults,
131
+ `BudgetPolicy`. Most users install this package and add module extras
132
+ as needed.
133
+
134
+ ## Three-line agent (once feat-001 lands)
135
+
136
+ ```python
137
+ from agentforge import Agent
138
+
139
+ agent = Agent(model="anthropic:claude-sonnet-4.7")
140
+ result = await agent.run("Say hello in three words.")
141
+ ```
142
+
143
+ ## Install
144
+
145
+ ```bash
146
+ pip install agentforge-py # core runtime
147
+ pip install "agentforge-py[anthropic]" # + Anthropic provider
148
+ pip install "agentforge-py[anthropic,memory-postgres]" # + persistence
149
+ ```
150
+
151
+ ## Status
152
+
153
+ v0.0 — pre-alpha. Repo bootstrapped; feat-001 (Core contracts &
154
+ `Agent` orchestrator) is the next milestone.
155
+
156
+ ## License
157
+
158
+ Apache 2.0.
@@ -14,7 +14,7 @@
14
14
 
15
15
  [project]
16
16
  name = "agentforge-py"
17
- version = "0.2.4"
17
+ version = "0.3.1"
18
18
  description = "AgentForge — open-source plug-and-play framework for production AI agents"
19
19
  readme = "README.md"
20
20
  requires-python = ">=3.13"
@@ -36,7 +36,7 @@ classifiers = [
36
36
  ]
37
37
 
38
38
  dependencies = [
39
- "agentforge-core ~= 0.2.4",
39
+ "agentforge-core ~= 0.3.1",
40
40
  "pydantic>=2.10",
41
41
  "pyyaml>=6.0",
42
42
  "typer>=0.15",
@@ -61,94 +61,94 @@ dependencies = [
61
61
  # installs the wrapper but not the SDK and the first call raises a
62
62
  # ModuleError (bug-015). bedrock hard-deps its SDK (aioboto3/botocore),
63
63
  # so it requests no extra — and must NOT request a phantom `[bedrock]`.
64
- anthropic = ["agentforge-anthropic[anthropic] ~= 0.2.4"]
65
- openai = ["agentforge-openai[openai] ~= 0.2.4"]
66
- bedrock = ["agentforge-bedrock ~= 0.2.4"]
67
- ollama = ["agentforge-ollama[ollama] ~= 0.2.4"]
68
- litellm = ["agentforge-litellm[litellm] ~= 0.2.4"]
64
+ anthropic = ["agentforge-anthropic[anthropic] ~= 0.3.1"]
65
+ openai = ["agentforge-openai[openai] ~= 0.3.1"]
66
+ bedrock = ["agentforge-bedrock ~= 0.3.1"]
67
+ ollama = ["agentforge-ollama[ollama] ~= 0.3.1"]
68
+ litellm = ["agentforge-litellm[litellm] ~= 0.3.1"]
69
69
 
70
70
  # Embeddings
71
- voyage = ["agentforge-voyage[voyage] ~= 0.2.4"]
71
+ voyage = ["agentforge-voyage[voyage] ~= 0.3.1"]
72
72
 
73
73
  # Memory backends (each hard-deps its driver SDK — no extra to chain)
74
- memory-sqlite = ["agentforge-memory-sqlite ~= 0.2.4"]
75
- memory-postgres = ["agentforge-memory-postgres ~= 0.2.4"]
76
- memory-neo4j = ["agentforge-memory-neo4j ~= 0.2.4"]
77
- memory-surrealdb = ["agentforge-memory-surrealdb ~= 0.2.4"]
74
+ memory-sqlite = ["agentforge-memory-sqlite ~= 0.3.1"]
75
+ memory-postgres = ["agentforge-memory-postgres ~= 0.3.1"]
76
+ memory-neo4j = ["agentforge-memory-neo4j ~= 0.3.1"]
77
+ memory-surrealdb = ["agentforge-memory-surrealdb ~= 0.3.1"]
78
78
 
79
79
  # Chat surface (chat hard-deps aiosqlite; history backends hard-dep their SDK)
80
- chat = ["agentforge-chat ~= 0.2.4"]
81
- chat-http = ["agentforge-chat-http ~= 0.2.4"]
82
- chat-slack = ["agentforge-chat-slack ~= 0.2.4"]
83
- chat-history-postgres = ["agentforge-chat-history-postgres ~= 0.2.4"]
84
- chat-history-redis = ["agentforge-chat-history-redis ~= 0.2.4"]
80
+ chat = ["agentforge-chat ~= 0.3.1"]
81
+ chat-http = ["agentforge-chat-http ~= 0.3.1"]
82
+ chat-slack = ["agentforge-chat-slack ~= 0.3.1"]
83
+ chat-history-postgres = ["agentforge-chat-history-postgres ~= 0.3.1"]
84
+ chat-history-redis = ["agentforge-chat-history-redis ~= 0.3.1"]
85
85
 
86
86
  # Rerankers
87
- reranker-cohere = ["agentforge-reranker-cohere[cohere] ~= 0.2.4"]
88
- reranker-voyage = ["agentforge-reranker-voyage[voyage] ~= 0.2.4"]
89
- reranker-mixedbread = ["agentforge-reranker-mixedbread[mixedbread] ~= 0.2.4"]
90
- reranker-sentence-transformers = ["agentforge-reranker-sentence-transformers[sentence-transformers] ~= 0.2.4"]
87
+ reranker-cohere = ["agentforge-reranker-cohere[cohere] ~= 0.3.1"]
88
+ reranker-voyage = ["agentforge-reranker-voyage[voyage] ~= 0.3.1"]
89
+ reranker-mixedbread = ["agentforge-reranker-mixedbread[mixedbread] ~= 0.3.1"]
90
+ reranker-sentence-transformers = ["agentforge-reranker-sentence-transformers[sentence-transformers] ~= 0.3.1"]
91
91
 
92
92
  # Guardrails (each hard-deps its SDK — no extra to chain)
93
- guard-llmguard = ["agentforge-guard-llmguard ~= 0.2.4"]
94
- guard-presidio = ["agentforge-guard-presidio ~= 0.2.4"]
95
- guard-nemo = ["agentforge-guard-nemo ~= 0.2.4"]
96
- guard-llamaguard = ["agentforge-guard-llamaguard ~= 0.2.4"]
93
+ guard-llmguard = ["agentforge-guard-llmguard ~= 0.3.1"]
94
+ guard-presidio = ["agentforge-guard-presidio ~= 0.3.1"]
95
+ guard-nemo = ["agentforge-guard-nemo ~= 0.3.1"]
96
+ guard-llamaguard = ["agentforge-guard-llamaguard ~= 0.3.1"]
97
97
 
98
98
  # Observability
99
- langfuse = ["agentforge-langfuse[langfuse] ~= 0.2.4"]
100
- phoenix = ["agentforge-phoenix[phoenix] ~= 0.2.4"]
101
- otel = ["agentforge-otel ~= 0.2.4"]
102
- statsd = ["agentforge-statsd[statsd] ~= 0.2.4"]
103
- evidently = ["agentforge-evidently[evidently] ~= 0.2.4"]
99
+ langfuse = ["agentforge-langfuse[langfuse] ~= 0.3.1"]
100
+ phoenix = ["agentforge-phoenix[phoenix] ~= 0.3.1"]
101
+ otel = ["agentforge-otel ~= 0.3.1"]
102
+ statsd = ["agentforge-statsd[statsd] ~= 0.3.1"]
103
+ evidently = ["agentforge-evidently[evidently] ~= 0.3.1"]
104
104
 
105
105
  # Protocols
106
- mcp = ["agentforge-mcp[mcp] ~= 0.2.4"]
107
- a2a = ["agentforge-a2a ~= 0.2.4"]
106
+ mcp = ["agentforge-mcp[mcp] ~= 0.3.1"]
107
+ a2a = ["agentforge-a2a ~= 0.3.1"]
108
108
 
109
109
  # Eval
110
- eval = ["agentforge-eval-geval ~= 0.2.4"]
110
+ eval = ["agentforge-eval-geval ~= 0.3.1"]
111
111
 
112
112
  # Testing
113
- testing = ["agentforge-testing ~= 0.2.4"]
113
+ testing = ["agentforge-testing ~= 0.3.1"]
114
114
 
115
115
  # Everything (development / docs / smoke-test convenience — not
116
116
  # recommended for production deploys; pick the actual integrations
117
117
  # you use to keep the dependency tree small). Vendor-SDK extras are
118
118
  # chained here too so `[all]` actually installs every SDK.
119
119
  all = [
120
- "agentforge-anthropic[anthropic] ~= 0.2.4",
121
- "agentforge-openai[openai] ~= 0.2.4",
122
- "agentforge-bedrock ~= 0.2.4",
123
- "agentforge-ollama[ollama] ~= 0.2.4",
124
- "agentforge-litellm[litellm] ~= 0.2.4",
125
- "agentforge-voyage[voyage] ~= 0.2.4",
126
- "agentforge-memory-sqlite ~= 0.2.4",
127
- "agentforge-memory-postgres ~= 0.2.4",
128
- "agentforge-memory-neo4j ~= 0.2.4",
129
- "agentforge-memory-surrealdb ~= 0.2.4",
130
- "agentforge-chat ~= 0.2.4",
131
- "agentforge-chat-http ~= 0.2.4",
132
- "agentforge-chat-slack ~= 0.2.4",
133
- "agentforge-chat-history-postgres ~= 0.2.4",
134
- "agentforge-chat-history-redis ~= 0.2.4",
135
- "agentforge-reranker-cohere[cohere] ~= 0.2.4",
136
- "agentforge-reranker-voyage[voyage] ~= 0.2.4",
137
- "agentforge-reranker-mixedbread[mixedbread] ~= 0.2.4",
138
- "agentforge-reranker-sentence-transformers[sentence-transformers] ~= 0.2.4",
139
- "agentforge-guard-llmguard ~= 0.2.4",
140
- "agentforge-guard-presidio ~= 0.2.4",
141
- "agentforge-guard-nemo ~= 0.2.4",
142
- "agentforge-guard-llamaguard ~= 0.2.4",
143
- "agentforge-langfuse[langfuse] ~= 0.2.4",
144
- "agentforge-phoenix[phoenix] ~= 0.2.4",
145
- "agentforge-otel ~= 0.2.4",
146
- "agentforge-statsd[statsd] ~= 0.2.4",
147
- "agentforge-evidently[evidently] ~= 0.2.4",
148
- "agentforge-mcp[mcp] ~= 0.2.4",
149
- "agentforge-a2a ~= 0.2.4",
150
- "agentforge-eval-geval ~= 0.2.4",
151
- "agentforge-testing ~= 0.2.4",
120
+ "agentforge-anthropic[anthropic] ~= 0.3.1",
121
+ "agentforge-openai[openai] ~= 0.3.1",
122
+ "agentforge-bedrock ~= 0.3.1",
123
+ "agentforge-ollama[ollama] ~= 0.3.1",
124
+ "agentforge-litellm[litellm] ~= 0.3.1",
125
+ "agentforge-voyage[voyage] ~= 0.3.1",
126
+ "agentforge-memory-sqlite ~= 0.3.1",
127
+ "agentforge-memory-postgres ~= 0.3.1",
128
+ "agentforge-memory-neo4j ~= 0.3.1",
129
+ "agentforge-memory-surrealdb ~= 0.3.1",
130
+ "agentforge-chat ~= 0.3.1",
131
+ "agentforge-chat-http ~= 0.3.1",
132
+ "agentforge-chat-slack ~= 0.3.1",
133
+ "agentforge-chat-history-postgres ~= 0.3.1",
134
+ "agentforge-chat-history-redis ~= 0.3.1",
135
+ "agentforge-reranker-cohere[cohere] ~= 0.3.1",
136
+ "agentforge-reranker-voyage[voyage] ~= 0.3.1",
137
+ "agentforge-reranker-mixedbread[mixedbread] ~= 0.3.1",
138
+ "agentforge-reranker-sentence-transformers[sentence-transformers] ~= 0.3.1",
139
+ "agentforge-guard-llmguard ~= 0.3.1",
140
+ "agentforge-guard-presidio ~= 0.3.1",
141
+ "agentforge-guard-nemo ~= 0.3.1",
142
+ "agentforge-guard-llamaguard ~= 0.3.1",
143
+ "agentforge-langfuse[langfuse] ~= 0.3.1",
144
+ "agentforge-phoenix[phoenix] ~= 0.3.1",
145
+ "agentforge-otel ~= 0.3.1",
146
+ "agentforge-statsd[statsd] ~= 0.3.1",
147
+ "agentforge-evidently[evidently] ~= 0.3.1",
148
+ "agentforge-mcp[mcp] ~= 0.3.1",
149
+ "agentforge-a2a ~= 0.3.1",
150
+ "agentforge-eval-geval ~= 0.3.1",
151
+ "agentforge-testing ~= 0.3.1",
152
152
  ]
153
153
 
154
154
  [project.scripts]
@@ -19,6 +19,11 @@ the per-feature specs under `docs/features/`.
19
19
 
20
20
  from __future__ import annotations
21
21
 
22
+ # Version is sourced from the installed distribution metadata so it can
23
+ # never drift from pyproject.toml (bug-024).
24
+ from importlib.metadata import PackageNotFoundError as _PkgNotFound
25
+ from importlib.metadata import version as _dist_version
26
+
22
27
  from agentforge_core import FallbackChain
23
28
 
24
29
  # feat-018: importing `agentforge.guardrails` here triggers the
@@ -69,7 +74,10 @@ from agentforge.strategies import (
69
74
  get_runtime,
70
75
  )
71
76
 
72
- __version__ = "0.2.3"
77
+ try:
78
+ __version__ = _dist_version("agentforge-py")
79
+ except _PkgNotFound: # pragma: no cover - source tree without installed metadata
80
+ __version__ = "0.0.0+unknown"
73
81
 
74
82
  __all__ = [
75
83
  "RUNTIME_KEY",
@@ -21,6 +21,7 @@ deterministic exit codes (per feat-017 §4 — config invalid → 2).
21
21
  from __future__ import annotations
22
22
 
23
23
  import contextlib
24
+ import inspect
24
25
  from pathlib import Path
25
26
  from typing import TYPE_CHECKING, Any
26
27
 
@@ -75,7 +76,7 @@ async def build_agent_from_config(
75
76
  Splits out from `load_and_build` for tests + reuse — tests build
76
77
  a `AgentForgeConfig` directly and skip the YAML parse.
77
78
  """
78
- memory = build_memory_from_config(config)
79
+ memory = await build_memory_from_config(config)
79
80
  if memory is not None:
80
81
  await _maybe_init_schema(memory)
81
82
  evaluators = build_evaluators_from_config(config)
@@ -115,12 +116,18 @@ async def build_agent_from_config(
115
116
  raise
116
117
 
117
118
 
118
- def build_memory_from_config(config: AgentForgeConfig) -> MemoryStore | None:
119
- """Resolve + instantiate `modules.memory`. Returns None when absent."""
119
+ async def build_memory_from_config(config: AgentForgeConfig) -> MemoryStore | None:
120
+ """Resolve + instantiate `modules.memory`. Returns None when absent.
121
+
122
+ Async because the real memory backends (sqlite/postgres/neo4j/
123
+ surrealdb) open a connection at construction and expose an async
124
+ `from_config` factory (bug-022). Falls back to the sync
125
+ `_instantiate` path for stores that ship a plain/sync constructor.
126
+ """
120
127
  if config.modules.memory is None:
121
128
  return None
122
129
  cls = _resolve_class("memory", config.modules.memory.driver)
123
- instance = _instantiate(cls, config.modules.memory.config)
130
+ instance = await _ainstantiate_memory(cls, config.modules.memory.config)
124
131
  if not isinstance(instance, MemoryStore):
125
132
  msg = (
126
133
  f"Resolved memory driver {config.modules.memory.driver!r} "
@@ -362,8 +369,12 @@ def _resolve_llm(config: AgentForgeConfig) -> LLMClient | str | None:
362
369
  We hand a string back to `Agent.__init__` when the model is a
363
370
  plain `"<provider>:<model>"` string — `Agent` already knows how
364
371
  to resolve that. When `agent.model` is missing but
365
- `providers["default"]` is present, we synthesize the string from
366
- the named-provider record.
372
+ `providers["default"]` is present, the named-provider record is
373
+ used — and its `config:` block is **passed through to the provider
374
+ constructor** (enh-004): a plain `type:model` string can only carry
375
+ the model id, so provider settings (`region`, `aws_profile`,
376
+ `role_arn`, `timeout_seconds`, …) have to ride the `config` block.
377
+ Without this they were silently dropped.
367
378
  """
368
379
  raw = config.agent.model
369
380
  if isinstance(raw, str):
@@ -371,7 +382,25 @@ def _resolve_llm(config: AgentForgeConfig) -> LLMClient | str | None:
371
382
  default = config.providers.get("default")
372
383
  if default is None or default.model is None:
373
384
  return None
374
- return f"{default.type}:{default.model}"
385
+ if not default.config:
386
+ return f"{default.type}:{default.model}"
387
+ # Construct the provider directly with `model_id` + the `config`
388
+ # kwargs — the same `cls(model_id=...)` contract `Agent` uses to
389
+ # resolve a model string (every provider's __init__ accepts
390
+ # `model_id`), extended with the per-provider settings.
391
+ cls = _resolve_class("providers", default.type)
392
+ try:
393
+ instance = cls(model_id=default.model, **default.config)
394
+ except TypeError as exc:
395
+ msg = (
396
+ f"Provider {default.type!r} ({cls.__name__}) rejected "
397
+ f"providers.default.config keys {sorted(default.config)}: {exc}"
398
+ )
399
+ raise ModuleError(msg) from exc
400
+ if not isinstance(instance, LLMClient):
401
+ msg = f"Resolved provider {default.type!r} ({cls.__name__}) does not implement LLMClient."
402
+ raise ModuleError(msg)
403
+ return instance
375
404
 
376
405
 
377
406
  def _resolve_class(category: str, name: str) -> type:
@@ -402,6 +431,29 @@ def _instantiate(cls: type, cfg: dict[str, Any]) -> Any:
402
431
  return cls(**cfg)
403
432
 
404
433
 
434
+ async def _ainstantiate_memory(cls: type, cfg: dict[str, Any]) -> Any:
435
+ """Async-aware construction for memory stores (bug-022).
436
+
437
+ Memory backends construct asynchronously (they open a connection)
438
+ and expose an awaitable `from_config`. Prefer it; if the resolved
439
+ class only offers a sync constructor (e.g. a test double), fall
440
+ back to the shared sync `_instantiate`.
441
+
442
+ Mirrors `_instantiate`'s keyword-then-positional `from_config`
443
+ shape so externally-shipped stores using either signature load.
444
+ """
445
+ from_config = getattr(cls, "from_config", None)
446
+ if callable(from_config):
447
+ try:
448
+ result = from_config(**cfg)
449
+ except TypeError:
450
+ result = from_config(cfg)
451
+ if inspect.isawaitable(result):
452
+ return await result
453
+ return result
454
+ return cls(**cfg)
455
+
456
+
405
457
  async def _maybe_init_schema(memory: MemoryStore) -> None:
406
458
  init = getattr(memory, "init_schema", None)
407
459
  if callable(init):
@@ -26,6 +26,7 @@ import yaml
26
26
  from agentforge_core.config import (
27
27
  AgentForgeConfig,
28
28
  load_config,
29
+ validate_app_config,
29
30
  validate_module_configs,
30
31
  )
31
32
  from agentforge_core.production.exceptions import ModuleError
@@ -128,6 +129,14 @@ def _run_validate(args: argparse.Namespace) -> int:
128
129
  except ModuleError as exc:
129
130
  sys.stderr.write(f"module config validation failed: {exc}\n")
130
131
  return 1
132
+ # Registered `app.<section>` schemas are always validated strictly
133
+ # (feat-026 Phase 2). Unregistered / not-installed sections are
134
+ # free-form, so `--strict-modules` governs only module resolution.
135
+ try:
136
+ validate_app_config(cfg)
137
+ except ModuleError as exc:
138
+ sys.stderr.write(f"app config validation failed: {exc}\n")
139
+ return 1
131
140
  sys.stdout.write("OK\n")
132
141
  return 0
133
142
 
@@ -83,7 +83,7 @@ async def _dispatch(args: argparse.Namespace) -> int:
83
83
  from agentforge_core.config.loader import load_config # noqa: PLC0415
84
84
 
85
85
  config = load_config(args.path, env=args.env, overrides=list(args.override) or None)
86
- memory = build_memory_from_config(config)
86
+ memory = await build_memory_from_config(config)
87
87
  if memory is None:
88
88
  sys.stderr.write("agentforge db: modules.memory must be configured.\n")
89
89
  return 1
@@ -49,7 +49,7 @@ async def _dispatch(args: argparse.Namespace) -> int:
49
49
  from agentforge_core.config.loader import load_config # noqa: PLC0415
50
50
 
51
51
  config = load_config(args.path, env=args.env, overrides=list(args.override) or None)
52
- memory = build_memory_from_config(config)
52
+ memory = await build_memory_from_config(config)
53
53
  if memory is None:
54
54
  sys.stderr.write("agentforge debug: modules.memory must be configured.\n")
55
55
  return 1
@@ -16,6 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import argparse
18
18
  import asyncio
19
+ import inspect
19
20
  import json
20
21
  import sys
21
22
  from pathlib import Path
@@ -113,6 +114,8 @@ async def _check_backends(config: AgentForgeConfig) -> list[dict[str, Any]]:
113
114
  async def _probe(label: str, factory: Any) -> dict[str, Any]:
114
115
  try:
115
116
  instance = factory()
117
+ if inspect.isawaitable(instance):
118
+ instance = await instance
116
119
  if instance is None:
117
120
  return {"name": label, "kind": "backend", "ok": True, "detail": "none configured"}
118
121
  init = getattr(instance, "init_schema", None)
@@ -72,7 +72,7 @@ def main(argv: Sequence[str] | None = None) -> int:
72
72
  def _resolve_version() -> str:
73
73
  """Return the installed `agentforge` distribution's version."""
74
74
  try:
75
- return version("agentforge")
75
+ return version("agentforge-py")
76
76
  except PackageNotFoundError: # pragma: no cover - unusual at runtime
77
77
  return "0.0.0+unknown"
78
78
 
@@ -5,13 +5,24 @@ PR #16. They edit `agentforge.yaml`, apply per-module manifest
5
5
  files, and shell out to `pip install` / `pip uninstall`.
6
6
 
7
7
  The pip subprocess is injected via the `pip_run` callable so tests
8
- can mock it without actually installing packages. Production uses
9
- `python -m pip` in the active venv.
8
+ can mock it without actually installing packages. Production uses an
9
+ environment-aware default runner (`_default_pip_runner`) that picks
10
+ the right installer for the active environment:
11
+
12
+ 1. **uv-managed project** (a `uv.lock` exists in the cwd or any
13
+ parent): use `uv add` / `uv remove` so the dependency is persisted
14
+ to `pyproject.toml` + `uv.lock` and survives a later `uv sync`.
15
+ 2. **classic venv** (the `pip` module is importable): use
16
+ `python -m pip` so traditional pip-managed environments keep
17
+ working.
18
+ 3. **uv venv that isn't a project** (no `uv.lock`, no `pip` module):
19
+ fall back to `uv pip --python <interpreter>`.
10
20
  """
11
21
 
12
22
  from __future__ import annotations
13
23
 
14
24
  import argparse
25
+ import importlib.util
15
26
  import subprocess # nosec B404
16
27
  import sys
17
28
  from collections.abc import Callable, Sequence
@@ -239,9 +250,46 @@ def _print_next_steps(manifest: Manifest) -> None:
239
250
  sys.stdout.write(f" - {step}\n")
240
251
 
241
252
 
253
+ def _find_uv_lock(start: Path) -> bool:
254
+ """Return True if a `uv.lock` exists in `start` or any parent.
255
+
256
+ Walks from `start` up to the filesystem root. The presence of a
257
+ `uv.lock` is uv's signal that the current directory belongs to a
258
+ uv-managed project, where `uv add` / `uv remove` (which edit
259
+ `pyproject.toml` + `uv.lock`) are the correct install verbs.
260
+ """
261
+ return any((directory / "uv.lock").exists() for directory in (start, *start.parents))
262
+
263
+
242
264
  def _default_pip_runner(args: Sequence[str]) -> int:
243
- """Run `python -m pip <args>` in the active venv."""
244
- cmd = [sys.executable, "-m", "pip", *args]
265
+ """Install/uninstall a distribution using the right tool for the
266
+ active environment.
267
+
268
+ The runner receives pip-style args — `["install", <dist>]` or
269
+ `["uninstall", "-y", <dist>]` — and selects one of three commands:
270
+
271
+ 1. **uv-managed project** (a `uv.lock` is found in the cwd or any
272
+ parent): translate to `uv add <dist>` / `uv remove <dist>`.
273
+ These edit `pyproject.toml` + `uv.lock`, so the dependency is
274
+ persisted and survives a later `uv sync` (plain `uv pip install`
275
+ does not — `uv sync` would uninstall it).
276
+ 2. **classic venv** (the `pip` module is importable): use
277
+ `python -m pip <args>` so traditional pip-managed environments
278
+ keep working.
279
+ 3. **uv venv that isn't a project** (no `uv.lock`, no `pip`
280
+ module): fall back to `uv pip --python <sys.executable> <args>`,
281
+ which installs into the active interpreter without needing a
282
+ `pip` module.
283
+ """
284
+ if _find_uv_lock(Path.cwd()):
285
+ verb = args[0]
286
+ distribution = args[-1]
287
+ uv_verb = "add" if verb == "install" else "remove"
288
+ cmd = ["uv", uv_verb, distribution]
289
+ elif importlib.util.find_spec("pip") is not None:
290
+ cmd = [sys.executable, "-m", "pip", *args]
291
+ else:
292
+ cmd = ["uv", "pip", "--python", sys.executable, *args]
245
293
  # No untrusted input — args is built from CLI arg `distribution`
246
294
  # which is just a distribution name string. shell=False (default).
247
295
  return subprocess.run(cmd, check=False).returncode # noqa: S603 # nosec B603