avo 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. avo-0.1.0/.env.example +57 -0
  2. avo-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  3. avo-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +38 -0
  4. avo-0.1.0/.github/workflows/ci.yml +35 -0
  5. avo-0.1.0/.gitignore +233 -0
  6. avo-0.1.0/CHANGELOG.md +49 -0
  7. avo-0.1.0/CODE_OF_CONDUCT.md +29 -0
  8. avo-0.1.0/CONTRIBUTING.md +72 -0
  9. avo-0.1.0/LICENSE +21 -0
  10. avo-0.1.0/Makefile +42 -0
  11. avo-0.1.0/PKG-INFO +504 -0
  12. avo-0.1.0/README.md +445 -0
  13. avo-0.1.0/benchmark/RESULTS.md +40 -0
  14. avo-0.1.0/benchmark/live/README.md +182 -0
  15. avo-0.1.0/benchmark/live/__init__.py +1 -0
  16. avo-0.1.0/benchmark/live/avo_run.py +207 -0
  17. avo-0.1.0/benchmark/live/consent.py +69 -0
  18. avo-0.1.0/benchmark/live/example_output/example_results.json +384 -0
  19. avo-0.1.0/benchmark/live/example_output/normal_completion_comparison.png +0 -0
  20. avo-0.1.0/benchmark/live/example_output/repetition_containment.png +0 -0
  21. avo-0.1.0/benchmark/live/models.py +121 -0
  22. avo-0.1.0/benchmark/live/pricing.py +175 -0
  23. avo-0.1.0/benchmark/live/raw_loop.py +213 -0
  24. avo-0.1.0/benchmark/live/render.py +288 -0
  25. avo-0.1.0/benchmark/live/results/.gitkeep +0 -0
  26. avo-0.1.0/benchmark/live/run_live_benchmark.py +604 -0
  27. avo-0.1.0/benchmark/live/scenarios.py +188 -0
  28. avo-0.1.0/benchmark/live/tests/__init__.py +1 -0
  29. avo-0.1.0/benchmark/live/tests/test_avo_run.py +169 -0
  30. avo-0.1.0/benchmark/live/tests/test_cli.py +452 -0
  31. avo-0.1.0/benchmark/live/tests/test_consent.py +72 -0
  32. avo-0.1.0/benchmark/live/tests/test_example_output.py +104 -0
  33. avo-0.1.0/benchmark/live/tests/test_minimax_provider.py +311 -0
  34. avo-0.1.0/benchmark/live/tests/test_openai_provider.py +225 -0
  35. avo-0.1.0/benchmark/live/tests/test_pricing.py +140 -0
  36. avo-0.1.0/benchmark/live/tests/test_provider_config.py +141 -0
  37. avo-0.1.0/benchmark/live/tests/test_provider_conversion.py +216 -0
  38. avo-0.1.0/benchmark/live/tests/test_raw_loop.py +381 -0
  39. avo-0.1.0/benchmark/live/tests/test_render.py +217 -0
  40. avo-0.1.0/benchmark/live/tests/test_scaffold.py +11 -0
  41. avo-0.1.0/benchmark/live/tests/test_scenarios.py +178 -0
  42. avo-0.1.0/benchmark/run_benchmark.py +449 -0
  43. avo-0.1.0/benchmark/scenarios/__init__.py +5 -0
  44. avo-0.1.0/benchmark/scenarios/catalog.py +69 -0
  45. avo-0.1.0/examples/app_tools_demo.py +75 -0
  46. avo-0.1.0/examples/basic_agent.py +65 -0
  47. avo-0.1.0/examples/live_providers/__init__.py +6 -0
  48. avo-0.1.0/examples/live_providers/common.py +159 -0
  49. avo-0.1.0/examples/live_providers/minimax_provider.py +301 -0
  50. avo-0.1.0/examples/live_providers/openai_provider.py +168 -0
  51. avo-0.1.0/examples/repeated_action.py +60 -0
  52. avo-0.1.0/examples/resume_after_interrupt.py +98 -0
  53. avo-0.1.0/logo.png +0 -0
  54. avo-0.1.0/public/logo.webp +0 -0
  55. avo-0.1.0/pyproject.toml +120 -0
  56. avo-0.1.0/src/avo/__init__.py +53 -0
  57. avo-0.1.0/src/avo/_pytest_plugin.py +58 -0
  58. avo-0.1.0/src/avo/app_tools/__init__.py +14 -0
  59. avo-0.1.0/src/avo/app_tools/approval.py +98 -0
  60. avo-0.1.0/src/avo/app_tools/edit_file.py +130 -0
  61. avo-0.1.0/src/avo/app_tools/file_tools.py +145 -0
  62. avo-0.1.0/src/avo/app_tools/git_status.py +80 -0
  63. avo-0.1.0/src/avo/app_tools/glob_tool.py +96 -0
  64. avo-0.1.0/src/avo/app_tools/grep_tool.py +159 -0
  65. avo-0.1.0/src/avo/app_tools/plan_tasks.py +116 -0
  66. avo-0.1.0/src/avo/app_tools/plan_tool.py +57 -0
  67. avo-0.1.0/src/avo/app_tools/sandbox.py +230 -0
  68. avo-0.1.0/src/avo/app_tools/shell_tool.py +115 -0
  69. avo-0.1.0/src/avo/app_tools/task_tool.py +142 -0
  70. avo-0.1.0/src/avo/app_tools/web_fetch.py +114 -0
  71. avo-0.1.0/src/avo/app_tools/web_search.py +188 -0
  72. avo-0.1.0/src/avo/app_tools/workspace.py +190 -0
  73. avo-0.1.0/src/avo/app_tools/workspace_map.py +69 -0
  74. avo-0.1.0/src/avo/audit.py +186 -0
  75. avo-0.1.0/src/avo/budget.py +99 -0
  76. avo-0.1.0/src/avo/chat.py +566 -0
  77. avo-0.1.0/src/avo/chat_session.py +297 -0
  78. avo-0.1.0/src/avo/chat_setup.py +242 -0
  79. avo-0.1.0/src/avo/chat_shell_rc.py +125 -0
  80. avo-0.1.0/src/avo/checkpoint.py +196 -0
  81. avo-0.1.0/src/avo/cli.py +155 -0
  82. avo-0.1.0/src/avo/compact.py +112 -0
  83. avo-0.1.0/src/avo/concurrency.py +72 -0
  84. avo-0.1.0/src/avo/config.py +142 -0
  85. avo-0.1.0/src/avo/doctor.py +240 -0
  86. avo-0.1.0/src/avo/eval.py +162 -0
  87. avo-0.1.0/src/avo/events.py +128 -0
  88. avo-0.1.0/src/avo/exceptions.py +70 -0
  89. avo-0.1.0/src/avo/hooks.py +179 -0
  90. avo-0.1.0/src/avo/integrations/__init__.py +5 -0
  91. avo-0.1.0/src/avo/integrations/lethe.py +56 -0
  92. avo-0.1.0/src/avo/ledger.py +210 -0
  93. avo-0.1.0/src/avo/mcp.py +321 -0
  94. avo-0.1.0/src/avo/mcp_servers/__init__.py +25 -0
  95. avo-0.1.0/src/avo/mcp_servers/_stdio.py +390 -0
  96. avo-0.1.0/src/avo/mcp_servers/filesystem.py +188 -0
  97. avo-0.1.0/src/avo/mcp_servers/git.py +172 -0
  98. avo-0.1.0/src/avo/mcp_servers/http_fetch.py +89 -0
  99. avo-0.1.0/src/avo/mcp_servers/sqlite.py +186 -0
  100. avo-0.1.0/src/avo/metrics.py +242 -0
  101. avo-0.1.0/src/avo/models.py +219 -0
  102. avo-0.1.0/src/avo/notifications.py +156 -0
  103. avo-0.1.0/src/avo/permissions.py +258 -0
  104. avo-0.1.0/src/avo/planning.py +145 -0
  105. avo-0.1.0/src/avo/plugins.py +110 -0
  106. avo-0.1.0/src/avo/policies.py +55 -0
  107. avo-0.1.0/src/avo/progress.py +102 -0
  108. avo-0.1.0/src/avo/providers/__init__.py +17 -0
  109. avo-0.1.0/src/avo/providers/anthropic.py +290 -0
  110. avo-0.1.0/src/avo/providers/base.py +28 -0
  111. avo-0.1.0/src/avo/providers/fake.py +142 -0
  112. avo-0.1.0/src/avo/providers/http_common.py +160 -0
  113. avo-0.1.0/src/avo/providers/minimax.py +362 -0
  114. avo-0.1.0/src/avo/providers/ollama.py +289 -0
  115. avo-0.1.0/src/avo/providers/openai.py +168 -0
  116. avo-0.1.0/src/avo/providers/openai_compatible.py +175 -0
  117. avo-0.1.0/src/avo/providers/streaming.py +72 -0
  118. avo-0.1.0/src/avo/py.typed +1 -0
  119. avo-0.1.0/src/avo/rate_limit.py +110 -0
  120. avo-0.1.0/src/avo/retry.py +88 -0
  121. avo-0.1.0/src/avo/runtime.py +446 -0
  122. avo-0.1.0/src/avo/runtime_handlers.py +407 -0
  123. avo-0.1.0/src/avo/runtime_persistence.py +318 -0
  124. avo-0.1.0/src/avo/schemas.py +97 -0
  125. avo-0.1.0/src/avo/skills.py +92 -0
  126. avo-0.1.0/src/avo/snapshot.py +83 -0
  127. avo-0.1.0/src/avo/state.py +184 -0
  128. avo-0.1.0/src/avo/storage/__init__.py +7 -0
  129. avo-0.1.0/src/avo/storage/base.py +62 -0
  130. avo-0.1.0/src/avo/storage/conversations.py +215 -0
  131. avo-0.1.0/src/avo/storage/memory.py +221 -0
  132. avo-0.1.0/src/avo/storage/sqlite.py +386 -0
  133. avo-0.1.0/src/avo/storage/sqlite_checkpoints.py +99 -0
  134. avo-0.1.0/src/avo/subagent.py +93 -0
  135. avo-0.1.0/src/avo/tools.py +200 -0
  136. avo-0.1.0/src/avo/tracing.py +181 -0
  137. avo-0.1.0/src/avo/usage.py +130 -0
  138. avo-0.1.0/src/avo/workspace/git.py +176 -0
  139. avo-0.1.0/src/avo/workspace/indexer.py +128 -0
  140. avo-0.1.0/tests/__init__.py +1 -0
  141. avo-0.1.0/tests/fixtures/fake_mcp_server.py +88 -0
  142. avo-0.1.0/tests/helpers.py +67 -0
  143. avo-0.1.0/tests/integration/__init__.py +33 -0
  144. avo-0.1.0/tests/integration/conftest.py +195 -0
  145. avo-0.1.0/tests/integration/probe_minimax.py +112 -0
  146. avo-0.1.0/tests/integration/test_anthropic_live.py +93 -0
  147. avo-0.1.0/tests/integration/test_minimax_live.py +216 -0
  148. avo-0.1.0/tests/integration/test_ollama_live.py +107 -0
  149. avo-0.1.0/tests/integration/test_openai_live.py +109 -0
  150. avo-0.1.0/tests/test_approval.py +94 -0
  151. avo-0.1.0/tests/test_audit.py +275 -0
  152. avo-0.1.0/tests/test_budget.py +133 -0
  153. avo-0.1.0/tests/test_chat_persistence.py +228 -0
  154. avo-0.1.0/tests/test_chat_repl.py +678 -0
  155. avo-0.1.0/tests/test_chat_session.py +678 -0
  156. avo-0.1.0/tests/test_chat_setup.py +501 -0
  157. avo-0.1.0/tests/test_checkpoint.py +144 -0
  158. avo-0.1.0/tests/test_cli.py +77 -0
  159. avo-0.1.0/tests/test_compact.py +120 -0
  160. avo-0.1.0/tests/test_concurrency.py +109 -0
  161. avo-0.1.0/tests/test_config.py +172 -0
  162. avo-0.1.0/tests/test_conversations.py +93 -0
  163. avo-0.1.0/tests/test_doctor.py +138 -0
  164. avo-0.1.0/tests/test_edit_file.py +123 -0
  165. avo-0.1.0/tests/test_eval.py +153 -0
  166. avo-0.1.0/tests/test_event_invariants.py +234 -0
  167. avo-0.1.0/tests/test_fake_provider.py +135 -0
  168. avo-0.1.0/tests/test_file_tools.py +184 -0
  169. avo-0.1.0/tests/test_git_repo.py +124 -0
  170. avo-0.1.0/tests/test_git_status_tool.py +87 -0
  171. avo-0.1.0/tests/test_glob.py +88 -0
  172. avo-0.1.0/tests/test_grep.py +118 -0
  173. avo-0.1.0/tests/test_hooks.py +198 -0
  174. avo-0.1.0/tests/test_ledger.py +200 -0
  175. avo-0.1.0/tests/test_lethe_integration.py +42 -0
  176. avo-0.1.0/tests/test_mcp.py +78 -0
  177. avo-0.1.0/tests/test_mcp_servers.py +229 -0
  178. avo-0.1.0/tests/test_metrics.py +145 -0
  179. avo-0.1.0/tests/test_models.py +79 -0
  180. avo-0.1.0/tests/test_notifications.py +135 -0
  181. avo-0.1.0/tests/test_permissions.py +274 -0
  182. avo-0.1.0/tests/test_plan_tasks_tool.py +76 -0
  183. avo-0.1.0/tests/test_planning.py +116 -0
  184. avo-0.1.0/tests/test_plugins.py +181 -0
  185. avo-0.1.0/tests/test_policies.py +118 -0
  186. avo-0.1.0/tests/test_progress_detection.py +103 -0
  187. avo-0.1.0/tests/test_providers_http.py +420 -0
  188. avo-0.1.0/tests/test_rate_limit.py +91 -0
  189. avo-0.1.0/tests/test_resume.py +291 -0
  190. avo-0.1.0/tests/test_retry.py +168 -0
  191. avo-0.1.0/tests/test_runtime.py +410 -0
  192. avo-0.1.0/tests/test_sandbox.py +232 -0
  193. avo-0.1.0/tests/test_schemas.py +160 -0
  194. avo-0.1.0/tests/test_skills.py +78 -0
  195. avo-0.1.0/tests/test_snapshot.py +107 -0
  196. avo-0.1.0/tests/test_sqlite_parity.py +319 -0
  197. avo-0.1.0/tests/test_streaming.py +79 -0
  198. avo-0.1.0/tests/test_subagent.py +128 -0
  199. avo-0.1.0/tests/test_task_tool.py +132 -0
  200. avo-0.1.0/tests/test_tools.py +82 -0
  201. avo-0.1.0/tests/test_tracing.py +84 -0
  202. avo-0.1.0/tests/test_usage.py +115 -0
  203. avo-0.1.0/tests/test_web_fetch.py +144 -0
  204. avo-0.1.0/tests/test_web_search.py +121 -0
  205. avo-0.1.0/tests/test_workspace.py +279 -0
  206. avo-0.1.0/tests/test_workspace_indexer.py +113 -0
