agentino-framework 1.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 (170) hide show
  1. agentino_framework-1.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +40 -0
  2. agentino_framework-1.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. agentino_framework-1.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +23 -0
  4. agentino_framework-1.1.0/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  5. agentino_framework-1.1.0/.github/workflows/ci.yml +55 -0
  6. agentino_framework-1.1.0/.github/workflows/release.yml +52 -0
  7. agentino_framework-1.1.0/.gitignore +18 -0
  8. agentino_framework-1.1.0/CHANGELOG.md +97 -0
  9. agentino_framework-1.1.0/CLAUDE.md +75 -0
  10. agentino_framework-1.1.0/CODE_OF_CONDUCT.md +42 -0
  11. agentino_framework-1.1.0/CONTRIBUTING.md +55 -0
  12. agentino_framework-1.1.0/DESIGN.md +209 -0
  13. agentino_framework-1.1.0/LICENSE +202 -0
  14. agentino_framework-1.1.0/NOTICE +16 -0
  15. agentino_framework-1.1.0/PKG-INFO +327 -0
  16. agentino_framework-1.1.0/README.md +239 -0
  17. agentino_framework-1.1.0/SECURITY.md +42 -0
  18. agentino_framework-1.1.0/docs/API_EXAMPLES.md +424 -0
  19. agentino_framework-1.1.0/docs/architecture/ADR-001-async-first.md +72 -0
  20. agentino_framework-1.1.0/docs/architecture/ADR-002-tool-execution-chain.md +110 -0
  21. agentino_framework-1.1.0/docs/architecture/ADR-003-yaml-configuration.md +67 -0
  22. agentino_framework-1.1.0/docs/architecture/ADR-004-jsonl-sessions.md +80 -0
  23. agentino_framework-1.1.0/docs/architecture/README.md +41 -0
  24. agentino_framework-1.1.0/docs/cookbook/hooks.md +136 -0
  25. agentino_framework-1.1.0/docs/cookbook/typed-tool-guards.md +122 -0
  26. agentino_framework-1.1.0/docs/integration-guide.md +341 -0
  27. agentino_framework-1.1.0/examples/booking_bot.py +91 -0
  28. agentino_framework-1.1.0/examples/ci_monitor/agents.yml +38 -0
  29. agentino_framework-1.1.0/examples/code_review/agents.yml +6 -0
  30. agentino_framework-1.1.0/examples/code_review/prompts/reviewer.md +18 -0
  31. agentino_framework-1.1.0/examples/hello.py +35 -0
  32. agentino_framework-1.1.0/pyproject.toml +88 -0
  33. agentino_framework-1.1.0/scripts/check_file_sizes.sh +22 -0
  34. agentino_framework-1.1.0/src/agentino/__init__.py +175 -0
  35. agentino_framework-1.1.0/src/agentino/__main__.py +502 -0
  36. agentino_framework-1.1.0/src/agentino/builtin_tools.py +561 -0
  37. agentino_framework-1.1.0/src/agentino/cli/__init__.py +0 -0
  38. agentino_framework-1.1.0/src/agentino/cli/json_emitter.py +130 -0
  39. agentino_framework-1.1.0/src/agentino/cli/renderer.py +390 -0
  40. agentino_framework-1.1.0/src/agentino/config/__init__.py +182 -0
  41. agentino_framework-1.1.0/src/agentino/config/agents_yaml.py +399 -0
  42. agentino_framework-1.1.0/src/agentino/config/pipeline_yaml.py +95 -0
  43. agentino_framework-1.1.0/src/agentino/config/tools_yaml.py +192 -0
  44. agentino_framework-1.1.0/src/agentino/config/utils.py +49 -0
  45. agentino_framework-1.1.0/src/agentino/core/__init__.py +0 -0
  46. agentino_framework-1.1.0/src/agentino/core/agent.py +738 -0
  47. agentino_framework-1.1.0/src/agentino/core/context.py +58 -0
  48. agentino_framework-1.1.0/src/agentino/core/extensions.py +226 -0
  49. agentino_framework-1.1.0/src/agentino/core/llm.py +589 -0
  50. agentino_framework-1.1.0/src/agentino/core/message.py +177 -0
  51. agentino_framework-1.1.0/src/agentino/core/models.py +203 -0
  52. agentino_framework-1.1.0/src/agentino/core/runner.py +549 -0
  53. agentino_framework-1.1.0/src/agentino/core/session.py +109 -0
  54. agentino_framework-1.1.0/src/agentino/core/state.py +120 -0
  55. agentino_framework-1.1.0/src/agentino/core/tool.py +317 -0
  56. agentino_framework-1.1.0/src/agentino/extras/__init__.py +0 -0
  57. agentino_framework-1.1.0/src/agentino/extras/audio.py +221 -0
  58. agentino_framework-1.1.0/src/agentino/extras/audit.py +109 -0
  59. agentino_framework-1.1.0/src/agentino/extras/knowledge.py +641 -0
  60. agentino_framework-1.1.0/src/agentino/extras/memory.py +173 -0
  61. agentino_framework-1.1.0/src/agentino/extras/skills.py +152 -0
  62. agentino_framework-1.1.0/src/agentino/extras/usage.py +243 -0
  63. agentino_framework-1.1.0/src/agentino/pipeline/__init__.py +27 -0
  64. agentino_framework-1.1.0/src/agentino/pipeline/core.py +179 -0
  65. agentino_framework-1.1.0/src/agentino/pipeline/staged.py +598 -0
  66. agentino_framework-1.1.0/src/agentino/providers/__init__.py +0 -0
  67. agentino_framework-1.1.0/src/agentino/providers/anthropic.py +112 -0
  68. agentino_framework-1.1.0/src/agentino/providers/codex.py +228 -0
  69. agentino_framework-1.1.0/src/agentino/py.typed +0 -0
  70. agentino_framework-1.1.0/src/agentino/reliability/__init__.py +0 -0
  71. agentino_framework-1.1.0/src/agentino/reliability/compaction.py +147 -0
  72. agentino_framework-1.1.0/src/agentino/reliability/errors.py +312 -0
  73. agentino_framework-1.1.0/src/agentino/reliability/resilience.py +242 -0
  74. agentino_framework-1.1.0/src/agentino/safety/__init__.py +0 -0
  75. agentino_framework-1.1.0/src/agentino/safety/auth.py +403 -0
  76. agentino_framework-1.1.0/src/agentino/safety/gates.py +86 -0
  77. agentino_framework-1.1.0/src/agentino/safety/hooks.py +256 -0
  78. agentino_framework-1.1.0/src/agentino/safety/sanitize.py +95 -0
  79. agentino_framework-1.1.0/src/agentino/safety/security.py +152 -0
  80. agentino_framework-1.1.0/src/agentino/scheduler/README.md +63 -0
  81. agentino_framework-1.1.0/src/agentino/scheduler/__init__.py +71 -0
  82. agentino_framework-1.1.0/src/agentino/scheduler/core.py +430 -0
  83. agentino_framework-1.1.0/src/agentino/scheduler/delivery.py +100 -0
  84. agentino_framework-1.1.0/src/agentino/scheduler/executor.py +68 -0
  85. agentino_framework-1.1.0/src/agentino/scheduler/file_store.py +183 -0
  86. agentino_framework-1.1.0/src/agentino/scheduler/picker.py +51 -0
  87. agentino_framework-1.1.0/src/agentino/scheduler/sqlite_store.py +112 -0
  88. agentino_framework-1.1.0/src/agentino/scheduler/store.py +84 -0
  89. agentino_framework-1.1.0/src/agentino/tools/__init__.py +6 -0
  90. agentino_framework-1.1.0/src/agentino/tools/std/__init__.py +108 -0
  91. agentino_framework-1.1.0/src/agentino/tools/std/_agent_memory.py +423 -0
  92. agentino_framework-1.1.0/src/agentino/tools/std/_file_storage.py +160 -0
  93. agentino_framework-1.1.0/src/agentino/tools/std/_llm_env.py +32 -0
  94. agentino_framework-1.1.0/src/agentino/tools/std/_pdf.py +107 -0
  95. agentino_framework-1.1.0/src/agentino/tools/std/_weather.py +264 -0
  96. agentino_framework-1.1.0/src/agentino/tools/std/_web_search.py +17 -0
  97. agentino_framework-1.1.0/src/agentino/tools/std/create_csv.py +54 -0
  98. agentino_framework-1.1.0/src/agentino/tools/std/create_document.py +236 -0
  99. agentino_framework-1.1.0/src/agentino/tools/std/create_pdf.py +180 -0
  100. agentino_framework-1.1.0/src/agentino/tools/std/create_presentation.py +141 -0
  101. agentino_framework-1.1.0/src/agentino/tools/std/create_spreadsheet.py +135 -0
  102. agentino_framework-1.1.0/src/agentino/tools/std/fetch_web_data.py +201 -0
  103. agentino_framework-1.1.0/src/agentino/tools/std/forget.py +25 -0
  104. agentino_framework-1.1.0/src/agentino/tools/std/get_weather.py +69 -0
  105. agentino_framework-1.1.0/src/agentino/tools/std/get_weather_forecast.py +71 -0
  106. agentino_framework-1.1.0/src/agentino/tools/std/list_files.py +52 -0
  107. agentino_framework-1.1.0/src/agentino/tools/std/read_file.py +217 -0
  108. agentino_framework-1.1.0/src/agentino/tools/std/read_memory.py +34 -0
  109. agentino_framework-1.1.0/src/agentino/tools/std/read_rss.py +68 -0
  110. agentino_framework-1.1.0/src/agentino/tools/std/remember.py +42 -0
  111. agentino_framework-1.1.0/src/agentino/tools/std/storage.py +145 -0
  112. agentino_framework-1.1.0/src/agentino/tools/std/translate_text.py +178 -0
  113. agentino_framework-1.1.0/src/agentino/tools/std/update_memory.py +30 -0
  114. agentino_framework-1.1.0/src/agentino/transport/__init__.py +21 -0
  115. agentino_framework-1.1.0/src/agentino/transport/channel.py +236 -0
  116. agentino_framework-1.1.0/src/agentino/transport/gateway.py +291 -0
  117. agentino_framework-1.1.0/src/agentino/transport/slack.py +264 -0
  118. agentino_framework-1.1.0/src/agentino/transport/telegram.py +267 -0
  119. agentino_framework-1.1.0/src/agentino/transport/webhook.py +77 -0
  120. agentino_framework-1.1.0/src/agentino/transport/websocket.py +360 -0
  121. agentino_framework-1.1.0/src/agentino/transport/whatsapp-bridge/bridge.js +306 -0
  122. agentino_framework-1.1.0/src/agentino/transport/whatsapp-bridge/package.json +17 -0
  123. agentino_framework-1.1.0/src/agentino/transport/whatsapp.py +188 -0
  124. agentino_framework-1.1.0/src/agentino/workers/__init__.py +18 -0
  125. agentino_framework-1.1.0/src/agentino/workers/coordinator.py +320 -0
  126. agentino_framework-1.1.0/src/agentino/workers/fork.py +204 -0
  127. agentino_framework-1.1.0/src/agentino/workers/spawn.py +222 -0
  128. agentino_framework-1.1.0/tests/test_agent.py +260 -0
  129. agentino_framework-1.1.0/tests/test_anthropic.py +199 -0
  130. agentino_framework-1.1.0/tests/test_auth.py +164 -0
  131. agentino_framework-1.1.0/tests/test_builtin_safety.py +202 -0
  132. agentino_framework-1.1.0/tests/test_cli.py +74 -0
  133. agentino_framework-1.1.0/tests/test_cli_json_emitter.py +479 -0
  134. agentino_framework-1.1.0/tests/test_config.py +496 -0
  135. agentino_framework-1.1.0/tests/test_context.py +122 -0
  136. agentino_framework-1.1.0/tests/test_docs_stay_true.py +161 -0
  137. agentino_framework-1.1.0/tests/test_edit_improvements.py +200 -0
  138. agentino_framework-1.1.0/tests/test_extensions.py +221 -0
  139. agentino_framework-1.1.0/tests/test_file_storage_provider.py +95 -0
  140. agentino_framework-1.1.0/tests/test_gates.py +127 -0
  141. agentino_framework-1.1.0/tests/test_gateway.py +471 -0
  142. agentino_framework-1.1.0/tests/test_hooks.py +309 -0
  143. agentino_framework-1.1.0/tests/test_integration.py +428 -0
  144. agentino_framework-1.1.0/tests/test_knowledge.py +316 -0
  145. agentino_framework-1.1.0/tests/test_llm.py +344 -0
  146. agentino_framework-1.1.0/tests/test_llm_lifecycle.py +99 -0
  147. agentino_framework-1.1.0/tests/test_llm_stream.py +430 -0
  148. agentino_framework-1.1.0/tests/test_message.py +55 -0
  149. agentino_framework-1.1.0/tests/test_models.py +116 -0
  150. agentino_framework-1.1.0/tests/test_new_modules.py +303 -0
  151. agentino_framework-1.1.0/tests/test_pipeline.py +233 -0
  152. agentino_framework-1.1.0/tests/test_project_knowledge.py +196 -0
  153. agentino_framework-1.1.0/tests/test_resilience.py +317 -0
  154. agentino_framework-1.1.0/tests/test_response_nudges.py +61 -0
  155. agentino_framework-1.1.0/tests/test_runner.py +141 -0
  156. agentino_framework-1.1.0/tests/test_sanitize.py +64 -0
  157. agentino_framework-1.1.0/tests/test_scheduler_stores.py +134 -0
  158. agentino_framework-1.1.0/tests/test_session.py +131 -0
  159. agentino_framework-1.1.0/tests/test_smoke.py +208 -0
  160. agentino_framework-1.1.0/tests/test_spawn.py +255 -0
  161. agentino_framework-1.1.0/tests/test_staged.py +649 -0
  162. agentino_framework-1.1.0/tests/test_staged_jumps.py +265 -0
  163. agentino_framework-1.1.0/tests/test_std_tools_storage_contract.py +41 -0
  164. agentino_framework-1.1.0/tests/test_tool.py +189 -0
  165. agentino_framework-1.1.0/tests/test_tool_chain.py +295 -0
  166. agentino_framework-1.1.0/tests/test_tool_timeout.py +167 -0
  167. agentino_framework-1.1.0/tests/test_typed_tool_guards.py +207 -0
  168. agentino_framework-1.1.0/tests/test_usage.py +159 -0
  169. agentino_framework-1.1.0/tests/test_webhook.py +66 -0
  170. agentino_framework-1.1.0/tests/test_whatsapp.py +136 -0
