llmrivotril 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.
- llmrivotril-0.1.0/.github/constraints-ci.txt +10 -0
- llmrivotril-0.1.0/.github/constraints-runtime.txt +25 -0
- llmrivotril-0.1.0/.github/workflows/ci.yml +88 -0
- llmrivotril-0.1.0/.github/workflows/release.yml +44 -0
- llmrivotril-0.1.0/.gitignore +57 -0
- llmrivotril-0.1.0/.pre-commit-config.yaml +14 -0
- llmrivotril-0.1.0/CHANGELOG.md +327 -0
- llmrivotril-0.1.0/CONTRIBUTING.md +65 -0
- llmrivotril-0.1.0/LICENSE +21 -0
- llmrivotril-0.1.0/PKG-INFO +283 -0
- llmrivotril-0.1.0/README.md +170 -0
- llmrivotril-0.1.0/README.pt-BR.md +160 -0
- llmrivotril-0.1.0/docs/configuration.md +112 -0
- llmrivotril-0.1.0/docs/configuration.pt-BR.md +112 -0
- llmrivotril-0.1.0/docs/guardrails-and-safety.md +94 -0
- llmrivotril-0.1.0/docs/guardrails-and-safety.pt-BR.md +101 -0
- llmrivotril-0.1.0/docs/integrations.md +169 -0
- llmrivotril-0.1.0/docs/integrations.pt-BR.md +172 -0
- llmrivotril-0.1.0/docs/observability.md +96 -0
- llmrivotril-0.1.0/docs/observability.pt-BR.md +101 -0
- llmrivotril-0.1.0/docs/providers.md +124 -0
- llmrivotril-0.1.0/docs/providers.pt-BR.md +125 -0
- llmrivotril-0.1.0/docs/rag.md +122 -0
- llmrivotril-0.1.0/docs/rag.pt-BR.md +131 -0
- llmrivotril-0.1.0/docs/releasing.md +60 -0
- llmrivotril-0.1.0/docs/releasing.pt-BR.md +55 -0
- llmrivotril-0.1.0/docs/reliability.md +141 -0
- llmrivotril-0.1.0/docs/reliability.pt-BR.md +144 -0
- llmrivotril-0.1.0/docs/streaming-and-tools.md +72 -0
- llmrivotril-0.1.0/docs/streaming-and-tools.pt-BR.md +72 -0
- llmrivotril-0.1.0/docs/technical-review.md +353 -0
- llmrivotril-0.1.0/examples/basic_usage.py +37 -0
- llmrivotril-0.1.0/examples/comparison.py +199 -0
- llmrivotril-0.1.0/examples/demo.py +218 -0
- llmrivotril-0.1.0/examples/tools_example.py +51 -0
- llmrivotril-0.1.0/pyproject.toml +244 -0
- llmrivotril-0.1.0/scripts/benchmark.py +287 -0
- llmrivotril-0.1.0/src/llmrivotril/__init__.py +97 -0
- llmrivotril-0.1.0/src/llmrivotril/_async.py +28 -0
- llmrivotril-0.1.0/src/llmrivotril/agent.py +1348 -0
- llmrivotril-0.1.0/src/llmrivotril/cache.py +311 -0
- llmrivotril-0.1.0/src/llmrivotril/cli.py +115 -0
- llmrivotril-0.1.0/src/llmrivotril/config.py +245 -0
- llmrivotril-0.1.0/src/llmrivotril/content.py +43 -0
- llmrivotril-0.1.0/src/llmrivotril/exceptions.py +14 -0
- llmrivotril-0.1.0/src/llmrivotril/guardrails.py +126 -0
- llmrivotril-0.1.0/src/llmrivotril/integrations/__init__.py +21 -0
- llmrivotril-0.1.0/src/llmrivotril/integrations/_common.py +38 -0
- llmrivotril-0.1.0/src/llmrivotril/integrations/adk.py +94 -0
- llmrivotril-0.1.0/src/llmrivotril/integrations/autogen.py +72 -0
- llmrivotril-0.1.0/src/llmrivotril/integrations/crewai.py +92 -0
- llmrivotril-0.1.0/src/llmrivotril/integrations/langchain.py +132 -0
- llmrivotril-0.1.0/src/llmrivotril/memory.py +200 -0
- llmrivotril-0.1.0/src/llmrivotril/metrics.py +169 -0
- llmrivotril-0.1.0/src/llmrivotril/moderation.py +80 -0
- llmrivotril-0.1.0/src/llmrivotril/pii.py +108 -0
- llmrivotril-0.1.0/src/llmrivotril/plugins.py +139 -0
- llmrivotril-0.1.0/src/llmrivotril/pricing.py +129 -0
- llmrivotril-0.1.0/src/llmrivotril/providers.py +1313 -0
- llmrivotril-0.1.0/src/llmrivotril/py.typed +0 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/__init__.py +16 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/chunkers.py +80 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/document.py +21 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/loaders.py +211 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/pipeline.py +141 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/retrievers.py +252 -0
- llmrivotril-0.1.0/src/llmrivotril/rag/vector_stores.py +543 -0
- llmrivotril-0.1.0/src/llmrivotril/resilience.py +335 -0
- llmrivotril-0.1.0/src/llmrivotril/scaffold.py +261 -0
- llmrivotril-0.1.0/src/llmrivotril/semantic.py +175 -0
- llmrivotril-0.1.0/src/llmrivotril/semantic_cache.py +128 -0
- llmrivotril-0.1.0/src/llmrivotril/server.py +233 -0
- llmrivotril-0.1.0/src/llmrivotril/static/tailwind.min.js +83 -0
- llmrivotril-0.1.0/src/llmrivotril/templates/dashboard.html +115 -0
- llmrivotril-0.1.0/src/llmrivotril/tools.py +221 -0
- llmrivotril-0.1.0/src/llmrivotril/verifier.py +533 -0
- llmrivotril-0.1.0/tests/__init__.py +0 -0
- llmrivotril-0.1.0/tests/conftest.py +22 -0
- llmrivotril-0.1.0/tests/test_agent.py +702 -0
- llmrivotril-0.1.0/tests/test_cache.py +237 -0
- llmrivotril-0.1.0/tests/test_cli.py +58 -0
- llmrivotril-0.1.0/tests/test_config.py +230 -0
- llmrivotril-0.1.0/tests/test_guardrails.py +104 -0
- llmrivotril-0.1.0/tests/test_integrations.py +234 -0
- llmrivotril-0.1.0/tests/test_memory.py +213 -0
- llmrivotril-0.1.0/tests/test_metrics.py +107 -0
- llmrivotril-0.1.0/tests/test_metrics_auto_save.py +62 -0
- llmrivotril-0.1.0/tests/test_moderation.py +87 -0
- llmrivotril-0.1.0/tests/test_pii.py +67 -0
- llmrivotril-0.1.0/tests/test_plugins.py +132 -0
- llmrivotril-0.1.0/tests/test_pricing.py +59 -0
- llmrivotril-0.1.0/tests/test_providers.py +790 -0
- llmrivotril-0.1.0/tests/test_public_api.py +15 -0
- llmrivotril-0.1.0/tests/test_rag.py +379 -0
- llmrivotril-0.1.0/tests/test_resilience.py +180 -0
- llmrivotril-0.1.0/tests/test_semantic.py +98 -0
- llmrivotril-0.1.0/tests/test_semantic_cache.py +85 -0
- llmrivotril-0.1.0/tests/test_semantic_integration.py +56 -0
- llmrivotril-0.1.0/tests/test_server.py +204 -0
- llmrivotril-0.1.0/tests/test_tools.py +277 -0
- llmrivotril-0.1.0/tests/test_vector_stores.py +469 -0
- llmrivotril-0.1.0/tests/test_verifier.py +161 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Reproducible versions for the CI toolchain.
|
|
2
|
+
# Runtime/provider dependencies remain version ranges in pyproject.toml so
|
|
3
|
+
# downstream applications can resolve them with their own dependency set.
|
|
4
|
+
build==1.6.1
|
|
5
|
+
httpx==0.28.1
|
|
6
|
+
mypy==2.3.1
|
|
7
|
+
pytest==9.1.1
|
|
8
|
+
pytest-asyncio==1.4.0
|
|
9
|
+
ruff==0.16.8
|
|
10
|
+
twine==7.0.0
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Runtime/provider versions validated together in the Python 3.13 integration
|
|
2
|
+
# venv. Use this file as a reproducible baseline; downstream applications may
|
|
3
|
+
# maintain a narrower set for the providers they actually enable.
|
|
4
|
+
anthropic==1.9.0
|
|
5
|
+
boto3==1.43.105
|
|
6
|
+
botocore==1.43.105
|
|
7
|
+
cohere==7.2.0
|
|
8
|
+
crewai==1.15.23
|
|
9
|
+
fastapi==0.141.1
|
|
10
|
+
google-adk==2.10.0
|
|
11
|
+
google-genai==2.25.0
|
|
12
|
+
httpx==0.28.1
|
|
13
|
+
instructor==1.15.4
|
|
14
|
+
langchain-core==1.6.6
|
|
15
|
+
openai==2.54.0
|
|
16
|
+
pydantic==2.12.5
|
|
17
|
+
qdrant-client==1.19.1
|
|
18
|
+
scikit-learn==1.9.1
|
|
19
|
+
scipy==1.18.1
|
|
20
|
+
s3transfer==0.19.2
|
|
21
|
+
sentence-transformers==6.1.0
|
|
22
|
+
tiktoken==0.14.0
|
|
23
|
+
torch==2.14.0
|
|
24
|
+
transformers==5.17.0
|
|
25
|
+
uvicorn==0.54.0
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout repository
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
cache: pip
|
|
26
|
+
cache-dependency-path: pyproject.toml
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: |
|
|
30
|
+
python -m pip install --upgrade pip
|
|
31
|
+
pip install -c .github/constraints-ci.txt -e ".[ci]"
|
|
32
|
+
|
|
33
|
+
- name: Lint with ruff
|
|
34
|
+
run: ruff check src tests examples scripts
|
|
35
|
+
|
|
36
|
+
- name: Check formatting with ruff
|
|
37
|
+
run: ruff format --check src tests examples scripts
|
|
38
|
+
|
|
39
|
+
- name: Type check with mypy
|
|
40
|
+
run: mypy src
|
|
41
|
+
|
|
42
|
+
- name: Test with pytest
|
|
43
|
+
run: pytest -v
|
|
44
|
+
|
|
45
|
+
build:
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
steps:
|
|
48
|
+
- name: Checkout repository
|
|
49
|
+
uses: actions/checkout@v4
|
|
50
|
+
|
|
51
|
+
- name: Set up Python
|
|
52
|
+
uses: actions/setup-python@v5
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.12"
|
|
55
|
+
cache: pip
|
|
56
|
+
cache-dependency-path: pyproject.toml
|
|
57
|
+
|
|
58
|
+
- name: Install build dependencies
|
|
59
|
+
run: |
|
|
60
|
+
python -m pip install --upgrade pip
|
|
61
|
+
pip install -c .github/constraints-ci.txt -e ".[ci]"
|
|
62
|
+
|
|
63
|
+
- name: Build package
|
|
64
|
+
run: python -m build
|
|
65
|
+
|
|
66
|
+
- name: Check package metadata
|
|
67
|
+
run: twine check dist/*
|
|
68
|
+
|
|
69
|
+
extras:
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- name: Checkout repository
|
|
73
|
+
uses: actions/checkout@v4
|
|
74
|
+
|
|
75
|
+
- name: Set up Python
|
|
76
|
+
uses: actions/setup-python@v5
|
|
77
|
+
with:
|
|
78
|
+
python-version: "3.12"
|
|
79
|
+
cache: pip
|
|
80
|
+
cache-dependency-path: pyproject.toml
|
|
81
|
+
|
|
82
|
+
- name: Install with all extras
|
|
83
|
+
run: |
|
|
84
|
+
python -m pip install --upgrade pip
|
|
85
|
+
pip install -c .github/constraints-ci.txt -e ".[dev]"
|
|
86
|
+
|
|
87
|
+
- name: Run tests with extras installed
|
|
88
|
+
run: pytest -v
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions: {}
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
name: Build and publish distributions
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
# Configure this environment's protection rules (required reviewers,
|
|
14
|
+
# wait timer) in Settings -> Environments to gate the actual upload step
|
|
15
|
+
# behind manual approval -- switching from Trusted Publishing to a
|
|
16
|
+
# static API token removed OIDC's per-run, unexfiltratable credential;
|
|
17
|
+
# an approval gate is the mitigation for that trade-off.
|
|
18
|
+
environment:
|
|
19
|
+
name: pypi
|
|
20
|
+
url: https://pypi.org/p/llmrivotril
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- name: Check out the release tag
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.12"
|
|
32
|
+
|
|
33
|
+
- name: Build distributions
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
python -m pip install -c .github/constraints-ci.txt build twine
|
|
37
|
+
python -m build
|
|
38
|
+
twine check dist/*
|
|
39
|
+
|
|
40
|
+
- name: Publish to PyPI
|
|
41
|
+
env:
|
|
42
|
+
TWINE_USERNAME: __token__
|
|
43
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
44
|
+
run: twine upload --skip-existing dist/*
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
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
|
+
# Virtual environments
|
|
30
|
+
.venv
|
|
31
|
+
venv/
|
|
32
|
+
ENV/
|
|
33
|
+
env/
|
|
34
|
+
|
|
35
|
+
# IDEs
|
|
36
|
+
.vscode/
|
|
37
|
+
.idea/
|
|
38
|
+
*.swp
|
|
39
|
+
*.swo
|
|
40
|
+
*~
|
|
41
|
+
|
|
42
|
+
# Testing
|
|
43
|
+
.pytest_cache/
|
|
44
|
+
.coverage
|
|
45
|
+
htmlcov/
|
|
46
|
+
.tox/
|
|
47
|
+
|
|
48
|
+
# Environment variables
|
|
49
|
+
.env
|
|
50
|
+
.env.local
|
|
51
|
+
|
|
52
|
+
# OS files
|
|
53
|
+
.DS_Store
|
|
54
|
+
Thumbs.db
|
|
55
|
+
|
|
56
|
+
# Logs
|
|
57
|
+
*.log
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.6.9
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
10
|
+
rev: v1.11.2
|
|
11
|
+
hooks:
|
|
12
|
+
- id: mypy
|
|
13
|
+
additional_dependencies: [types-python-dateutil]
|
|
14
|
+
args: [src]
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-09-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- First release candidate for PyPI distribution.
|
|
15
|
+
- Framework-integration adapters for CrewAI (`BaseLLM`), AG2/pyautogen
|
|
16
|
+
(`ModelClient` protocol, no extra dependency), LangChain/LangGraph
|
|
17
|
+
(`BaseChatModel`), and Google ADK (`BaseLlm`) under
|
|
18
|
+
`llmrivotril.integrations`. Each is optional (`llmrivotril[crewai]`,
|
|
19
|
+
`llmrivotril[langchain]`, `llmrivotril[adk]`, or `llmrivotril[integrations]`
|
|
20
|
+
for all three) and documented in `docs/integrations.md`, including
|
|
21
|
+
multi-agent/crew setup notes.
|
|
22
|
+
- Three independent, opt-in token-saving controls, all off by default and
|
|
23
|
+
documented in `docs/reliability.md`:
|
|
24
|
+
- `SemanticCache` (`llmrivotril.semantic_cache`) -- wraps any `BaseCache`
|
|
25
|
+
backend with an embedding-similarity lookup, so paraphrased repeat
|
|
26
|
+
prompts hit the cache too, not just byte-identical ones. Requires
|
|
27
|
+
`llmrivotril[semantic]`.
|
|
28
|
+
- `MemoryStore(max_tokens=..., count_tokens=...)` -- trims the oldest
|
|
29
|
+
memory turns by actual token count, layered on top of the existing
|
|
30
|
+
turn-count `retention_window` cap. `RivotrilAgent(memory_max_tokens=...)`
|
|
31
|
+
wires this in automatically for its default memory store.
|
|
32
|
+
- `MemoryStore(summarize=..., summarize_trigger_turns=...)` -- compacts
|
|
33
|
+
turns that would otherwise be dropped into a short summary instead.
|
|
34
|
+
`RivotrilAgent(memory_summarize=True, memory_summarize_trigger_turns=...)`
|
|
35
|
+
wires in a summarizer backed by the agent's own provider.
|
|
36
|
+
- `BaseCache.get`/`set` gained an optional `prompt=` parameter (ignored by
|
|
37
|
+
the existing exact-match backends) so a fuzzy-matching cache can see the
|
|
38
|
+
raw prompt text; this is a backward-compatible addition, not a breaking
|
|
39
|
+
change to the interface.
|
|
40
|
+
- Brazilian Portuguese translations (`*.pt-BR.md`) of the README and every
|
|
41
|
+
public doc, each cross-linked with its English original.
|
|
42
|
+
- RAG context injection, deterministic vector-store identifiers, protected
|
|
43
|
+
memory persistence, cache namespacing, and expanded telemetry.
|
|
44
|
+
- Explicit grounding failure policies and provider-specific retry handling.
|
|
45
|
+
- Gemini adapter migration to the `google-genai` SDK.
|
|
46
|
+
- `RAGPipeline.retrieve()`/`aretrieve()` for accessing ranked documents with
|
|
47
|
+
IDs and metadata before formatting context for an LLM.
|
|
48
|
+
- Public top-level exports for `BaseLoader`, `BaseChunker` and `BaseRetriever`
|
|
49
|
+
so custom RAG components do not depend on internal module paths.
|
|
50
|
+
- Async RAG methods now execute synchronous loading, chunking and retrieval in
|
|
51
|
+
a short-lived worker without blocking the event loop.
|
|
52
|
+
- RAG queries support exact metadata filters, source labels and maximum context
|
|
53
|
+
size limits.
|
|
54
|
+
- PostgreSQL, Qdrant and Pinecone use native metadata filters when available;
|
|
55
|
+
Weaviate now supports native filters for explicitly configured flattened
|
|
56
|
+
metadata fields and keeps a client-side fallback for other fields.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
- CI and release workflows now use `.github/constraints-ci.txt` to keep lint,
|
|
61
|
+
type-check, test, and packaging tool versions reproducible without pinning
|
|
62
|
+
runtime/provider dependencies for downstream applications.
|
|
63
|
+
- LangChain, CrewAI and Google ADK integrations now support streaming through
|
|
64
|
+
their native adapter protocols; LangChain also supports `bind_tools()`.
|
|
65
|
+
- Prompt content can contain text, image, audio and document parts. OpenAI,
|
|
66
|
+
Azure, Anthropic, Gemini and Bedrock preserve supported rich content while
|
|
67
|
+
guardrails, PII redaction, token accounting and memory use a safe text view.
|
|
68
|
+
- Bedrock Converse streaming now accumulates `toolUse` deltas and executes the
|
|
69
|
+
generic agent tool loop.
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- RAG retrievers now reject negative `top_k` values instead of relying on
|
|
74
|
+
Python slicing semantics.
|
|
75
|
+
- Three `WeaviateRetriever` tests only passed when `weaviate-client` happened
|
|
76
|
+
to be installed locally, because `_collection_properties()`/
|
|
77
|
+
`_native_metadata_filter()` do a real (unmocked) `from weaviate.classes...
|
|
78
|
+
import ...` that a mocked `client=` object can't stand in for. This wasn't
|
|
79
|
+
caught by the "326 tests passed" gate recorded earlier in
|
|
80
|
+
`docs/technical-review.md`, because that run had `weaviate-client`
|
|
81
|
+
installed -- CI's `lint-and-test` job (`pip install -e ".[ci]"`, no
|
|
82
|
+
optional extras) would have failed on these 3. Fixed by mocking
|
|
83
|
+
`weaviate.classes.config`/`.query` the same way the other optional
|
|
84
|
+
vector-store dependencies already are; verified clean with zero optional
|
|
85
|
+
packages installed, matching real CI exactly.
|
|
86
|
+
|
|
87
|
+
### Security
|
|
88
|
+
|
|
89
|
+
- Dashboard log rendering no longer interpolates untrusted content as HTML.
|
|
90
|
+
- SQL table identifiers are validated before being used by the pgvector
|
|
91
|
+
adapter.
|
|
92
|
+
|
|
93
|
+
## [0.0.9] - 2026-09-28
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
|
|
97
|
+
- `AnthropicProvider`/`CohereProvider`/`GeminiProvider` now implement
|
|
98
|
+
`stream()`/`astream()` (previously unimplemented, raised
|
|
99
|
+
`NotImplementedError`), each using that provider's native streaming API
|
|
100
|
+
and yielding plain text chunks. Not verified against a live account --
|
|
101
|
+
same caveat as the Azure/Bedrock adapters.
|
|
102
|
+
- `run_stream()`/`run_stream_async()` now accept `response_model=`. Returns
|
|
103
|
+
a `StreamedStructuredResult`/`AsyncStreamedStructuredResult` instead of a
|
|
104
|
+
plain iterator: iterate it for the raw JSON text as it streams, and read
|
|
105
|
+
`.result` after the loop ends for the validated `response_model`
|
|
106
|
+
instance (partial JSON isn't a valid model, so there's nothing to
|
|
107
|
+
validate until the stream is done). Can't be combined with `tools=`
|
|
108
|
+
(raises `ValueError`).
|
|
109
|
+
|
|
110
|
+
## [0.0.8] - 2026-09-28
|
|
111
|
+
|
|
112
|
+
### Added
|
|
113
|
+
|
|
114
|
+
- `ModerationGuardrail`: flags input/output via OpenAI's moderation
|
|
115
|
+
endpoint, for adversarial/unsafe content the local keyword/regex/topic
|
|
116
|
+
guardrails aren't meant to catch. Fails closed by default (`fail_open=`
|
|
117
|
+
to opt out).
|
|
118
|
+
- `RIVOTRIL_DASHBOARD_TOKENS`: multiple named bearer tokens for the
|
|
119
|
+
dashboard (`"label1:token1,label2:token2"`) instead of one shared secret;
|
|
120
|
+
each valid token's label is logged on access. `RIVOTRIL_DASHBOARD_TOKEN`
|
|
121
|
+
(singular) still works as a single unlabeled token.
|
|
122
|
+
- `AzureOpenAIProvider` and `BedrockProvider`: new provider adapters.
|
|
123
|
+
Azure OpenAI uses the `openai` SDK's dedicated `AzureOpenAI`/
|
|
124
|
+
`AsyncAzureOpenAI` clients (no extra install). Bedrock uses the Bedrock
|
|
125
|
+
Runtime Converse API for one request shape across model families
|
|
126
|
+
(requires `llmrivotril[bedrock]`); `tools=` isn't translated to Converse's
|
|
127
|
+
tool-call format yet, and `acomplete`/`astream` run the synchronous boto3
|
|
128
|
+
call in a worker thread since boto3 has no official async client. Neither
|
|
129
|
+
adapter has been verified against a live Azure/AWS account -- built from
|
|
130
|
+
documented API shapes and covered by mocked unit tests only.
|
|
131
|
+
- `PgVectorRetriever`, `QdrantRetriever`, `WeaviateRetriever`,
|
|
132
|
+
`PineconeRetriever`: external vector-store retrievers for RAG beyond
|
|
133
|
+
in-memory scale, behind `llmrivotril[pgvector|qdrant|weaviate|pinecone]`
|
|
134
|
+
(or `llmrivotril[vector-stores]` for all four). Also not verified against
|
|
135
|
+
a live service -- same caveat as the two new providers.
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
|
|
139
|
+
- The non-streaming multi-round tool-calling loop
|
|
140
|
+
(`_handle_tool_calls`/`_handle_tool_calls_async`) passed `tools=None` on
|
|
141
|
+
every follow-up call after the first, so a conversation needing a second
|
|
142
|
+
tool call in the same turn could never request one -- the model was never
|
|
143
|
+
offered any tool schemas past round one.
|
|
144
|
+
|
|
145
|
+
## [0.0.7] - 2026-09-28
|
|
146
|
+
|
|
147
|
+
### Added
|
|
148
|
+
|
|
149
|
+
- `InMemoryEmbeddingRetriever(cache_path=...)`: content-hash-keyed embedding
|
|
150
|
+
cache persisted to JSON, so re-ingesting unchanged document content across
|
|
151
|
+
process restarts skips recomputing its embedding.
|
|
152
|
+
- `run_stream()`/`run_stream_async()` accept `tools=`; a turn where the model
|
|
153
|
+
answers directly still streams token by token, and a turn where it calls a
|
|
154
|
+
tool falls back to a single blocking round-trip for that turn.
|
|
155
|
+
- `MemoryStore(auto_save_path=...)` / `RIVOTRIL_MEMORY_PATH`: persist
|
|
156
|
+
conversation history to a JSON file automatically, mirroring
|
|
157
|
+
`RIVOTRIL_METRICS_PATH`/`RIVOTRIL_CACHE_PATH`.
|
|
158
|
+
- `RAGPipeline.aingest()`/`RAGPipeline.aquery()`: async wrappers (via a
|
|
159
|
+
worker thread) so ingestion/retrieval don't block the event loop inside
|
|
160
|
+
`run_async()`.
|
|
161
|
+
- `py.typed` marker (PEP 561) so downstream type checkers pick up this
|
|
162
|
+
package's types.
|
|
163
|
+
- Dashboard endpoints are now rate-limited per client IP
|
|
164
|
+
(`RIVOTRIL_DASHBOARD_RATE_LIMIT_MAX_CALLS`/`_PER_SECONDS`).
|
|
165
|
+
|
|
166
|
+
### Fixed
|
|
167
|
+
|
|
168
|
+
- `InMemoryEmbeddingRetriever.retrieve()` scored documents with a pure-Python
|
|
169
|
+
cosine-similarity loop; switched to a cached numpy matrix (~5x faster at a
|
|
170
|
+
few thousand documents), with the pure-Python path kept as a fallback when
|
|
171
|
+
numpy isn't installed.
|
|
172
|
+
- `InMemoryEmbeddingRetriever._load_model()` had the same unlocked
|
|
173
|
+
lazy-model-load race already fixed in `semantic.py`; added the same
|
|
174
|
+
double-checked lock.
|
|
175
|
+
- Deleted `InMemoryKeywordRetriever`'s duplicated `[a-z0-9]+` tokenizer/
|
|
176
|
+
stopword list (same accent-splitting bug as `verifier.py`); it now reuses
|
|
177
|
+
the shared, fixed `_tokenize`.
|
|
178
|
+
- Test isolation: `tests/test_config.py` set `os.environ[...]` directly and
|
|
179
|
+
only had a before-test cleanup fixture, so a var left set by its last test
|
|
180
|
+
leaked into whatever test module pytest ran next. Also fixed a subtler
|
|
181
|
+
variant of the same bug in the fix itself: calling `monkeypatch.delenv()`
|
|
182
|
+
from *inside* another fixture's post-`yield` teardown gets undone by
|
|
183
|
+
monkeypatch's own finalizer (which runs afterwards, in reverse dependency
|
|
184
|
+
order) -- switched to plain `os.environ.pop()` for this cleanup.
|
|
185
|
+
|
|
186
|
+
### Documentation
|
|
187
|
+
|
|
188
|
+
- Documented that `plugins="auto"` executes code from any installed
|
|
189
|
+
package's entry points, with no sandboxing.
|
|
190
|
+
- Documented that Azure OpenAI and AWS Bedrock are not supported via
|
|
191
|
+
`base_url` (they need a different client/auth/request shape, not just a
|
|
192
|
+
different endpoint).
|
|
193
|
+
- Documented the local dashboard's trust model (single shared token, no
|
|
194
|
+
per-user accounts -- not for multi-tenant or public exposure).
|
|
195
|
+
|
|
196
|
+
## [0.0.6] - 2026-09-27
|
|
197
|
+
|
|
198
|
+
### Added
|
|
199
|
+
|
|
200
|
+
- Response caching:
|
|
201
|
+
- `cache=` argument on `RivotrilAgent` (`InMemoryCache`, `DiskCache`, `RedisCache`, or custom `BaseCache`).
|
|
202
|
+
- `RIVOTRIL_CACHE_PATH` environment variable to activate disk-based caching.
|
|
203
|
+
- Deterministic cache keys based on model, messages, tools, and response model.
|
|
204
|
+
- `RedisCache` for multi-process/distributed deployments (optional `llmrivotril[redis]` dependency).
|
|
205
|
+
- Schema-repair fallback for structured outputs:
|
|
206
|
+
- `schema_repair_attempts=` argument on `RivotrilAgent`.
|
|
207
|
+
- `RIVOTRIL_SCHEMA_REPAIR_ATTEMPTS` environment variable.
|
|
208
|
+
- Re-prompts the model with validation errors when Pydantic schema validation fails.
|
|
209
|
+
- Cost tracking:
|
|
210
|
+
- `track_costs=` argument on `RivotrilAgent`.
|
|
211
|
+
- `RIVOTRIL_TRACK_COSTS` environment variable.
|
|
212
|
+
- Built-in pricing table for OpenAI, Anthropic, Cohere, and Gemini models.
|
|
213
|
+
- `estimate_cost()`, `register_pricing()`, and `list_supported_models()` helpers.
|
|
214
|
+
- PII detection and redaction:
|
|
215
|
+
- `redact_pii=` argument on `RivotrilAgent`.
|
|
216
|
+
- `RIVOTRIL_REDACT_PII` environment variable.
|
|
217
|
+
- `PIIRedactor` with regex scanners for email, CPF, CNPJ, phone, and credit card.
|
|
218
|
+
- Token budget controls on `RivotrilAgent`:
|
|
219
|
+
- `max_prompt_tokens` and `max_session_tokens` constructor arguments.
|
|
220
|
+
- `RIVOTRIL_MAX_PROMPT_TOKENS` and `RIVOTRIL_MAX_SESSION_TOKENS` environment variables.
|
|
221
|
+
- `TokenBudgetExceededError` raised when a run would exceed the configured budget.
|
|
222
|
+
- Plugin system via Python entry points:
|
|
223
|
+
- Groups `llmrivotril.guardrails` and `llmrivotril.verifiers`.
|
|
224
|
+
- `plugins="auto"` or `plugins=[...]` on `RivotrilAgent`.
|
|
225
|
+
- `discover_plugins()` and `load_plugins()` helpers exported from the top-level package.
|
|
226
|
+
- Automatic metrics persistence:
|
|
227
|
+
- `RIVOTRIL_METRICS_PATH` environment variable and `metrics_path=` argument on `RivotrilAgent`.
|
|
228
|
+
- `MetricsCollector.load_metrics()` alias for `load_from_json()`.
|
|
229
|
+
- Function calling / tools support:
|
|
230
|
+
- `tools=` argument on `agent.run()` and `agent.run_async()`.
|
|
231
|
+
- `ToolRegistry` and `ToolCall` exported from the top-level package.
|
|
232
|
+
- Accepts OpenAI-style tool dicts or plain Python callables (auto-introspected into schemas).
|
|
233
|
+
- Built-in tool-call loop with follow-up completion.
|
|
234
|
+
- Offline dashboard: Tailwind CSS is now bundled and served locally instead of loaded from CDN.
|
|
235
|
+
- File-based configuration via `llmrivotril.toml`, `llmrivotril.yaml`, or `[tool.llmrivotril]` in `pyproject.toml`.
|
|
236
|
+
- Precedence: file defaults < environment variables < constructor arguments.
|
|
237
|
+
- `RIVOTRIL_PROVIDER` environment variable and `provider=` argument on `RivotrilAgent`.
|
|
238
|
+
- Multi-provider support with adapters for OpenAI, Anthropic, Cohere, and Gemini in `llmrivotril.providers`.
|
|
239
|
+
- `ModelBasedFaithfulnessVerifier` for LLM-as-a-judge grounding checks.
|
|
240
|
+
|
|
241
|
+
### Fixed
|
|
242
|
+
|
|
243
|
+
- PII redaction now applies to structured (`response_model=`) results and runs
|
|
244
|
+
before a response is written to `cache=`; previously `redact_pii=True` left
|
|
245
|
+
structured outputs unredacted and could persist raw PII at rest in the cache.
|
|
246
|
+
- `DiskCache` no longer uses `pickle` (arbitrary code execution risk if the
|
|
247
|
+
cache file is ever tampered with); it now stores JSON in a local SQLite
|
|
248
|
+
file, with indexed per-key reads/writes instead of rewriting the whole
|
|
249
|
+
store on every `get`/`set`.
|
|
250
|
+
- `PIIRedactor.redact()` no longer corrupts text when two pattern matches
|
|
251
|
+
overlap; overlapping spans are merged before replacement.
|
|
252
|
+
- The local dashboard's token check now uses a constant-time comparison
|
|
253
|
+
(`secrets.compare_digest`) instead of `!=`, closing a timing side-channel.
|
|
254
|
+
- `_load_dotenv()` no longer silently swallows a missing `python-dotenv`
|
|
255
|
+
install; it's a core dependency and is now imported unconditionally.
|
|
256
|
+
- Fixed a duplicated `_ENV_INTS` definition in `config.py` that silently
|
|
257
|
+
discarded the first set of keys.
|
|
258
|
+
- Corrected the configuration-precedence docstring in `config.py` to match
|
|
259
|
+
the actual lookup order.
|
|
260
|
+
- `CircuitBreaker` no longer lets multiple threads dispatch a HALF_OPEN probe
|
|
261
|
+
concurrently; checking and transitioning state is now a single atomic
|
|
262
|
+
operation instead of two separately-locked steps.
|
|
263
|
+
- `KeywordOverlapVerifier`'s tokenizer used `[a-z0-9]+`, which split accented
|
|
264
|
+
words (e.g. "informação" -> "informa" + "o"), corrupting grounding checks
|
|
265
|
+
for Portuguese and other accented-language text. Switched to a
|
|
266
|
+
Unicode-aware pattern and added Portuguese stopwords alongside the
|
|
267
|
+
existing English list.
|
|
268
|
+
|
|
269
|
+
## [0.0.5] - 2026-09-25
|
|
270
|
+
|
|
271
|
+
### Added
|
|
272
|
+
|
|
273
|
+
- Local RAG module (`llmrivotril.rag`) with:
|
|
274
|
+
- `Document` model
|
|
275
|
+
- `TextLoader` and `MarkdownLoader`
|
|
276
|
+
- `SimpleChunker` with configurable size and overlap
|
|
277
|
+
- `InMemoryKeywordRetriever` (no external dependencies)
|
|
278
|
+
- `InMemoryEmbeddingRetriever` (optional `sentence-transformers`)
|
|
279
|
+
- `RAGPipeline` to ingest sources and feed context into `RivotrilAgent`
|
|
280
|
+
- Re-exported RAG primitives from the top-level `llmrivotril` package.
|
|
281
|
+
|
|
282
|
+
## [0.0.4] - 2026-09-25
|
|
283
|
+
|
|
284
|
+
### Added
|
|
285
|
+
|
|
286
|
+
- `llmrivotril init [PATH]` CLI command to scaffold a new project with:
|
|
287
|
+
- `pyproject.toml`, `.gitignore`, `.env.example`, `README.md`
|
|
288
|
+
- package directory with `agent.py` and `guardrails.py`
|
|
289
|
+
- starter `tests/test_agent.py`
|
|
290
|
+
|
|
291
|
+
## [0.0.3] - 2026-09-25
|
|
292
|
+
|
|
293
|
+
### Added
|
|
294
|
+
|
|
295
|
+
- Environment-variable configuration via `llmrivotril.config.load_env_config()`.
|
|
296
|
+
- `RIVOTRIL_MODEL`, `RIVOTRIL_API_KEY`, `RIVOTRIL_BASE_URL`, `RIVOTRIL_SYSTEM_PROMPT`
|
|
297
|
+
- `RIVOTRIL_REQUEST_TIMEOUT`
|
|
298
|
+
- `RIVOTRIL_RATE_LIMIT_MAX_CALLS`, `RIVOTRIL_RATE_LIMIT_PER_SECONDS`
|
|
299
|
+
- `RIVOTRIL_RETRY_MAX_ATTEMPTS`, `RIVOTRIL_RETRY_MIN_WAIT`, `RIVOTRIL_RETRY_MAX_WAIT`
|
|
300
|
+
- `RIVOTRIL_CIRCUIT_FAILURE_THRESHOLD`, `RIVOTRIL_CIRCUIT_RECOVERY_TIMEOUT`
|
|
301
|
+
- Explicit constructor arguments always override environment values.
|
|
302
|
+
- `/api/health` endpoint on the dashboard returning status, version, and UTC timestamp.
|
|
303
|
+
- Async-safe `AsyncRateLimiter` used by `RivotrilAgent.run_async()`.
|
|
304
|
+
- `system_prompt` support injected as a `system` message.
|
|
305
|
+
- `context_sources` accepts `str | list[str] | None` and joins multiple sources.
|
|
306
|
+
- Structured logging through the `llmrivotril` logger.
|
|
307
|
+
- CLI commands: `benchmark`, `doctor`, `version`.
|
|
308
|
+
- `request_timeout` forwarded to OpenAI/instructor calls.
|
|
309
|
+
- Per-agent `metrics` injection and `MetricsCollector.reset()`.
|
|
310
|
+
- `disallowed_patterns` regex guardrails on input and output.
|
|
311
|
+
|
|
312
|
+
### Changed
|
|
313
|
+
|
|
314
|
+
- `tiktoken` encoding now falls back to `cl100k_base` for unknown model names, improving compatibility with local/Ollama models.
|
|
315
|
+
- `Guardrail` output validation also checks `disallowed_keywords`.
|
|
316
|
+
|
|
317
|
+
## [0.0.2] - 2026-09-24
|
|
318
|
+
|
|
319
|
+
### Added
|
|
320
|
+
|
|
321
|
+
- First packaged release of LLM-Rivotril.
|
|
322
|
+
|
|
323
|
+
## [0.0.1] - 2026-09-20
|
|
324
|
+
|
|
325
|
+
### Added
|
|
326
|
+
|
|
327
|
+
- Proof-of-concept agent with basic guardrails.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Contributing to LLM-Rivotril
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in improving LLM-Rivotril!
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
1. Fork the repository.
|
|
8
|
+
2. Clone your fork:
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/your-username/llmrivotril.git
|
|
11
|
+
cd llmrivotril
|
|
12
|
+
```
|
|
13
|
+
3. Create a virtual environment and install in editable mode:
|
|
14
|
+
```bash
|
|
15
|
+
python -m venv .venv
|
|
16
|
+
source .venv/bin/activate
|
|
17
|
+
pip install -e ".[dev]"
|
|
18
|
+
```
|
|
19
|
+
For a lighter install that skips optional provider SDKs and semantic dependencies,
|
|
20
|
+
use `pip install -e ".[ci]"`.
|
|
21
|
+
|
|
22
|
+
## Development Workflow
|
|
23
|
+
|
|
24
|
+
1. Create a feature branch:
|
|
25
|
+
```bash
|
|
26
|
+
git checkout -b feature/your-feature-name
|
|
27
|
+
```
|
|
28
|
+
2. Make your changes, adding tests for new behavior.
|
|
29
|
+
3. Run the test suite:
|
|
30
|
+
```bash
|
|
31
|
+
pytest
|
|
32
|
+
```
|
|
33
|
+
4. Run linting and type checks:
|
|
34
|
+
```bash
|
|
35
|
+
ruff check src tests examples scripts
|
|
36
|
+
ruff format --check src tests examples scripts
|
|
37
|
+
mypy src
|
|
38
|
+
```
|
|
39
|
+
5. Commit your changes and open a pull request.
|
|
40
|
+
|
|
41
|
+
## Code Style
|
|
42
|
+
|
|
43
|
+
- Follow PEP 8.
|
|
44
|
+
- Use type hints for public functions and classes.
|
|
45
|
+
- Keep functions focused and small.
|
|
46
|
+
- Write docstrings for modules, classes, and public methods.
|
|
47
|
+
|
|
48
|
+
## Testing
|
|
49
|
+
|
|
50
|
+
- Place unit tests in `tests/`.
|
|
51
|
+
- Use `pytest` fixtures to isolate stateful components such as `MemoryStore` and `MetricsCollector`.
|
|
52
|
+
- Mock external API calls (OpenAI / Instructor) in agent tests.
|
|
53
|
+
|
|
54
|
+
## Reporting Issues
|
|
55
|
+
|
|
56
|
+
When reporting bugs, include:
|
|
57
|
+
|
|
58
|
+
- Python version
|
|
59
|
+
- Package version (`pip show llmrivotril`)
|
|
60
|
+
- Minimal reproducible example
|
|
61
|
+
- Expected vs actual behavior
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LLM-Rivotril Contributors
|
|
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.
|