beliefstate 1.0.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.
- beliefstate-1.0.0/.github/workflows/ci.yml +79 -0
- beliefstate-1.0.0/.github/workflows/lint.yml +36 -0
- beliefstate-1.0.0/.github/workflows/pages.yml +41 -0
- beliefstate-1.0.0/.github/workflows/publish.yml +53 -0
- beliefstate-1.0.0/.gitignore +68 -0
- beliefstate-1.0.0/ADAPTER_AUDIT_REPORT.md +132 -0
- beliefstate-1.0.0/CRITICAL_BLOCKERS_ANALYSIS.md +216 -0
- beliefstate-1.0.0/IMPLEMENTATION_TRACKING.md +711 -0
- beliefstate-1.0.0/LICENSE +21 -0
- beliefstate-1.0.0/OPENTELEMETRY_GUIDE.md +267 -0
- beliefstate-1.0.0/PKG-INFO +485 -0
- beliefstate-1.0.0/PRODUCTION_ENHANCEMENTS.md +452 -0
- beliefstate-1.0.0/PROJECT_STATE_ANALYSIS.md +702 -0
- beliefstate-1.0.0/README.md +416 -0
- beliefstate-1.0.0/assets/data_flow.png +0 -0
- beliefstate-1.0.0/beliefstate/__init__.py +176 -0
- beliefstate-1.0.0/beliefstate/adapters/__init__.py +15 -0
- beliefstate-1.0.0/beliefstate/adapters/anthropic.py +247 -0
- beliefstate-1.0.0/beliefstate/adapters/base.py +45 -0
- beliefstate-1.0.0/beliefstate/adapters/common.py +284 -0
- beliefstate-1.0.0/beliefstate/adapters/gemini.py +328 -0
- beliefstate-1.0.0/beliefstate/adapters/litellm.py +293 -0
- beliefstate-1.0.0/beliefstate/adapters/ollama.py +397 -0
- beliefstate-1.0.0/beliefstate/adapters/openai.py +282 -0
- beliefstate-1.0.0/beliefstate/call.py +23 -0
- beliefstate-1.0.0/beliefstate/config.py +253 -0
- beliefstate-1.0.0/beliefstate/detector.py +333 -0
- beliefstate-1.0.0/beliefstate/dispatcher.py +343 -0
- beliefstate-1.0.0/beliefstate/extractor.py +553 -0
- beliefstate-1.0.0/beliefstate/integrations/__init__.py +29 -0
- beliefstate-1.0.0/beliefstate/integrations/asgi.py +75 -0
- beliefstate-1.0.0/beliefstate/integrations/common.py +156 -0
- beliefstate-1.0.0/beliefstate/integrations/fastapi.py +120 -0
- beliefstate-1.0.0/beliefstate/integrations/flask.py +99 -0
- beliefstate-1.0.0/beliefstate/integrations/langchain.py +129 -0
- beliefstate-1.0.0/beliefstate/integrations/llamaindex.py +119 -0
- beliefstate-1.0.0/beliefstate/integrations/openai.py +152 -0
- beliefstate-1.0.0/beliefstate/integrations/wsgi.py +58 -0
- beliefstate-1.0.0/beliefstate/judge.py +155 -0
- beliefstate-1.0.0/beliefstate/logging_utils.py +78 -0
- beliefstate-1.0.0/beliefstate/models.py +59 -0
- beliefstate-1.0.0/beliefstate/observability.py +319 -0
- beliefstate-1.0.0/beliefstate/py.typed +1 -0
- beliefstate-1.0.0/beliefstate/resilience.py +255 -0
- beliefstate-1.0.0/beliefstate/resolver.py +109 -0
- beliefstate-1.0.0/beliefstate/store/__init__.py +6 -0
- beliefstate-1.0.0/beliefstate/store/base.py +49 -0
- beliefstate-1.0.0/beliefstate/store/memory.py +192 -0
- beliefstate-1.0.0/beliefstate/store/redis.py +164 -0
- beliefstate-1.0.0/beliefstate/store/sqlite.py +443 -0
- beliefstate-1.0.0/beliefstate/tracker.py +1302 -0
- beliefstate-1.0.0/docs/adapters.html +329 -0
- beliefstate-1.0.0/docs/advanced.html +332 -0
- beliefstate-1.0.0/docs/configuration.html +285 -0
- beliefstate-1.0.0/docs/index.html +382 -0
- beliefstate-1.0.0/docs/integrations.html +281 -0
- beliefstate-1.0.0/docs/reference.html +257 -0
- beliefstate-1.0.0/docs/stores.html +263 -0
- beliefstate-1.0.0/docs/style.css +742 -0
- beliefstate-1.0.0/documentation.md +724 -0
- beliefstate-1.0.0/examples/.env.example +28 -0
- beliefstate-1.0.0/examples/beliefstate.db-shm +0 -0
- beliefstate-1.0.0/examples/beliefstate.db-wal +0 -0
- beliefstate-1.0.0/examples/demo.py +218 -0
- beliefstate-1.0.0/examples/quick_test.py +119 -0
- beliefstate-1.0.0/examples/requirements.txt +14 -0
- beliefstate-1.0.0/examples/streamlit_app.py +461 -0
- beliefstate-1.0.0/examples/streamlit_app_simple.py +346 -0
- beliefstate-1.0.0/examples/test_package.py +239 -0
- beliefstate-1.0.0/examples/verify_setup.py +191 -0
- beliefstate-1.0.0/pyproject.toml +108 -0
- beliefstate-1.0.0/tests/conftest.py +33 -0
- beliefstate-1.0.0/tests/test_asgi.py +57 -0
- beliefstate-1.0.0/tests/test_config.py +105 -0
- beliefstate-1.0.0/tests/test_detector.py +69 -0
- beliefstate-1.0.0/tests/test_dispatcher.py +140 -0
- beliefstate-1.0.0/tests/test_extractor.py +70 -0
- beliefstate-1.0.0/tests/test_extractor_helpers.py +269 -0
- beliefstate-1.0.0/tests/test_imports.py +76 -0
- beliefstate-1.0.0/tests/test_integrations.py +409 -0
- beliefstate-1.0.0/tests/test_judge.py +144 -0
- beliefstate-1.0.0/tests/test_models.py +216 -0
- beliefstate-1.0.0/tests/test_nvidia.py +71 -0
- beliefstate-1.0.0/tests/test_observability.py +116 -0
- beliefstate-1.0.0/tests/test_ollama.py +90 -0
- beliefstate-1.0.0/tests/test_package_import.py +237 -0
- beliefstate-1.0.0/tests/test_production_hardening.py +466 -0
- beliefstate-1.0.0/tests/test_providers.py +158 -0
- beliefstate-1.0.0/tests/test_resilience.py +117 -0
- beliefstate-1.0.0/tests/test_resolver.py +107 -0
- beliefstate-1.0.0/tests/test_store.py +165 -0
- beliefstate-1.0.0/tests/test_store_memory.py +162 -0
- beliefstate-1.0.0/tests/test_store_sqlite_advanced.py +184 -0
- beliefstate-1.0.0/tests/test_tracker_advanced.py +431 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
# ── Core-only import test ────────────────────────────────────────────
|
|
11
|
+
core-import:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
name: Verify core import (no optional deps)
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- name: Install core only
|
|
21
|
+
run: python -m pip install -e .
|
|
22
|
+
- name: Verify import succeeds
|
|
23
|
+
run: |
|
|
24
|
+
python -c "from beliefstate import BeliefTracker, TrackerConfig, Belief; print('Core import OK')"
|
|
25
|
+
python -c "from beliefstate import OpenAIAdapter; assert OpenAIAdapter is None or callable(OpenAIAdapter); print('Lazy import OK')"
|
|
26
|
+
|
|
27
|
+
# ── Test matrix ──────────────────────────────────────────────────────
|
|
28
|
+
test:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
strategy:
|
|
31
|
+
fail-fast: false
|
|
32
|
+
matrix:
|
|
33
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
34
|
+
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
|
|
38
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
39
|
+
uses: actions/setup-python@v5
|
|
40
|
+
with:
|
|
41
|
+
python-version: ${{ matrix.python-version }}
|
|
42
|
+
cache: 'pip'
|
|
43
|
+
|
|
44
|
+
- name: Install base dependencies
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install --upgrade pip
|
|
47
|
+
python -m pip install -e .
|
|
48
|
+
|
|
49
|
+
- name: Install dev dependencies
|
|
50
|
+
run: |
|
|
51
|
+
python -m pip install -e ".[dev]"
|
|
52
|
+
|
|
53
|
+
- name: Install optional dependencies (non-blocking)
|
|
54
|
+
run: |
|
|
55
|
+
python -m pip install -e ".[openai,anthropic,ollama,litellm,redis,langchain,llamaindex,fastapi,flask]" || true
|
|
56
|
+
|
|
57
|
+
- name: Skip Gemini on Python 3.12+ (compatibility issue)
|
|
58
|
+
if: matrix.python-version == '3.10' || matrix.python-version == '3.11'
|
|
59
|
+
run: |
|
|
60
|
+
python -m pip install -e ".[gemini]" || true
|
|
61
|
+
|
|
62
|
+
- name: Run Ruff Linter
|
|
63
|
+
run: ruff check .
|
|
64
|
+
|
|
65
|
+
- name: Run Ruff Formatter Check
|
|
66
|
+
run: ruff format --check .
|
|
67
|
+
|
|
68
|
+
- name: Run Mypy Type Checker
|
|
69
|
+
run: |
|
|
70
|
+
mypy beliefstate
|
|
71
|
+
|
|
72
|
+
- name: Run Pytest
|
|
73
|
+
run: |
|
|
74
|
+
pytest -v --tb=short
|
|
75
|
+
|
|
76
|
+
- name: Run Pytest with Coverage
|
|
77
|
+
if: matrix.python-version == '3.12'
|
|
78
|
+
run: |
|
|
79
|
+
pytest --cov=beliefstate --cov-report=xml --cov-fail-under=55
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Lint & Type Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
name: Lint and Type Check
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
cache: 'pip'
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
python -m pip install -e ".[dev]"
|
|
27
|
+
python -m pip install -e ".[openai,anthropic,ollama,litellm,redis,langchain,llamaindex,fastapi,flask]" || true
|
|
28
|
+
|
|
29
|
+
- name: Run Ruff Linter
|
|
30
|
+
run: ruff check .
|
|
31
|
+
|
|
32
|
+
- name: Run Ruff Formatter Check
|
|
33
|
+
run: ruff format --check .
|
|
34
|
+
|
|
35
|
+
- name: Run Mypy Type Checker
|
|
36
|
+
run: mypy beliefstate
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Deploy GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- 'docs/**'
|
|
9
|
+
- '.github/workflows/pages.yml'
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
pages: write
|
|
16
|
+
id-token: write
|
|
17
|
+
|
|
18
|
+
# Allow only one concurrent deployment
|
|
19
|
+
concurrency:
|
|
20
|
+
group: "pages"
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
deploy:
|
|
25
|
+
environment:
|
|
26
|
+
name: github-pages
|
|
27
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
- name: Setup Pages
|
|
33
|
+
uses: actions/configure-pages@v5
|
|
34
|
+
- name: Upload artifact
|
|
35
|
+
uses: actions/upload-pages-artifact@v3
|
|
36
|
+
with:
|
|
37
|
+
# Upload entire docs repository
|
|
38
|
+
path: './docs'
|
|
39
|
+
- name: Deploy to GitHub Pages
|
|
40
|
+
id: deployment
|
|
41
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-n-publish:
|
|
10
|
+
name: Build and publish to PyPI
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # Mandatory for PyPI Trusted Publishing OIDC
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.11"
|
|
24
|
+
cache: 'pip'
|
|
25
|
+
|
|
26
|
+
- name: Install build dependencies
|
|
27
|
+
run: |
|
|
28
|
+
python -m pip install --upgrade pip
|
|
29
|
+
python -m pip install build
|
|
30
|
+
|
|
31
|
+
- name: Build binary wheel and source tarball
|
|
32
|
+
run: |
|
|
33
|
+
python -m build
|
|
34
|
+
|
|
35
|
+
- name: Check build artifacts
|
|
36
|
+
run: |
|
|
37
|
+
ls -lh dist/
|
|
38
|
+
tar -tzf dist/*.tar.gz | head -20
|
|
39
|
+
|
|
40
|
+
- name: Publish to PyPI
|
|
41
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
42
|
+
with:
|
|
43
|
+
skip-existing: true
|
|
44
|
+
|
|
45
|
+
- name: Create GitHub Release
|
|
46
|
+
uses: softprops/action-gh-release@v1
|
|
47
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
48
|
+
with:
|
|
49
|
+
files: dist/*
|
|
50
|
+
draft: false
|
|
51
|
+
prerelease: false
|
|
52
|
+
env:
|
|
53
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
*.egg-info/
|
|
24
|
+
.installed.cfg
|
|
25
|
+
*.egg
|
|
26
|
+
|
|
27
|
+
# Installer logs
|
|
28
|
+
pip-log.txt
|
|
29
|
+
pip-delete-this-directory.txt
|
|
30
|
+
|
|
31
|
+
# Unit test / coverage reports
|
|
32
|
+
htmlcov/
|
|
33
|
+
.tox/
|
|
34
|
+
.coverage
|
|
35
|
+
.coverage.*
|
|
36
|
+
.cache
|
|
37
|
+
nosetests.xml
|
|
38
|
+
coverage.xml
|
|
39
|
+
*.cover
|
|
40
|
+
.hypothesis/
|
|
41
|
+
.pytest_cache/
|
|
42
|
+
|
|
43
|
+
# Type hints
|
|
44
|
+
.mypy_cache/
|
|
45
|
+
|
|
46
|
+
# Linting
|
|
47
|
+
.ruff_cache/
|
|
48
|
+
|
|
49
|
+
# Environments
|
|
50
|
+
.env
|
|
51
|
+
.venv
|
|
52
|
+
env/
|
|
53
|
+
venv/
|
|
54
|
+
ENV/
|
|
55
|
+
env.bak/
|
|
56
|
+
venv.bak/
|
|
57
|
+
|
|
58
|
+
# Project specific
|
|
59
|
+
*.db
|
|
60
|
+
*.sqlite3
|
|
61
|
+
beliefstate.db
|
|
62
|
+
demo_beliefs.db
|
|
63
|
+
|
|
64
|
+
# IDEs
|
|
65
|
+
.vscode/
|
|
66
|
+
.idea/
|
|
67
|
+
*.swp
|
|
68
|
+
*.swo
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Adapter & Integration Production Readiness Audit
|
|
2
|
+
|
|
3
|
+
## Date: June 18, 2026
|
|
4
|
+
## Status: Audit Complete - Production Enhancements Required
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## FINDINGS
|
|
9
|
+
|
|
10
|
+
### CRITICAL ISSUES
|
|
11
|
+
|
|
12
|
+
#### 1. **OpenAI Adapter - Missing Error Handling**
|
|
13
|
+
- ❌ No retry logic for transient API errors (rate limits, timeouts)
|
|
14
|
+
- ❌ No graceful handling of partial responses
|
|
15
|
+
- ❌ No validation of API keys at initialization
|
|
16
|
+
- ❌ No request timeout configuration
|
|
17
|
+
- ✅ Response format parsing is robust
|
|
18
|
+
|
|
19
|
+
#### 2. **Anthropic Adapter - Embedding Not Implemented**
|
|
20
|
+
- ❌ `get_embedding()` and `get_embeddings()` raise NotImplementedError
|
|
21
|
+
- ❌ No fallback mechanism to suggest alternatives
|
|
22
|
+
- ❌ Requires manual setup with external embedding provider
|
|
23
|
+
- ⚠️ Prompt-based JSON formatting is fragile, could fail with long schemas
|
|
24
|
+
|
|
25
|
+
#### 3. **Gemini Adapter - API Incompatibility Risk**
|
|
26
|
+
- ❌ Using experimental `google-genai` library (not stable)
|
|
27
|
+
- ❌ Message format conversion may lose information
|
|
28
|
+
- ❌ No handling of Gemini-specific response formats (safety ratings, etc.)
|
|
29
|
+
- ❌ Missing configuration defaults for safety settings
|
|
30
|
+
|
|
31
|
+
#### 4. **Ollama Adapter - No Validation**
|
|
32
|
+
- ❌ No check for Ollama server availability
|
|
33
|
+
- ❌ No model availability verification
|
|
34
|
+
- ❌ No handling of malformed local responses
|
|
35
|
+
- ⚠️ Assumes localhost:11434 without configuration
|
|
36
|
+
|
|
37
|
+
#### 5. **LiteLLM Adapter - Incomplete**
|
|
38
|
+
- ❌ Minimal implementation, missing error handling
|
|
39
|
+
- ❌ No support for response schema validation
|
|
40
|
+
- ❌ No provider-specific optimizations
|
|
41
|
+
|
|
42
|
+
#### 6. **Integration Issues**
|
|
43
|
+
- ❌ FastAPI middleware doesn't handle missing X-Session-ID gracefully
|
|
44
|
+
- ❌ Flask integration may have threading issues with ContextVar
|
|
45
|
+
- ❌ No rate limiting or circuit breaker at integration layer
|
|
46
|
+
- ❌ Missing request/response logging for debugging
|
|
47
|
+
- ❌ No support for distributed tracing (OpenTelemetry)
|
|
48
|
+
|
|
49
|
+
### HIGH PRIORITY ISSUES
|
|
50
|
+
|
|
51
|
+
#### 7. **Shared Concerns Across All Adapters**
|
|
52
|
+
- ❌ No structured logging
|
|
53
|
+
- ❌ No metrics/observability (request latency, errors, etc.)
|
|
54
|
+
- ❌ No explicit timeout handling
|
|
55
|
+
- ❌ No request deduplication (idempotency)
|
|
56
|
+
- ❌ Missing documentation on required environment variables
|
|
57
|
+
- ❌ No health check mechanism
|
|
58
|
+
|
|
59
|
+
#### 8. **Response Parsing Fragility**
|
|
60
|
+
- ❌ All adapters assume specific response structures
|
|
61
|
+
- ❌ No fallback if response format changes
|
|
62
|
+
- ❌ Minimal validation of extracted text
|
|
63
|
+
|
|
64
|
+
#### 9. **Embedding Consistency**
|
|
65
|
+
- ❌ Different embedding models have different dimensions
|
|
66
|
+
- ❌ No automatic model dimension discovery
|
|
67
|
+
- ❌ No validation that embedding dimensions match stored dimensions
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## RECOMMENDATIONS
|
|
72
|
+
|
|
73
|
+
### IMMEDIATE (Must Fix for Production)
|
|
74
|
+
1. Add retry logic with exponential backoff to all adapters
|
|
75
|
+
2. Implement proper embedding support or validation for Anthropic
|
|
76
|
+
3. Add structured logging throughout
|
|
77
|
+
4. Implement health checks for all providers
|
|
78
|
+
5. Add request timeout configuration
|
|
79
|
+
|
|
80
|
+
### SHORT-TERM (Should Fix)
|
|
81
|
+
1. Add request deduplication / idempotency
|
|
82
|
+
2. Implement proper error categorization (transient vs permanent)
|
|
83
|
+
3. Add metrics collection (latency, errors, model drift)
|
|
84
|
+
4. Add OpenTelemetry support for distributed tracing
|
|
85
|
+
5. Validate embedding dimensions match cached values
|
|
86
|
+
|
|
87
|
+
### LONG-TERM (Nice to Have)
|
|
88
|
+
1. Provider-specific optimizations and features
|
|
89
|
+
2. Advanced caching strategies
|
|
90
|
+
3. A/B testing framework for models
|
|
91
|
+
4. Cost tracking per request
|
|
92
|
+
5. Provider health dashboards
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## FILES AFFECTED
|
|
97
|
+
|
|
98
|
+
### Adapters (Need Updates)
|
|
99
|
+
- `beliefstate/adapters/base.py` - Add health check protocol
|
|
100
|
+
- `beliefstate/adapters/openai.py` - Add retry, timeout, validation
|
|
101
|
+
- `beliefstate/adapters/anthropic.py` - Add embedding fallback
|
|
102
|
+
- `beliefstate/adapters/gemini.py` - Add safety handling, validation
|
|
103
|
+
- `beliefstate/adapters/ollama.py` - Add server validation
|
|
104
|
+
- `beliefstate/adapters/litellm.py` - Expand implementation
|
|
105
|
+
- `beliefstate/adapters/common.py` - NEW: Shared utilities (retry, logging, etc.)
|
|
106
|
+
|
|
107
|
+
### Integrations (Need Updates)
|
|
108
|
+
- `beliefstate/integrations/fastapi.py` - Add error handling, logging
|
|
109
|
+
- `beliefstate/integrations/flask.py` - Add thread safety, logging
|
|
110
|
+
- `beliefstate/integrations/asgi.py` - Add middleware chain support
|
|
111
|
+
- `beliefstate/integrations/common.py` - NEW: Shared integration utilities
|
|
112
|
+
|
|
113
|
+
### New Files
|
|
114
|
+
- `beliefstate/observability.py` - Logging, metrics, tracing
|
|
115
|
+
- `beliefstate/resilience.py` - Already exists, enhance with more patterns
|
|
116
|
+
- `beliefstate/health.py` - NEW: Health check utilities
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## SUCCESS CRITERIA
|
|
121
|
+
|
|
122
|
+
- ✅ All adapters have retry logic with exponential backoff
|
|
123
|
+
- ✅ All adapters have timeout configuration
|
|
124
|
+
- ✅ All adapters validate initialization (API keys, model availability)
|
|
125
|
+
- ✅ All adapters have structured logging
|
|
126
|
+
- ✅ All adapters have health check methods
|
|
127
|
+
- ✅ All adapters handle embedding requirements explicitly
|
|
128
|
+
- ✅ All integrations have error handling middleware
|
|
129
|
+
- ✅ All integrations have request logging
|
|
130
|
+
- ✅ All 37 existing tests still pass
|
|
131
|
+
- ✅ No breaking API changes
|
|
132
|
+
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# BeliefState: Critical Blockers - Verified Status
|
|
2
|
+
|
|
3
|
+
## Status Summary
|
|
4
|
+
This document audits the 4 "CRITICAL" blockers identified in the requirements against the actual codebase.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## BLOCKER #1: Belief @dataclass vs Pydantic BaseModel
|
|
9
|
+
|
|
10
|
+
**STATUS**: ✅ **ALREADY FIXED**
|
|
11
|
+
|
|
12
|
+
**Finding**: `models.py` already uses Pydantic BaseModel with field validation:
|
|
13
|
+
```python
|
|
14
|
+
class Belief(BaseModel):
|
|
15
|
+
subject: str
|
|
16
|
+
predicate: str
|
|
17
|
+
value: str
|
|
18
|
+
confidence: float = Field(ge=0.0, le=1.0) # ← Validation present
|
|
19
|
+
turn: int
|
|
20
|
+
source: str
|
|
21
|
+
embedding: List[float] = Field(default_factory=list)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Verification**:
|
|
25
|
+
- RedisStore calls `belief.model_dump_json()` → works ✅
|
|
26
|
+
- SQLiteStore calls `Belief()` constructor → works ✅
|
|
27
|
+
- Field validation `ge=0.0, le=1.0` → present ✅
|
|
28
|
+
|
|
29
|
+
**Action**: No fix needed for this task. Can mark #1 as complete, but add architecture enhancements:
|
|
30
|
+
- Add `embedding_model: str` field (Task #7)
|
|
31
|
+
- Add `created_at: datetime` field for TTL tracking
|
|
32
|
+
- Add session context if needed
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## BLOCKER #2: LocalNLIJudge Event Loop Blocking
|
|
37
|
+
|
|
38
|
+
**STATUS**: ✅ **ALREADY FIXED**
|
|
39
|
+
|
|
40
|
+
**Finding**: `judge.py` LocalNLIJudge.check() already uses `run_in_executor()`:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
async def check(self, old: Belief, new: Belief) -> Tuple[bool, float, str]:
|
|
44
|
+
# ...
|
|
45
|
+
loop = asyncio.get_running_loop()
|
|
46
|
+
pipeline_fn = self._pipeline
|
|
47
|
+
|
|
48
|
+
# ✅ Runs in thread pool, doesn't block event loop
|
|
49
|
+
res = await loop.run_in_executor(
|
|
50
|
+
None,
|
|
51
|
+
lambda: pipeline_fn({"text": premise, "text_pair": hypothesis})
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Verification**:
|
|
56
|
+
- CPU-bound NLI inference wrapped in executor ✅
|
|
57
|
+
- Event loop not blocked ✅
|
|
58
|
+
|
|
59
|
+
**Action**: No fix needed for this task. Mark #2 as complete.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## BLOCKER #3: SQLiteBeliefStore Persistent Connection
|
|
64
|
+
|
|
65
|
+
**STATUS**: ✅ **PARTIALLY FIXED** (reuses connection, but no lifecycle mgmt)
|
|
66
|
+
|
|
67
|
+
**Finding**: SQLiteStore uses `_get_connection()` for connection reuse:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
async def _get_connection(self) -> Any:
|
|
71
|
+
if self._conn is None:
|
|
72
|
+
# ...
|
|
73
|
+
self._conn = await aiosqlite.connect(self.db_path)
|
|
74
|
+
# ...
|
|
75
|
+
return self._conn # ← Reused across all calls
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**What works**:
|
|
79
|
+
- Connection is reused (not reopened per call) ✅
|
|
80
|
+
- `:memory:` database works because same connection is reused ✅
|
|
81
|
+
- File-based DB avoids connection pool exhaustion ✅
|
|
82
|
+
|
|
83
|
+
**What's missing**:
|
|
84
|
+
- No explicit `open()` / `close()` / context manager interface
|
|
85
|
+
- Connection never cleaned up (no `__del__` or `await close()`)
|
|
86
|
+
- Tests can't do `async with store: ...` cleanup
|
|
87
|
+
|
|
88
|
+
**Action**: Add lifecycle management:
|
|
89
|
+
```python
|
|
90
|
+
async def open(self) -> None:
|
|
91
|
+
"""Explicitly open and initialize the database."""
|
|
92
|
+
await self._get_connection()
|
|
93
|
+
|
|
94
|
+
async def close(self) -> None:
|
|
95
|
+
"""Explicitly close the database connection."""
|
|
96
|
+
if self._conn:
|
|
97
|
+
await self._conn.close()
|
|
98
|
+
self._conn = None
|
|
99
|
+
|
|
100
|
+
async def __aenter__(self):
|
|
101
|
+
await self.open()
|
|
102
|
+
return self
|
|
103
|
+
|
|
104
|
+
async def __aexit__(self, *args):
|
|
105
|
+
await self.close()
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This is an **enhancement**, not a critical blocker. The current code works but lacks hygiene.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## BLOCKER #4: Demo Mock Mode Bypasses Pipeline
|
|
113
|
+
|
|
114
|
+
**STATUS**: ⚠️ **PARTIALLY VERIFIED**
|
|
115
|
+
|
|
116
|
+
**Finding**: Current `demo.py` uses real Ollama, not mocks:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
@tracker.wrap
|
|
120
|
+
async def chat_with_ollama(messages):
|
|
121
|
+
client = ollama.AsyncClient()
|
|
122
|
+
response = await client.chat(model="qwen2.5:7b", messages=messages)
|
|
123
|
+
return response
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Analysis**:
|
|
127
|
+
- ✅ Uses real Ollama (not hardcoded mock)
|
|
128
|
+
- ✅ Real extractor runs (not replaced with mock)
|
|
129
|
+
- ✅ Real adapter normalization happens
|
|
130
|
+
- ✅ Real pipeline executes
|
|
131
|
+
- ⚠️ Problem: Requires Ollama running locally to execute
|
|
132
|
+
|
|
133
|
+
**Why previous note said "mock mode"**:
|
|
134
|
+
- The requirement snippet mentioned: "When OPENAI_API_KEY is absent, demo.py replaces the entire extractor with hardcoded mock"
|
|
135
|
+
- This doesn't exist in current code
|
|
136
|
+
- The current demo just calls real Ollama
|
|
137
|
+
|
|
138
|
+
**Improvement Opportunity**:
|
|
139
|
+
Use `respx` to mock HTTP calls so demo works without external services:
|
|
140
|
+
```python
|
|
141
|
+
with respx.mock:
|
|
142
|
+
respx.post("https://api.ollama.ai/chat").mock(
|
|
143
|
+
return_value=httpx.Response(200, json=MOCK_RESPONSE)
|
|
144
|
+
)
|
|
145
|
+
await chat_with_ollama(messages)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This is an **enhancement for reliability**, not a critical blocker.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## SUMMARY: Which Blockers Are Real?
|
|
153
|
+
|
|
154
|
+
| # | Blocker | Status | Impact | Action |
|
|
155
|
+
|---|---------|--------|--------|--------|
|
|
156
|
+
| 1 | Belief dataclass | ✅ Fixed | None | Mark complete |
|
|
157
|
+
| 2 | Event loop blocking | ✅ Fixed | None | Mark complete |
|
|
158
|
+
| 3 | SQLite connection | ⚠️ Works but inelegant | Low | Add lifecycle mgmt (enhancement) |
|
|
159
|
+
| 4 | Demo mocking | ✅ Uses real Ollama | Low | Add respx mocking (improvement) |
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Actual Blockers to Address
|
|
164
|
+
|
|
165
|
+
The real issues are in the **ARCH** category (tasks #5-10):
|
|
166
|
+
|
|
167
|
+
1. **Dual-adapter pattern**: ✅ **ALREADY IMPLEMENTED**
|
|
168
|
+
- `internal_adapter` parameter exists in `BeliefTracker.__init__`
|
|
169
|
+
- Used for background tasks (extraction, detection)
|
|
170
|
+
- Working as designed
|
|
171
|
+
|
|
172
|
+
2. **No max_beliefs enforcement**: ⚠️ **REAL ISSUE**
|
|
173
|
+
- Current: `get_context_prompt()` iterates all beliefs
|
|
174
|
+
- Needed: Cap at `config.max_beliefs` (default 50)
|
|
175
|
+
|
|
176
|
+
3. **No embedding_model versioning**: Dimension mismatch crashes silently
|
|
177
|
+
- Current: Embeddings lack source info
|
|
178
|
+
- Needed: Store `embedding_model` field per belief
|
|
179
|
+
|
|
180
|
+
4. **No ASK escalation**: Same conflict loops forever
|
|
181
|
+
- Current: ASK conflict notes stack infinitely
|
|
182
|
+
- Needed: Track conflicts, escalate to BLOCK if unresolved
|
|
183
|
+
|
|
184
|
+
5. **Distributed dispatcher session leak**: Celery/RQ lose session context
|
|
185
|
+
- Current: ContextVar doesn't cross process boundary
|
|
186
|
+
- Needed: Serialize session_id in task payload
|
|
187
|
+
|
|
188
|
+
6. **No entailment deduplication**: Duplicate beliefs clutter store
|
|
189
|
+
- Current: "likes Python" and "enjoys Python" both stored
|
|
190
|
+
- Needed: Use entailment score to deduplicate
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Revised Task Priority
|
|
195
|
+
|
|
196
|
+
**Mark complete (already done)**:
|
|
197
|
+
- #1 Belief Pydantic ✅
|
|
198
|
+
- #2 Event loop ✅
|
|
199
|
+
- #5 Dual-adapter ✅ (already in tracker.py)
|
|
200
|
+
|
|
201
|
+
**Real fixes needed (ARCH + missing features)**:
|
|
202
|
+
1. Add `max_beliefs` cap to `get_context_prompt()` (Task #6)
|
|
203
|
+
2. Add embedding_model field to prevent dimension mismatch (Task #7)
|
|
204
|
+
3. Implement ASK escalation logic (Task #8)
|
|
205
|
+
4. Fix Celery/RQ session_id propagation (Task #9)
|
|
206
|
+
5. Add entailment deduplication (Task #10)
|
|
207
|
+
6. Add public query API (Task #11)
|
|
208
|
+
7. Implement adapter auto-detection (Task #12)
|
|
209
|
+
8. Add streaming support (Task #13)
|
|
210
|
+
9. Store-level TTL (Task #14)
|
|
211
|
+
10. OpenTelemetry integration (Task #15)
|
|
212
|
+
|
|
213
|
+
**Nice-to-have enhancements**:
|
|
214
|
+
- #3 SQLite lifecycle management (open/close context mgr)
|
|
215
|
+
- #4 Demo respx mocking for reliability
|
|
216
|
+
|