avo-0.1.0/.env.example ADDED
@@ -0,0 +1,57 @@
1
+ # Avo provider configuration
2
+ #
3
+ # Copy this file to `.env` (which is git-ignored) and fill in only the
4
+ # variables that apply to your deployment. Never commit a `.env` file with
5
+ # real API keys.
6
+
7
+ # ---------------------------------------------------------------------------
8
+ # Provider selection (required)
9
+ # ---------------------------------------------------------------------------
10
+
11
+ # ollama | minimax | anthropic | openai
12
+ AVO_PROVIDER=
13
+
14
+ # Default model name for the active provider
15
+ AVO_MODEL=
16
+
17
+ # ---------------------------------------------------------------------------
18
+ # Ollama (local, typically no API key)
19
+ # ---------------------------------------------------------------------------
20
+
21
+ # SOTERIA_OLLAMA_BASE_URL=http://localhost:11434
22
+ # SOTERIA_OLLAMA_MODEL=
23
+ # SOTERIA_OLLAMA_API_KEY=
24
+
25
+ # ---------------------------------------------------------------------------
26
+ # MiniMax
27
+ # ---------------------------------------------------------------------------
28
+
29
+ # SOTERIA_MINIMAX_API_KEY=
30
+ # SOTERIA_MINIMAX_BASE_URL=https://api.minimax.io
31
+ # SOTERIA_MINIMAX_MODEL=
32
+ # SOTERIA_MINIMAX_API_STYLE=anthropic
33
+
34
+ # ---------------------------------------------------------------------------
35
+ # Anthropic
36
+ # ---------------------------------------------------------------------------
37
+
38
+ # SOTERIA_ANTHROPIC_API_KEY=
39
+ # SOTERIA_ANTHROPIC_MODEL=
40
+ # SOTERIA_ANTHROPIC_BASE_URL=https://api.anthropic.com
41
+
42
+ # ---------------------------------------------------------------------------
43
+ # OpenAI (and OpenAI-compatible self-hosted endpoints)
44
+ # ---------------------------------------------------------------------------
45
+
46
+ # SOTERIA_OPENAI_API_KEY=
47
+ # SOTERIA_OPENAI_MODEL=
48
+ # SOTERIA_OPENAI_BASE_URL=https://api.openai.com/v1
49
+
50
+ # ---------------------------------------------------------------------------
51
+ # Runtime overrides (optional)
52
+ # ---------------------------------------------------------------------------
53
+
54
+ # SOTERIA_DATABASE_PATH=
55
+ # SOTERIA_MAX_TOTAL_TOKENS=
56
+ # SOTERIA_MAX_RUNTIME_SECONDS=
57
+ # SOTERIA_REPEATED_ACTION_LIMIT=
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a bug in Avo
4
+ title: "[bug] "
5
+ labels: bug
6
+ ---
7
+
8
+ **Describe the bug**
9
+ A clear description of what happens vs. what you expected.
10
+
11
+ **Reproduction**
12
+ Minimal code or commands that reproduce the issue. Include provider
13
+ (`AVO_PROVIDER`) and model (`AVO_MODEL`) where applicable.
14
+
15
+ **Environment**
16
+ - Avo version (`pip show avo` or `python -c "import avo; print(avo.__version__)"`)
17
+ - Python version
18
+ - Provider (Ollama / MiniMax / Anthropic / OpenAI / OpenAI-compatible)
19
+ - OS
20
+
21
+ **Logs / trace**
22
+ If available, paste a `avo --database avo.db runs inspect RUN_ID`
23
+ trace excerpt.
24
+
25
+ **Notes**
26
+ Anything else that might be relevant (e.g. was a paid model invoked,
27
+ is the bug reproducible on the deterministic `FakeProvider`).
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Pull request
3
+ about: Propose changes to the Avo runtime or its tooling
4
+ title: ""
5
+ labels:---
6
+
7
+ ## Summary
8
+
9
+ <!-- One-paragraph description of what this PR does and why. -->
10
+
11
+ ## Linked issues
12
+
13
+ <!-- Link any issue this closes, e.g. "Closes #42". -->
14
+
15
+ ## Quality gates
16
+
17
+ - [ ] `make lint`
18
+ - [ ] `make format-check`
19
+ - [ ] `make typecheck`
20
+ - [ ] `make test` — 219+ tests passing
21
+ - [ ] No new runtime dependency unless justified in the PR description
22
+ - [ ] Offline tests added for any new public surface
23
+
24
+ ## Provider or state-machine changes
25
+
26
+ If your PR touches `src/avo/providers/` or
27
+ `src/avo/runtime.py`, confirm:
28
+
29
+ - [ ] No change to the public `ModelProvider` Protocol contract
30
+ - [ ] No change to the `STOP_REASONS_BY_STATE` mapping without
31
+ updating `src/avo/state.py` and the README stop-reasons list
32
+ - [ ] No change to event ordering or sequence invariants
33
+
34
+ ## Docs
35
+
36
+ - [ ] README updated if the public API changed
37
+ - [ ] `project.md` updated if a new module was added
38
+ - [ ] `CHANGELOG.md` entry under `[Unreleased]`
@@ -0,0 +1,35 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ quality:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.11", "3.12", "3.13"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ cache: pip
24
+ - name: Install
25
+ run: python -m pip install -e ".[dev]"
26
+ - name: Ruff lint
27
+ run: ruff check .
28
+ - name: Ruff format
29
+ run: ruff format --check .
30
+ - name: Mypy
31
+ run: mypy src/avo
32
+ - name: Tests
33
+ run: pytest
34
+ - name: Build
35
+ run: python -m build
avo-0.1.0/.gitignore ADDED
@@ -0,0 +1,233 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+
141
+ mnesia/
142
+ rabbitmq/
143
+ rabbitmq-data/
144
+
145
+ # ActiveMQ
146
+ activemq-data/
147
+
148
+ # SageMath parsed files
149
+ *.sage.py
150
+
151
+ # Environments
152
+ .env
153
+ .envrc
154
+ .venv
155
+ env/
156
+ venv/
157
+ ENV/
158
+ env.bak/
159
+ venv.bak/
160
+
161
+ # Spyder project settings
162
+ .spyderproject
163
+ .spyproject
164
+
165
+ # Rope project settings
166
+ .ropeproject
167
+
168
+ # mkdocs documentation
169
+ /site
170
+
171
+ # mypy
172
+ .mypy_cache/
173
+ .dmypy.json
174
+ dmypy.json
175
+
176
+ # Pyre type checker
177
+ .pyre/
178
+
179
+ # pytype static type analyzer
180
+ .pytype/
181
+
182
+ # Cython debug symbols
183
+ cython_debug/
184
+
185
+ # PyCharm
186
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
187
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
188
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
189
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
190
+ # .idea/
191
+
192
+ # Abstra
193
+ # Abstra is an AI-powered process automation framework.
194
+ # Ignore directories containing user credentials, local state, and settings.
195
+ # Learn more at https://abstra.io/docs
196
+ .abstra/
197
+
198
+ # Visual Studio Code
199
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
200
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
201
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
202
+ # you could uncomment the following to ignore the entire vscode folder
203
+ # .vscode/
204
+ # Temporary file for partial code execution
205
+ tempCodeRunnerFile.py
206
+
207
+ # Ruff stuff:
208
+ .ruff_cache/
209
+
210
+ # PyPI configuration file
211
+ .pypirc
212
+
213
+ # Marimo
214
+ marimo/_static/
215
+ marimo/_lsp/
216
+ __marimo__/
217
+
218
+ # Streamlit
219
+ .streamlit/secrets.toml
220
+
221
+ # Live benchmark runtime results
222
+ benchmark/live/results/*
223
+ !benchmark/live/results/.gitkeep
224
+
225
+
226
+ .claude/
227
+ .superpowers/
228
+ CLAUDE.md
229
+ project.md
230
+ NEXT-UPDATE.md
231
+ soteria.db
232
+ soteria_loop.db
233
+ *.db
avo-0.1.0/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ All notable changes to Avo are recorded here. Versions follow
4
+ [Semantic Versioning](https://semver.org/). The first public release
5
+ is **0.1.0**.
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+
11
+ - `src/avo/config.py` — single-entry `build_provider_from_env`
12
+ factory that dispatches `AVO_PROVIDER` to the right provider
13
+ config (`ollama`, | `minimax`, | `anthropic`, | `openai`).
14
+ - `src/avo/providers/ollama.py` — native `/api/chat` adapter.
15
+ - `src/avo/providers/anthropic.py` — Messages API adapter
16
+ with `tool_use` block parsing.
17
+ - `src/avo/providers/openai_compatible.py` — OpenAI
18
+ Chat-Completions adapter that also covers self-hosted gateways.
19
+ - `src/avo/providers/minimax.py` — new `from_avo_env`
20
+ constructor alongside the legacy benchmark `from_env` path.
21
+ - `src/avo/app_tools/workspace.py` — `Workspace` class and
22
+ `validate_path` helper. Rejects `..`, absolute escapes, symlink
23
+ leaves, null bytes, and empty strings.
24
+ - `src/avo/app_tools/approval.py` — `build_approval_callback`
25
+ reading `AVO_TOOLS_REQUIRE_APPROVAL`.
26
+ - `src/avo/app_tools/file_tools.py` — `read_file_tool` and
27
+ `write_file_tool` bound through `bind_workspace`.
28
+ - `src/avo/chat.py` — interactive REPL that drives one
29
+ `AgentRuntime.run(...)` invocation per user line. Slash commands:
30
+ `/provider`, / `/inspect RUN_ID`, / `/resume RUN_ID`, / `/quit`.
31
+ - `avo chat` — new CLI subcommand (slice 0.4 of the
32
+ roadmap). Delegates to existing `build_provider_from_env`,
33
+ `Workspace`, `bind_workspace`, file tools, and `SQLiteEventStore`.
34
+ - `.env.example` — empty placeholder template.
35
+ - `examples/app_tools_demo.py` — offline walk-through of the workspace
36
+ + approval tools.
37
+
38
+ ### Quality
39
+
40
+ - 219 offline tests across `tests/` (workspace traversal, approval,
41
+ provider HTTP-mock, resume, state, SQLite parity).
42
+ - mypy strict, ruff lint + format, coverage gate `fail_under = 90`.
43
+
44
+ ## [0.1.0] — 2026-07-20
45
+
46
+ Initial alpha foundation. Provider-agnostic async state machine,
47
+ append-only event history, deterministic `FakeProvider`, SQLite-backed
48
+ event store with resume, stop-reason taxonomy (13 enum values).
49
+ See the README for the user-facing overview.
@@ -0,0 +1,29 @@
1
+ # Code of Conduct
2
+
3
+ Avo contributors are expected to make participation respectful, safe, and
4
+ welcoming.
5
+
6
+ ## Expected behavior
7
+
8
+ - Be considerate, patient, and constructive.
9
+ - Discuss ideas and code without personal attacks.
10
+ - Respect differing experience, identity, background, and viewpoint.
11
+ - Give and receive technical feedback in good faith.
12
+ - Protect private information and report security-sensitive details privately.
13
+
14
+ Harassment, discriminatory language, threats, unwanted sexual attention,
15
+ doxxing, and sustained disruption are not acceptable in project spaces.
16
+
17
+ ## Enforcement
18
+
19
+ Project maintainers may edit or remove contributions and temporarily or
20
+ permanently restrict participation when behavior violates these expectations.
21
+ Enforcement decisions should be proportionate, documented privately, and
22
+ handled with care for affected people.
23
+
24
+ Report conduct concerns to the repository owner through a private channel listed
25
+ on the project profile. Reports will be reviewed as promptly and confidentially
26
+ as practical. Good-faith reporters will not face retaliation.
27
+
28
+ This policy applies to repository discussions, pull requests, community spaces,
29
+ and public interactions made while representing Avo.
@@ -0,0 +1,72 @@
1
+ # Contributing to Avo
2
+
3
+ Avo welcomes focused changes that improve boundedness, observability,
4
+ recovery, or safety without expanding the project into a general agent
5
+ framework.
6
+
7
+ ## Environment setup
8
+
9
+ Use Python 3.11 or newer:
10
+
11
+ ```bash
12
+ python -m venv .venv
13
+ source .venv/bin/activate
14
+ python -m pip install --upgrade pip
15
+ python -m pip install -e ".[dev]"
16
+ ```
17
+
18
+ No API key or network access is needed after development dependencies are
19
+ installed.
20
+
21
+ ## Local checks
22
+
23
+ Run the same gates used by CI:
24
+
25
+ ```bash
26
+ ruff check .
27
+ ruff format --check .
28
+ mypy src/avo
29
+ pytest
30
+ python -m build
31
+ ```
32
+
33
+ To measure core coverage:
34
+
35
+ ```bash
36
+ coverage run -m pytest
37
+ coverage report
38
+ ```
39
+
40
+ Run all offline examples and regenerate the benchmark when runtime behavior
41
+ changes:
42
+
43
+ ```bash
44
+ python examples/basic_agent.py
45
+ python examples/repeated_action.py
46
+ python examples/resume_after_interrupt.py
47
+ python benchmark/run_benchmark.py
48
+ ```
49
+
50
+ ## Contribution workflow
51
+
52
+ 1. Open an issue for substantial API or event-schema changes.
53
+ 2. Create a focused branch and keep commits reviewable.
54
+ 3. Preserve append-only history, state validation, and terminal-event
55
+ invariants.
56
+ 4. Add deterministic behavioral tests for every behavior change or bug fix.
57
+ 5. Update `README.md`, `DESIGN.md`, examples, and benchmark results
58
+ when user-visible contracts change.
59
+ 6. Run every local check before opening a pull request.
60
+
61
+ Avoid real API calls in the default test suite. Error messages should name the
62
+ run, tool, provider operation, or database involved and explain what the user
63
+ can do next.
64
+
65
+ ## Pull requests
66
+
67
+ Describe the execution behavior before and after the change, the failure modes
68
+ considered, and the checks run. If the change affects persistence or resume,
69
+ include a close/reopen test and a failure-injection test at the relevant
70
+ checkpoint boundary.
71
+
72
+ By participating, you agree to follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
avo-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FaqihHakim
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
avo-0.1.0/Makefile ADDED
@@ -0,0 +1,42 @@
1
+ .PHONY: install dev lint format typecheck test test-app-tools benchmark clean build
2
+
3
+ PYTHON ?= python
4
+
5
+ install:
6
+ $(PYTHON) -m pip install -e .
7
+
8
+ dev:
9
+ $(PYTHON) -m pip install -e ".[dev]"
10
+
11
+ lint:
12
+ $(PYTHON) -m ruff check .
13
+
14
+ format:
15
+ $(PYTHON) -m ruff format .
16
+
17
+ format-check:
18
+ $(PYTHON) -m ruff format --check .
19
+
20
+ typecheck:
21
+ $(PYTHON) -m mypy src/soteria_loop
22
+
23
+ test:
24
+ $(PYTHON) -m pytest
25
+
26
+ test-app-tools:
27
+ $(PYTHON) -m pytest tests/test_workspace.py tests/test_approval.py tests/test_file_tools.py -v
28
+
29
+ benchmark:
30
+ $(PYTHON) benchmark/run_benchmark.py
31
+
32
+ build:
33
+ $(PYTHON) -m build
34
+
35
+ clean:
36
+ rm -rf build dist *.egg-info src/*.egg-info
37
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
38
+ find . -type d -name .pytest_cache -exec rm -rf {} + 2>/dev/null || true
39
+ find . -type d -name .mypy_cache -exec rm -rf {} + 2>/dev/null || true
40
+ find . -type d -name .ruff_cache -exec rm -rf {} + 2>/dev/null || true
41
+
42
+ all-gates: lint format-check typecheck test