kaos-memory 0.0.1.dev0__tar.gz → 0.6.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 (39) hide show
  1. kaos_memory-0.6.0/.gitignore +83 -0
  2. kaos_memory-0.6.0/Dockerfile +46 -0
  3. kaos_memory-0.6.0/Makefile +47 -0
  4. kaos_memory-0.6.0/PKG-INFO +103 -0
  5. kaos_memory-0.6.0/README.md +71 -0
  6. kaos_memory-0.6.0/kaos_memory/__init__.py +56 -0
  7. kaos_memory-0.6.0/kaos_memory/app.py +428 -0
  8. kaos_memory-0.6.0/kaos_memory/client.py +216 -0
  9. kaos_memory-0.6.0/kaos_memory/config.py +201 -0
  10. kaos_memory-0.6.0/kaos_memory/contract.py +224 -0
  11. kaos_memory-0.6.0/kaos_memory/pydantic_ai/__init__.py +37 -0
  12. kaos_memory-0.6.0/kaos_memory/pydantic_ai/adapters.py +152 -0
  13. kaos_memory-0.6.0/kaos_memory/pydantic_ai/toolset.py +204 -0
  14. kaos_memory-0.6.0/kaos_memory/stores.py +583 -0
  15. kaos_memory-0.6.0/kaos_memory/telemetry.py +151 -0
  16. kaos_memory-0.6.0/pyproject.toml +63 -0
  17. kaos_memory-0.6.0/tests/__init__.py +0 -0
  18. kaos_memory-0.6.0/tests/_fakes.py +27 -0
  19. kaos_memory-0.6.0/tests/conftest.py +31 -0
  20. kaos_memory-0.6.0/tests/test_async_offload.py +49 -0
  21. kaos_memory-0.6.0/tests/test_background.py +81 -0
  22. kaos_memory-0.6.0/tests/test_client_service_failuremode.py +126 -0
  23. kaos_memory-0.6.0/tests/test_config.py +109 -0
  24. kaos_memory-0.6.0/tests/test_longterm.py +126 -0
  25. kaos_memory-0.6.0/tests/test_models.py +83 -0
  26. kaos_memory-0.6.0/tests/test_recall.py +118 -0
  27. kaos_memory-0.6.0/tests/test_scope.py +67 -0
  28. kaos_memory-0.6.0/tests/test_service_e2e.py +123 -0
  29. kaos_memory-0.6.0/tests/test_service_health.py +45 -0
  30. kaos_memory-0.6.0/tests/test_shortterm.py +317 -0
  31. kaos_memory-0.6.0/tests/test_stores_smoke.py +56 -0
  32. kaos_memory-0.6.0/tests/test_summary_forget.py +96 -0
  33. kaos_memory-0.6.0/tests/test_telemetry.py +106 -0
  34. kaos_memory-0.6.0/tests/test_write.py +152 -0
  35. kaos_memory-0.6.0/uv.lock +3884 -0
  36. kaos_memory-0.0.1.dev0/PKG-INFO +0 -17
  37. kaos_memory-0.0.1.dev0/README.md +0 -8
  38. kaos_memory-0.0.1.dev0/pyproject.toml +0 -15
  39. kaos_memory-0.0.1.dev0/src/kaos_memory/__init__.py +0 -3