@@ -0,0 +1,40 @@
1
+ name: Bug report
2
+ description: Something behaves differently from what the docs say
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened
9
+ description: What you did, what you expected, and what you got instead.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: reproduce
14
+ attributes:
15
+ label: Minimal reproduction
16
+ description: >
17
+ The smallest script or config that shows the problem. This is the
18
+ single most useful thing you can include.
19
+ render: python
20
+ validations:
21
+ required: true
22
+ - type: input
23
+ id: version
24
+ attributes:
25
+ label: Version
26
+ description: Release number or commit SHA.
27
+ validations:
28
+ required: true
29
+ - type: input
30
+ id: python
31
+ attributes:
32
+ label: Python version
33
+ placeholder: "3.12.3"
34
+ validations:
35
+ required: true
36
+ - type: textarea
37
+ id: traceback
38
+ attributes:
39
+ label: Traceback or logs
40
+ render: text
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Security vulnerability
4
+ url: https://github.com/islavutin-oss/agentino/security/advisories/new
5
+ about: Report privately, not as a public issue.
@@ -0,0 +1,23 @@
1
+ name: Feature request
2
+ description: Propose a change to what Agentino does
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: The problem
9
+ description: >
10
+ What are you trying to do that is awkward or impossible today?
11
+ Describe the situation, not the solution.
12
+ validations:
13
+ required: true
14
+ - type: textarea
15
+ id: proposal
16
+ attributes:
17
+ label: What you have in mind
18
+ description: If you have an API or config shape in mind, sketch it.
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: What you tried instead
23
+ description: Workarounds you have used, and why they fall short.
@@ -0,0 +1,15 @@
1
+ ## What this changes
2
+
3
+ <!-- One paragraph. What is different after this lands? -->
4
+
5
+ ## Why
6
+
7
+ <!-- The reasoning a reviewer cannot get from the diff. Link the issue if
8
+ there is one. -->
9
+
10
+ ## Checklist
11
+
12
+ - [ ] Tests cover the change, and a bug fix has a test that failed before it
13
+ - [ ] `pytest` passes locally
14
+ - [ ] `ruff check .` and `ruff format --check .` pass
15
+ - [ ] Docs updated if behaviour or configuration changed
@@ -0,0 +1,55 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: ci-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ lint:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+ - run: pip install -e ".[dev]"
24
+ - name: ruff check
25
+ run: ruff check .
26
+ - name: ruff format --check
27
+ run: ruff format --check .
28
+
29
+ test:
30
+ runs-on: ubuntu-latest
31
+ strategy:
32
+ fail-fast: false
33
+ matrix:
34
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: actions/setup-python@v5
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+ - run: pip install -e ".[dev]"
41
+ - name: pytest
42
+ run: pytest tests/ -q
43
+
44
+ build:
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - uses: actions/setup-python@v5
49
+ with:
50
+ python-version: "3.12"
51
+ - run: pip install build twine
52
+ - name: Build the distribution
53
+ run: python -m build
54
+ - name: Check the distribution metadata
55
+ run: twine check dist/*
@@ -0,0 +1,52 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write # to attach build artifacts to the release
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+ - run: pip install build twine
20
+ - run: python -m build
21
+ - run: twine check dist/*
22
+ - uses: actions/upload-artifact@v4
23
+ with:
24
+ name: dist
25
+ path: dist/
26
+ - name: Attach the artifacts to the release
27
+ if: github.event_name == 'release'
28
+ run: gh release upload "$GITHUB_REF_NAME" dist/*
29
+ env:
30
+ GH_TOKEN: ${{ github.token }}
31
+
32
+ # Publishing is a separate job so a build failure never leaves a partial
33
+ # upload, and so the PyPI credential is scoped to this job alone. It uses
34
+ # Trusted Publishing (OIDC) — there is no API token stored in the repo.
35
+ #
36
+ # Before the first run, configure a pending publisher on PyPI:
37
+ # https://pypi.org/manage/account/publishing/
38
+ # owner: <the GitHub owner> repository: agentino
39
+ # workflow: release.yml environment: pypi
40
+ publish:
41
+ needs: build
42
+ if: github.event_name == 'release'
43
+ runs-on: ubuntu-latest
44
+ environment: pypi
45
+ permissions:
46
+ id-token: write # required for Trusted Publishing
47
+ steps:
48
+ - uses: actions/download-artifact@v4
49
+ with:
50
+ name: dist
51
+ path: dist/
52
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,18 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ sessions/
10
+ usage.jsonl
11
+ *.jsonl
12
+ .env
13
+ node_modules/
14
+ package-lock.json
15
+
16
+ # Tooling caches
17
+ .hypothesis/
18
+ .mypy_cache/
@@ -0,0 +1,97 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project aims
5
+ to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html) from 1.0
6
+ onward.
7
+
8
+ ## [1.1.0] — 2026-08-29
9
+
10
+ ### Added
11
+
12
+ - Apache-2.0 licence, `NOTICE`, contribution guide, security policy, code of
13
+ conduct, and issue and pull-request templates.
14
+ - `agentino.tools.std._llm_env`, one vendor-neutral resolver for the LLM
15
+ endpoint used by the standard tools. Configure with `AGENTINO_BASE_URL` /
16
+ `AGENTINO_API_KEY` or the conventional `OPENAI_*` pair.
17
+ - `__all__` on the public packages, so the supported surface is explicit.
18
+ - `gpt-5.4-codex` in the model registry; it is now the default Codex model.
19
+ - `agentino.tools.std.set_pdf_renderer`, plus a plain reportlab renderer, so
20
+ `create_pdf` works in a standalone install. A host with its own house style
21
+ registers a renderer instead; async renderers are awaited.
22
+ - Storage-contract tests for the file-producing standard tools.
23
+ - `agentino.tools.std.set_file_storage_provider`, so a host application can
24
+ supply its own file storage, plus a local-filesystem default
25
+ (`AGENTINO_FILES_DIR`, falling back to `./.agentino/files`) so the
26
+ file-producing tools work with no configuration.
27
+
28
+ - `py.typed`, so a type checker no longer ignores every annotation in the
29
+ package.
30
+ - Tests that check the documentation against the package: every documented
31
+ import resolves, every file path named in prose exists, and a list of names
32
+ that were promised but never existed cannot reappear.
33
+
34
+ ### Changed
35
+
36
+ - Published on PyPI as `agentino-framework`: `pip install agentino-framework`.
37
+ The `agentino` name there belongs to an unrelated project, so the
38
+ distribution carries a second name; the import name is unaffected and
39
+ remains `agentino`. Releases also attach wheels and sdists to the GitHub
40
+ release, and are uploaded by Trusted Publishing rather than a stored token.
41
+ - Licence changed from MIT to Apache-2.0. The repository previously declared
42
+ MIT in metadata with no licence file present.
43
+ - `print_summary` now reports how many stages passed and prints `FAILED`
44
+ rather than `COMPLETE` when any stage failed.
45
+ - CI runs `ruff check` and `ruff format --check`, covers Python 3.10 through
46
+ 3.13, and builds the distribution with a `twine` metadata check.
47
+
48
+ ### Fixed
49
+
50
+ - `builtin_tools` raised `NameError` instead of a readable message when
51
+ `httpx` was missing: the `ImportError` handler called `error_unavailable`
52
+ without importing it.
53
+ - Task notifications dropped the notification body, showing only the
54
+ description.
55
+ - `fetch_web_data` and `translate_text` read different environment variables
56
+ for the same endpoint and defaulted to a hardcoded private host.
57
+ - Four standard tools imported modules belonging to the workspace runtime
58
+ built *on top of* this framework — `protocols` in three, and
59
+ `helpers.documents.branded_pdf` in `create_pdf`. A standalone install
60
+ had no such module, so `read_file`, `list_files` and file creation raised
61
+ ImportError. The dependency is now inverted: the host registers storage.
62
+ - A tenant id of `..` traversed out of the storage root. Path segments that
63
+ are only dots are replaced, not just character-substituted.
64
+
65
+ - `examples/hello.py` and `examples/booking_bot.py` called `agent.run(...)`
66
+ without awaiting it, so both printed a coroutine object and never reached a
67
+ model. The smallest example in the repository did not work.
68
+ - `discover_tools_from_dir` is exported publicly but was annotated `Path` and
69
+ called `.is_dir()` directly, so the natural call with a string raised
70
+ `AttributeError`. Every caller inside the package passed a `Path`, which is
71
+ why it went unnoticed.
72
+ - The transport package documented `pip install agentino[telegram]`, `[slack]`
73
+ and `[serve]`. None of those extras existed, so each of those commands
74
+ failed.
75
+ - The README declared MIT while `LICENSE`, `NOTICE` and `pyproject` all
76
+ declare Apache-2.0 — the one statement that would have mattered to someone
77
+ deciding whether they could use this.
78
+ - The README promised `Runner.run_sync`. There is no synchronous wrapper
79
+ anywhere; the core is async throughout.
80
+ - `LLMClient`'s docstring listed `OPENAI_BASE_URL` as a fallback for the
81
+ endpoint. It is not read at all, so setting it silently did nothing.
82
+ - `SECURITY.md` described the project as pre-1.0 at version 1.1.0, in the
83
+ section a reader consults to learn which releases are patched.
84
+ - The README's layout omitted `tools/`, the built-in tools package.
85
+
86
+ ### Removed
87
+
88
+ - `browse_web` and `crawl_page`. Both imported `helpers.crawler`, a module
89
+ belonging to a host application that has never existed in this package, so
90
+ they returned an error string on every call and no test covered them. The
91
+ `browser` extra goes with them.
92
+ - An internal cross-repository planning document.
93
+ - CI exclusions for two test files whose 30 tests pass.
94
+
95
+ ## [1.1.0] and earlier
96
+
97
+ Released before this changelog was kept. See the git history.
@@ -0,0 +1,75 @@
1
+ # CLAUDE.md — Agentino
2
+
3
+ Notes for coding agents (and humans) working in this repository.
4
+
5
+ ## What this is
6
+
7
+ A lightweight Python agent framework — 88 modules, about 12,000 lines of
8
+ code. An agent is a loop:
9
+ send messages and tool schemas to an LLM; if it calls a tool, run the tool and
10
+ loop; if it returns text, stop. Everything else here is in service of that.
11
+
12
+ ## Setup
13
+
14
+ ```bash
15
+ python -m venv .venv && source .venv/bin/activate
16
+ pip install -e ".[dev]"
17
+ ```
18
+
19
+ ## Commands
20
+
21
+ ```bash
22
+ pytest tests/ -q # the suite CI runs
23
+ ruff check src/ tests/ # lint — must be clean
24
+ ruff format --check src/ tests/ # formatting — must be clean
25
+ python -m build # build the wheel
26
+
27
+ agentino chat # REPL
28
+ agentino run agents.yml # run agents from config
29
+ agentino run agents.yml -m "hi" # one-shot message
30
+ agentino run agents.yml --gateway # multi-channel gateway
31
+ ```
32
+
33
+ ## Layout
34
+
35
+ ```
36
+ src/agentino/
37
+ ├── core/ Agent, Runner, LLMClient, Tool, Message, Context, State, Session
38
+ ├── config/ YAML loaders for agents, pipelines, tools
39
+ ├── pipeline/ Pipeline and StagedPipeline (multi-stage flows with verdicts)
40
+ ├── safety/ GateManager, HookManager, sanitizers
41
+ ├── reliability/ retry and backoff, history compaction, the error taxonomy
42
+ ├── extras/ knowledge base, memory, audio, skills, usage tracking
43
+ ├── providers/ pluggable LLM backends
44
+ ├── scheduler/ CronScheduler and the JobStore protocol
45
+ ├── transport/ outbound channels — Telegram, Slack, WhatsApp, WebSocket
46
+ ├── workers/ fork_agent and make_spawn_tool for multi-agent work
47
+ ├── tools/std/ the standard tool catalogue
48
+ └── cli/ REPL renderer and the JSON event emitter
49
+ ```
50
+
51
+ `from agentino import ...` is the public API and is what `__all__` in
52
+ `src/agentino/__init__.py` declares. Deeper paths such as
53
+ `from agentino.safety.gates import GateManager` are how internal packages talk
54
+ to each other; treat them as unstable.
55
+
56
+ ## Conventions that matter here
57
+
58
+ - **The framework provides mechanisms, not policies.** Anything that encodes
59
+ one application's behaviour — prompt wording, thresholds, a specific tool's
60
+ name, a natural language — belongs to that application, not here. If you
61
+ find yourself adding a rule that only makes sense for one deployment, add a
62
+ seam instead and let config supply the rule.
63
+ - **No hardcoded endpoints or credentials.** Configuration comes from the
64
+ environment; `agentino.tools.std._llm_env` resolves the LLM endpoint and is
65
+ the only place that should know a default host.
66
+ - **Tests come with the change.** A bug fix without a test that fails before
67
+ it is not finished.
68
+ - **Lint is enforced.** CI runs `ruff check` and `ruff format --check`, so a
69
+ formatting argument is never worth having.
70
+
71
+ ## Releasing
72
+
73
+ Version lives in `pyproject.toml`. The distribution is published as
74
+ `agentino-framework` because the `agentino` name on PyPI belongs to an
75
+ unrelated project; the import name is unaffected.
@@ -0,0 +1,42 @@
1
+ # Code of Conduct
2
+
3
+ ## Our pledge
4
+
5
+ We want participation in this project to be a harassment-free experience for
6
+ everyone, whatever their age, body size, disability, ethnicity, sex
7
+ characteristics, gender identity and expression, level of experience,
8
+ education, socio-economic status, nationality, personal appearance, race,
9
+ religion, or sexual identity and orientation.
10
+
11
+ ## Our standards
12
+
13
+ Things that help:
14
+
15
+ - being welcoming and respectful of differing viewpoints
16
+ - accepting constructive criticism gracefully
17
+ - focusing on what is best for the project
18
+ - showing empathy toward other people
19
+
20
+ Things that are not acceptable:
21
+
22
+ - sexualised language or imagery, and unwelcome sexual attention
23
+ - trolling, insults, derogatory comments, and personal or political attacks
24
+ - public or private harassment
25
+ - publishing someone's private information without explicit permission
26
+
27
+ ## Enforcement
28
+
29
+ Report unacceptable behaviour by contacting the maintainer,
30
+ [@islavutin-oss](https://github.com/islavutin-oss), through a GitHub private message
31
+ or a private security advisory on this repository. All reports are reviewed
32
+ and investigated, and will be kept confidential.
33
+
34
+ Maintainers may remove comments, commits, code, issues and other
35
+ contributions that violate this Code of Conduct, and may ban contributors
36
+ temporarily or permanently for behaviour they judge inappropriate,
37
+ threatening, offensive or harmful.
38
+
39
+ ## Attribution
40
+
41
+ Adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
42
+ version 1.4.
@@ -0,0 +1,55 @@
1
+ # Contributing to Agentino
2
+
3
+ Thanks for taking the time. This is a small project, so the process is short.
4
+
5
+ ## Before you start
6
+
7
+ For anything beyond a bug fix or a typo, **open an issue first**. It is much
8
+ less painful to disagree about an approach in an issue than in a finished
9
+ pull request.
10
+
11
+ ## Getting set up
12
+
13
+ ```bash
14
+ git clone https://github.com/islavutin-oss/agentino.git
15
+ cd agentino
16
+ python -m venv .venv && source .venv/bin/activate
17
+ pip install -e ".[dev]"
18
+ ```
19
+
20
+ Run the tests and the linter:
21
+
22
+ ```bash
23
+ pytest tests/ -q
24
+ ruff check .
25
+ ruff format --check .
26
+ ```
27
+
28
+ CI runs exactly these, on Python 3.10 through 3.13.
29
+
30
+ ## What a good pull request looks like
31
+
32
+ - **One change per pull request.** Unrelated fixes bundled together are hard
33
+ to review and harder to revert.
34
+ - **Tests come with the change.** A bug fix should include a test that fails
35
+ before it and passes after.
36
+ - **The suite is green.** Not "green except for a flaky one" — if something
37
+ is flaky, that is worth an issue of its own.
38
+ - **Commit messages say what changed and why.** The subject line is
39
+ imperative and under about 72 characters; the body explains the reasoning
40
+ a reviewer cannot get from the diff.
41
+
42
+ We use [Conventional Commits](https://www.conventionalcommits.org) prefixes:
43
+ `feat:`, `fix:`, `docs:`, `test:`, `refactor:`, `chore:`, `ci:`.
44
+
45
+ ## Style
46
+
47
+ The linter settles formatting arguments, so there is nothing to debate:
48
+ `ruff format` owns line width, `ruff check` owns the rest. Type hints on
49
+ public functions. Comments should explain why something is the way it is —
50
+ the code already says what it does.
51
+
52
+ ## Licensing
53
+
54
+ Contributions are accepted under the [Apache License 2.0](LICENSE), the same
55
+ licence the project ships under. There is no CLA.
@@ -0,0 +1,209 @@
1
+ # Design Document
2
+
3
+ ## Vision
4
+
5
+ Lightweight Python agent framework. YAML config → agents → run.
6
+
7
+ Apache-2.0 licensed. Provider-agnostic. Core deps: httpx + pyyaml.
8
+
9
+ ## Core Principle
10
+
11
+ **An agent is a loop.** Send messages + tools to an LLM. If the LLM calls a tool, execute it and loop. If the LLM returns text, you're done.
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ ┌─────────────────────────────────────────────┐
17
+ │ Layer 4: Transport │
18
+ │ Telegram, Slack, WhatsApp, WebSocket │
19
+ ├─────────────────────────────────────────────┤
20
+ │ Layer 3: Orchestration │
21
+ │ StagedPipeline, RouterPipeline, Parallel │
22
+ ├─────────────────────────────────────────────┤
23
+ │ Layer 2: Persistence │
24
+ │ Session (JSONL), KnowledgeBase (TF-IDF + │
25
+ │ dense embeddings, SQLite cache) │
26
+ ├─────────────────────────────────────────────┤
27
+ │ Layer 1: Core │
28
+ │ Agent, @tool, LLMClient, Config, Events │
29
+ └─────────────────────────────────────────────┘
30
+ ```
31
+
32
+ Each layer independently usable. All layers optional except Core.
33
+
34
+ ## Config-Driven Agents
35
+
36
+ ```yaml
37
+ # agents.yml
38
+ providers:
39
+ router:
40
+ base_url: https://router.example.com/v1
41
+ api_key: ${AGENTINO_API_KEY}
42
+ provider: openai-codex
43
+
44
+ agents:
45
+ coder:
46
+ model: router/gpt-5.4-codex
47
+ soul: ./SOUL.md
48
+ tools_dir: ./tools
49
+ tools: [read_file, write_file, shell, grep, stage_verdict]
50
+ temperature: 0.3
51
+ max_turns: 50
52
+
53
+ gateway:
54
+ slack:
55
+ bot_token: ${SLACK_BOT_TOKEN}
56
+ app_token: ${SLACK_APP_TOKEN}
57
+ agent: coder
58
+ ```
59
+
60
+ `load_config("agents.yml")` auto-detects `stages.yml` → creates StagedPipeline.
61
+
62
+ ## Agent Pattern
63
+
64
+ ```
65
+ my-agent/
66
+ ├── SOUL.md # identity + rules
67
+ ├── agents.yml # model, tools, provider config
68
+ ├── stages.yml # pipeline stages (optional)
69
+ └── tools/ # custom tools (optional)
70
+ ```
71
+
72
+ ## Staged Pipeline
73
+
74
+ Multi-stage execution with deterministic control flow:
75
+
76
+ ```yaml
77
+ # stages.yml
78
+ global_max_cycles: 20
79
+
80
+ stages:
81
+ - name: IMPLEMENT
82
+ prompt: "Implement the plan..."
83
+ verdict_tool: stage_verdict
84
+ repeatable: true
85
+ on_fail: retry
86
+
87
+ - name: TEST
88
+ prompt: "Run tests..."
89
+ verdict_tool: stage_verdict
90
+ repeatable: true
91
+ on_fail: IMPLEMENT # jump back on failure
92
+ ```
93
+
94
+ - `verdict_tool` — structured ACCEPT/REJECT/FAIL signals
95
+ - `repeatable` + `max_cycles` — retry stages
96
+ - `on_fail: "STAGE_NAME"` — jump to named stage (loops)
97
+ - `global_max_cycles` — hard budget
98
+ - Fresh Agent context per stage
99
+ - `on_event` callback for all pipeline events
100
+
101
+ ## Router Pipeline
102
+
103
+ LLM-based intent classification → route to specialist agents:
104
+
105
+ ```yaml
106
+ pipeline:
107
+ type: router
108
+ router: classifier
109
+ routes:
110
+ support: support_agent
111
+ billing: billing_agent
112
+ default: support
113
+ ```
114
+
115
+ ## Message Hook
116
+
117
+ App-level intent routing:
118
+
119
+ ```yaml
120
+ message_hook: my_module # loads my_module.classify_and_route
121
+ ```
122
+
123
+ `async (runner, agent, message, session) -> str | None`
124
+ Return str = reply (skip pipeline). Return None = run pipeline.
125
+
126
+ ## Built-in Tools
127
+
128
+ `shell`, `read_file`, `write_file`, `edit_file`, `list_files`, `grep`, `search_files`, `stage_verdict`
129
+
130
+ Shell timeout: `AGENTINO_SHELL_TIMEOUT` env var (default: no limit).
131
+
132
+ ## Knowledge Base
133
+
134
+ Hybrid TF-IDF + dense embeddings. Auto-indexed from `.agentino/`.
135
+ Tools: `search_knowledge`, `save_knowledge`, `delete_knowledge`.
136
+
137
+ ## Gateway
138
+
139
+ Single process, multiple channels: Telegram, Slack, WhatsApp, WebSocket.
140
+
141
+ ```
142
+ agentino run agents.yml --gateway
143
+ ```
144
+
145
+ ## File Layout
146
+
147
+ ```
148
+ src/agentino/ ~12,000 LOC
149
+ ├── agent.py Core loop + resilience
150
+ ├── tool.py @tool decorator, schema gen
151
+ ├── llm.py OpenAI-compatible client
152
+ ├── config.py YAML loader, auto-detect stages.yml
153
+ ├── staged.py StagedPipeline
154
+ ├── pipeline.py RouterPipeline, sequence, parallel
155
+ ├── runner.py Runner, message_hook, HTTP, REPL
156
+ ├── cli_renderer.py Terminal rendering
157
+ ├── builtin_tools.py shell, read_file, grep, etc.
158
+ ├── knowledge.py Hybrid search KB
159
+ ├── session.py JSONL persistence
160
+ ├── resilience.py Retry, compaction, truncation
161
+ ├── message.py Message, ToolCall, Event
162
+ ├── auth.py Multi-provider auth
163
+ ├── context.py Thread-local context
164
+ ├── spawn.py Subagent spawning
165
+ ├── audio.py STT transcription
166
+ ├── usage.py Token tracking
167
+ └── transport/ Channel adapters
168
+ ├── gateway.py
169
+ ├── telegram.py
170
+ ├── slack.py
171
+ ├── websocket.py
172
+ ├── webhook.py
173
+ └── whatsapp.py
174
+ ```
175
+
176
+ 27 test files. Python >=3.10.
177
+
178
+ ## Dependencies
179
+
180
+ | Install | Adds |
181
+ |---------|------|
182
+ | `pip install agentino` | httpx, pyyaml |
183
+ | `agentino[memory]` | + numpy |
184
+ | `agentino[telegram]` | + aiogram |
185
+ | `agentino[slack]` | + slack-bolt, aiohttp |
186
+ | `agentino[serve]` | + uvicorn, starlette |
187
+ | `agentino[all]` | everything |
188
+
189
+ ## Design Decisions
190
+
191
+ - YAML-only config (see ADR-003)
192
+ - OpenAI-compatible API (Codex, OpenAI, Anthropic, any endpoint)
193
+ - Async-first architecture (see ADR-001)
194
+ - Tool execution chain: validate → permission → execute (see ADR-002)
195
+ - FinalResult for deterministic structured outputs
196
+ - JSONL sessions (see ADR-004)
197
+ - Framework provides mechanisms, not policies — no app logic in core
198
+ - stages.yml = pure pipeline config, app routing via message_hook
199
+
200
+ ## Architecture Decision Records
201
+
202
+ See `docs/architecture/` for detailed ADRs on major design choices:
203
+
204
+ | ADR | Title | Summary |
205
+ |-----|-------|---------|
206
+ | ADR-001 | Async-First | All core APIs are async for concurrent I/O efficiency |
207
+ | ADR-002 | Tool Execution Chain | 3-stage validation → permission → execution pattern |
208
+ | ADR-003 | YAML-Only | Single configuration format for simplicity |
209
+ | ADR-004 | JSONL Sessions | Line-based conversation persistence for git-friendliness |