@@ -0,0 +1,83 @@
1
+
2
+ __pycache__/
3
+ .coverage
4
+ .DS_Store
5
+ .eggs/
6
+ .env
7
+ .env.local
8
+ .idea/
9
+ .operator-sdk/
10
+ .pytest_cache/
11
+ .Python
12
+ .venv
13
+ .vscode/
14
+ *.a
15
+ *.egg-info/
16
+ *.log
17
+ *.o
18
+ *.py[cod]
19
+ *.so
20
+ *.swo
21
+ *.swp
22
+ *~
23
+ *$py.class
24
+ # Analysis reports (local only, not committed)
25
+ # Build artifacts
26
+ # Docker
27
+ # Generated KIND E2E values (created by hack/update-kind-e2e-values.sh)
28
+ # Go
29
+ # IDE
30
+ # Kubernetes
31
+ # Operator SDK
32
+ # Planning documents (local only, not committed)
33
+ # Python
34
+ # Test outputs
35
+ awesome-ai-apps
36
+ bin/
37
+ build/
38
+ CLAUDE.md
39
+ cover.out
40
+ develop-eggs/
41
+ dist/
42
+ docker-compose.override.yml
43
+ downloads/
44
+ eggs/
45
+ env/
46
+ ENV/
47
+ go.sum
48
+ hack/kind-e2e-values.yaml
49
+ htmlcov/
50
+ kubeconfig
51
+ kubeconfig.yaml
52
+ lib/
53
+ lib64/
54
+ MEMORY_REPORT.md
55
+ parts/
56
+ PLAN_*
57
+ PLAN-*.md
58
+ PLAN-OTEL-RESULTS.md
59
+ PLAN.md
60
+ REPORT_*.md
61
+ REPORT-*.md
62
+ REPORT.md
63
+ sdist/
64
+ TASKS.md
65
+ var/
66
+ vendor/
67
+ venv/
68
+ wheels/
69
+ PROGRESS.md
70
+ .roborev.toml
71
+ .husky/
72
+
73
+ # Samples data (copied at build time from operator/config/samples)
74
+ kaos-cli/kaos_cli/samples/data/*.yaml
75
+ .obsidian/
76
+ .planning/
77
+ ROADMAP.md
78
+ tmp/
79
+ REPORT*
80
+ PLAN*
81
+
82
+ # Nested clone of the Agentic Identity Broker (separate repo; not part of KAOS)
83
+ agentic-identity-broker/
@@ -0,0 +1,46 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # libpq is required at runtime by psycopg (pure-Python impl) for the pgvector
6
+ # external storage backend; the slim base image does not ship it.
7
+ RUN --mount=type=cache,target=/var/cache/apt \
8
+ apt-get update && apt-get install -y --no-install-recommends libpq5 && \
9
+ rm -rf /var/lib/apt/lists/*
10
+
11
+ # Install UV for dependency management
12
+ RUN --mount=type=cache,target=/root/.cache/pip \
13
+ pip install uv
14
+
15
+ # Copy only dependency files first for better layer caching
16
+ COPY pyproject.toml ./
17
+
18
+ # Install dependencies using UV with cache mount (cached unless pyproject.toml changes).
19
+ # The service image needs the full engine: install the `service` extra.
20
+ RUN --mount=type=cache,target=/root/.cache/uv \
21
+ uv pip compile --extra service pyproject.toml -o requirements.txt && \
22
+ uv pip install --system -r requirements.txt
23
+
24
+ # Copy source code (changes frequently, so copied last)
25
+ COPY kaos_memory/ kaos_memory/
26
+ COPY README.md ./
27
+
28
+ # Install package (no deps - already installed above) for importlib.metadata
29
+ RUN uv pip install --system --no-deps .
30
+
31
+ # Default local-mode data directory (Chroma + SQLite + history live here on a PVC)
32
+ RUN mkdir -p /data/memory && \
33
+ useradd -m -u 65532 memory && chown -R memory:memory /app /data
34
+ USER memory
35
+
36
+ ENV KAOS_MEMORY_STORAGE_TYPE=local \
37
+ KAOS_MEMORY_LOCAL_PATH=/data/memory \
38
+ KAOS_MEMORY_PORT=8080
39
+
40
+ # Health check hits liveness (independent of store/model readiness)
41
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
42
+ CMD python -c "import httpx; httpx.get('http://localhost:8080/healthz').raise_for_status()" || exit 1
43
+
44
+ EXPOSE 8080
45
+
46
+ CMD ["python", "-m", "kaos_memory.app"]
@@ -0,0 +1,47 @@
1
+ .PHONY: help build docker-build run-local test lint format clean
2
+
3
+ IMG ?= axsauze/kaos-memory-service:latest
4
+
5
+ help:
6
+ @echo "KAOS Memory Service build targets:"
7
+ @echo " build - Install dependencies using UV"
8
+ @echo " docker-build - Build the container image"
9
+ @echo " run-local - Run the service locally in local storage mode"
10
+ @echo " test - Run pytest tests"
11
+ @echo " lint - Run linting (black check + type check)"
12
+ @echo " format - Format code with black"
13
+ @echo " clean - Clean build artifacts"
14
+
15
+ # Install dependencies
16
+ build:
17
+ uv pip install -e .[service,dev,pydantic-ai]
18
+
19
+ # Build the container image
20
+ docker-build:
21
+ docker build -t $(IMG) .
22
+
23
+ # Run the service locally in local (Chroma + SQLite) mode.
24
+ # Override the model endpoint with KAOS_MEMORY_MODEL_BASE_URL for real extraction.
25
+ run-local:
26
+ KAOS_MEMORY_STORAGE_TYPE=local \
27
+ KAOS_MEMORY_LOCAL_PATH=$(PWD)/tmp/memory-data \
28
+ KAOS_MEMORY_PORT=8080 \
29
+ python -m kaos_memory
30
+
31
+ # Run tests
32
+ test:
33
+ uv run pytest tests/ -v
34
+
35
+ # Run linting checks (same as CI)
36
+ lint:
37
+ black --check .
38
+ uvx ty@0.0.55 check
39
+
40
+ # Format code with black
41
+ format:
42
+ black .
43
+
44
+ # Clean artifacts
45
+ clean:
46
+ rm -rf build/ dist/ *.egg-info/ __pycache__ .pytest_cache .coverage htmlcov/
47
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
@@ -0,0 +1,103 @@
1
+ Metadata-Version: 2.4
2
+ Name: kaos-memory
3
+ Version: 0.6.0
4
+ Summary: KAOS production-grade agent memory - tiered stores, memory service, and client for Kubernetes agent orchestration
5
+ License: Apache-2.0
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: httpx>=0.25.0
8
+ Requires-Dist: opentelemetry-api>=1.20.0
9
+ Requires-Dist: pydantic>=2.0.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: black>=24.0.0; extra == 'dev'
12
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'dev'
13
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
14
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
15
+ Provides-Extra: pydantic-ai
16
+ Requires-Dist: pydantic-ai<3.0.0,>=2.0.0; extra == 'pydantic-ai'
17
+ Provides-Extra: service
18
+ Requires-Dist: chromadb>=1.5.0; extra == 'service'
19
+ Requires-Dist: fastapi>=0.104.0; extra == 'service'
20
+ Requires-Dist: mem0ai==2.0.10; extra == 'service'
21
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.20.0; extra == 'service'
22
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.41b0; extra == 'service'
23
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.41b0; extra == 'service'
24
+ Requires-Dist: opentelemetry-instrumentation-logging>=0.41b0; extra == 'service'
25
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'service'
26
+ Requires-Dist: pgvector>=0.2.0; extra == 'service'
27
+ Requires-Dist: psycopg[pool]>=3.1.0; extra == 'service'
28
+ Requires-Dist: pydantic-settings>=2.0.0; extra == 'service'
29
+ Requires-Dist: tiktoken>=0.7.0; extra == 'service'
30
+ Requires-Dist: uvicorn>=0.24.0; extra == 'service'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # KAOS Memory
34
+
35
+ `kaos-memory` is the production-grade agent memory library for KAOS: one package that owns the wire contract, the tiered storage engine and HTTP service, the service client, and an optional Pydantic AI integration. It is packaged so consumers only pull what they use.
36
+
37
+ | Install | Modules | Dependencies |
38
+ | --- | --- | --- |
39
+ | `kaos-memory` (core) | `kaos_memory.contract`, `kaos_memory.client` | Pydantic + httpx only |
40
+ | `kaos-memory[service]` | `kaos_memory.app`, `kaos_memory.stores`, `kaos_memory.config` | + Mem0, Chroma/pgvector, tiktoken, FastAPI |
41
+ | `kaos-memory[pydantic-ai]` | `kaos_memory.pydantic_ai` | + Pydantic AI |
42
+
43
+ - **`kaos_memory.contract`** — the single source of truth for the HTTP contract: the `Scope`/`ScopeLevel` identity and the recall/write/forget request and response schemas. Carries no engine or web-framework dependency, so both the service and the client import the same definitions.
44
+ - **`kaos_memory.client`** — `MemoryServiceClient`, the framework-agnostic best-effort HTTP client for the service (recall degrades to empty; write/forget are fail-soft unless `failure_mode="strict"`).
45
+ - **`kaos_memory.pydantic_ai`** — direct Pydantic AI integration: message/turn adapters (`pydantic_message_to_turns`, `reconstruct_message_history`), server-side scope derivation (`scope_from_deps`), and the opt-in memory toolset (`MemoryTools`, `build_memory_toolset`).
46
+
47
+ The service (`[service]` extra) composes two atomic, independently-testable stores:
48
+
49
+ - **`LongTermStore`** — wraps [Mem0](https://github.com/mem0ai/mem0) as a library and exposes scope-mapped `write` / `recall` / `delete` / `delete_scope`. It is the only importer of `mem0`. Owner scoping is applied inside the vector query so recall never crosses tenants.
50
+ - **`ShortTermStore`** — a scope-keyed relational short-term buffer bounding a verbatim recency window by a token budget, with an opt-in fold that compacts evicted turns into a versioned medium-term digest rather than truncating them. Folding is amortised by high/low water marks (evict down to the low mark on crossing the high mark), the digest is kept as append-only versions under a retention cap, and each fold's evicted batch is returned so callers can cascade it to long-term extraction. On Postgres the window is an UNLOGGED table and folds are serialised per scope by an advisory lock so replicas cannot double-fold.
51
+
52
+ Both bind their models to a resolved OpenAI-compatible endpoint (a KAOS `ModelAPI`) via a single `ModelConfig`, and run in one of two storage modes:
53
+
54
+ | Mode | Vector store | Short-term table | Topology |
55
+ | --- | --- | --- | --- |
56
+ | `local` | embedded Chroma | SQLite | single container on one PVC |
57
+ | `external` | pgvector | Postgres | stateless, shared Postgres |
58
+
59
+ ## Scope model
60
+
61
+ A `Scope` names whose memory an operation touches and maps onto a Mem0 owner identifier:
62
+
63
+ | Scope level | Mem0 owner key |
64
+ | --- | --- |
65
+ | `private` | `agent_id` (this agent) |
66
+ | `user` | `user_id` (a principal) |
67
+ | `session` | `run_id` (one run) |
68
+ | `shared` | a reserved shared owner id on `agent_id` |
69
+
70
+ `shared` resolves to a reserved owner id rather than an empty filter because Mem0 rejects an owner-less search. This module ships only the correct translation; fail-closed enforcement is a later phase.
71
+
72
+ ## Development
73
+
74
+ ```bash
75
+ make build # install with dev extras into the active venv
76
+ make test # run the unit tests
77
+ make lint # black --check + ty type check
78
+ make format # black
79
+ ```
80
+
81
+ ### Running the pgvector / Postgres tests
82
+
83
+ The `external`-mode tests are gated behind the `pgvector` marker and a DSN env var. Start a local container and point the tests at it:
84
+
85
+ ```bash
86
+ docker run -d --name kaos-pgv \
87
+ -e POSTGRES_PASSWORD=pw -e POSTGRES_DB=memdb \
88
+ -p 55432:5432 pgvector/pgvector:pg16
89
+
90
+ export KAOS_TEST_PGVECTOR_DSN=postgresql://postgres:pw@localhost:55432/memdb
91
+ pytest tests/ -v
92
+ ```
93
+
94
+ Without the DSN set, the `pgvector`-marked tests are skipped and the local Chroma/SQLite tests run on their own.
95
+
96
+ ## Layout
97
+
98
+ | Module | Purpose |
99
+ | --- | --- |
100
+ | `config.py` | typed storage, model and short-term tier configuration |
101
+ | `stores.py` | the whole storage layer: the `Scope` value object and Mem0 owner mapping, token counting, the OpenAI-compatible model client, the relational short-term store, and the Mem0-backed long-term adapter |
102
+
103
+ The HTTP service, the agent-runtime client, and the operator wiring that resolves this configuration from a `MemoryStore` resource are built in subsequent phases.
@@ -0,0 +1,71 @@
1
+ # KAOS Memory
2
+
3
+ `kaos-memory` is the production-grade agent memory library for KAOS: one package that owns the wire contract, the tiered storage engine and HTTP service, the service client, and an optional Pydantic AI integration. It is packaged so consumers only pull what they use.
4
+
5
+ | Install | Modules | Dependencies |
6
+ | --- | --- | --- |
7
+ | `kaos-memory` (core) | `kaos_memory.contract`, `kaos_memory.client` | Pydantic + httpx only |
8
+ | `kaos-memory[service]` | `kaos_memory.app`, `kaos_memory.stores`, `kaos_memory.config` | + Mem0, Chroma/pgvector, tiktoken, FastAPI |
9
+ | `kaos-memory[pydantic-ai]` | `kaos_memory.pydantic_ai` | + Pydantic AI |
10
+
11
+ - **`kaos_memory.contract`** — the single source of truth for the HTTP contract: the `Scope`/`ScopeLevel` identity and the recall/write/forget request and response schemas. Carries no engine or web-framework dependency, so both the service and the client import the same definitions.
12
+ - **`kaos_memory.client`** — `MemoryServiceClient`, the framework-agnostic best-effort HTTP client for the service (recall degrades to empty; write/forget are fail-soft unless `failure_mode="strict"`).
13
+ - **`kaos_memory.pydantic_ai`** — direct Pydantic AI integration: message/turn adapters (`pydantic_message_to_turns`, `reconstruct_message_history`), server-side scope derivation (`scope_from_deps`), and the opt-in memory toolset (`MemoryTools`, `build_memory_toolset`).
14
+
15
+ The service (`[service]` extra) composes two atomic, independently-testable stores:
16
+
17
+ - **`LongTermStore`** — wraps [Mem0](https://github.com/mem0ai/mem0) as a library and exposes scope-mapped `write` / `recall` / `delete` / `delete_scope`. It is the only importer of `mem0`. Owner scoping is applied inside the vector query so recall never crosses tenants.
18
+ - **`ShortTermStore`** — a scope-keyed relational short-term buffer bounding a verbatim recency window by a token budget, with an opt-in fold that compacts evicted turns into a versioned medium-term digest rather than truncating them. Folding is amortised by high/low water marks (evict down to the low mark on crossing the high mark), the digest is kept as append-only versions under a retention cap, and each fold's evicted batch is returned so callers can cascade it to long-term extraction. On Postgres the window is an UNLOGGED table and folds are serialised per scope by an advisory lock so replicas cannot double-fold.
19
+
20
+ Both bind their models to a resolved OpenAI-compatible endpoint (a KAOS `ModelAPI`) via a single `ModelConfig`, and run in one of two storage modes:
21
+
22
+ | Mode | Vector store | Short-term table | Topology |
23
+ | --- | --- | --- | --- |
24
+ | `local` | embedded Chroma | SQLite | single container on one PVC |
25
+ | `external` | pgvector | Postgres | stateless, shared Postgres |
26
+
27
+ ## Scope model
28
+
29
+ A `Scope` names whose memory an operation touches and maps onto a Mem0 owner identifier:
30
+
31
+ | Scope level | Mem0 owner key |
32
+ | --- | --- |
33
+ | `private` | `agent_id` (this agent) |
34
+ | `user` | `user_id` (a principal) |
35
+ | `session` | `run_id` (one run) |
36
+ | `shared` | a reserved shared owner id on `agent_id` |
37
+
38
+ `shared` resolves to a reserved owner id rather than an empty filter because Mem0 rejects an owner-less search. This module ships only the correct translation; fail-closed enforcement is a later phase.
39
+
40
+ ## Development
41
+
42
+ ```bash
43
+ make build # install with dev extras into the active venv
44
+ make test # run the unit tests
45
+ make lint # black --check + ty type check
46
+ make format # black
47
+ ```
48
+
49
+ ### Running the pgvector / Postgres tests
50
+
51
+ The `external`-mode tests are gated behind the `pgvector` marker and a DSN env var. Start a local container and point the tests at it:
52
+
53
+ ```bash
54
+ docker run -d --name kaos-pgv \
55
+ -e POSTGRES_PASSWORD=pw -e POSTGRES_DB=memdb \
56
+ -p 55432:5432 pgvector/pgvector:pg16
57
+
58
+ export KAOS_TEST_PGVECTOR_DSN=postgresql://postgres:pw@localhost:55432/memdb
59
+ pytest tests/ -v
60
+ ```
61
+
62
+ Without the DSN set, the `pgvector`-marked tests are skipped and the local Chroma/SQLite tests run on their own.
63
+
64
+ ## Layout
65
+
66
+ | Module | Purpose |
67
+ | --- | --- |
68
+ | `config.py` | typed storage, model and short-term tier configuration |
69
+ | `stores.py` | the whole storage layer: the `Scope` value object and Mem0 owner mapping, token counting, the OpenAI-compatible model client, the relational short-term store, and the Mem0-backed long-term adapter |
70
+
71
+ The HTTP service, the agent-runtime client, and the operator wiring that resolves this configuration from a `MemoryStore` resource are built in subsequent phases.
@@ -0,0 +1,56 @@
1
+ """KAOS production-grade agent memory.
2
+
3
+ ``kaos_memory`` is the one source of truth for KAOS memory: the wire contract,
4
+ the tiered storage engine and HTTP service, the service client, and an optional
5
+ Pydantic AI integration. It is packaged so consumers only pull what they use:
6
+
7
+ - the core install exposes the :mod:`kaos_memory.contract` schemas and the
8
+ :class:`~kaos_memory.client.MemoryServiceClient` (Pydantic + httpx only);
9
+ - the ``service`` extra adds the storage engine and FastAPI service
10
+ (:mod:`kaos_memory.app`, :mod:`kaos_memory.stores`, :mod:`kaos_memory.config`),
11
+ which pull the heavy engine dependencies (Mem0, Chroma/pgvector, tiktoken);
12
+ - the ``pydantic-ai`` extra adds :mod:`kaos_memory.pydantic_ai` — message/turn
13
+ adapters and a memory toolset for direct Pydantic AI integration.
14
+
15
+ Only the lightweight contract and client are imported eagerly here; the service
16
+ and Pydantic AI surfaces are imported from their submodules so importing this
17
+ package never drags in the engine or an agent framework.
18
+ """
19
+
20
+ from kaos_memory.client import MemoryServiceClient
21
+ from kaos_memory.contract import (
22
+ SHARED_OWNER,
23
+ FailureMode,
24
+ ForgetRequest,
25
+ ForgetResponse,
26
+ MediumTermContext,
27
+ RecallRequest,
28
+ RecallResponse,
29
+ Scope,
30
+ ScopeLevel,
31
+ ShortTermContext,
32
+ Turn,
33
+ WriteRequest,
34
+ WriteResponse,
35
+ scope_key,
36
+ )
37
+
38
+ __version__ = "0.4.8.dev0"
39
+
40
+ __all__ = [
41
+ "MemoryServiceClient",
42
+ "Scope",
43
+ "ScopeLevel",
44
+ "SHARED_OWNER",
45
+ "scope_key",
46
+ "FailureMode",
47
+ "RecallRequest",
48
+ "RecallResponse",
49
+ "WriteRequest",
50
+ "WriteResponse",
51
+ "ForgetRequest",
52
+ "ForgetResponse",
53
+ "Turn",
54
+ "ShortTermContext",
55
+ "MediumTermContext",
56
+ ]