Metadata-Version: 2.4
Name: concinno-skills-memory
Version: 0.1.0
Summary: Concinno's progressive-disclosure memory store — three-layer index/summary/archive with ZIQ noise-filter outcome wiring.
Project-URL: Homepage, https://github.com/aiking931931/concinno
Project-URL: Documentation, https://github.com/aiking931931/concinno/blob/main/projects/concinno-skills-memory/README.md
Project-URL: Repository, https://github.com/aiking931931/concinno
Project-URL: Issues, https://github.com/aiking931931/concinno/issues
Project-URL: Changelog, https://github.com/aiking931931/concinno/blob/main/projects/concinno-skills-memory/CHANGELOG.md
Author-email: "AI King (Chen-Xuan Wang)" <me@ai-king.dev>
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
Keywords: agent,concinno,context-management,memory,progressive-disclosure,rag,ziq
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# concinno-skills-memory

> Progressive-disclosure memory store for LLM agents — three layers
> (index / summary / archive) so the agent can scan a cheap top
> layer first and only pay for deeper layers when a keyword hit
> justifies the cost.

Part of the [Concinno](https://github.com/aiking931931/concinno)
ecosystem. Standalone-installable; no runtime dependency on the main
`concinno` package.

## Why this exists

Loading the entire conversation history into every prompt is wasteful.
The progressive-disclosure pattern keeps the per-turn token cost
roughly constant by exposing memories in tiers:

| Layer | Content                | Cost per entry  | When to read              |
|-------|------------------------|-----------------|---------------------------|
| 1     | Topic + headline (≤100 char) | Lowest    | Every turn (auto-loaded)  |
| 2     | Per-topic summary (≤500 char) | Medium   | When a Layer-1 hit looks relevant |
| 3     | Full archive (no cap)  | Highest         | Only when L2 is insufficient |

The agent stays at Layer 1 by default and escalates entry-by-entry
through `expand_memory()`.

## Difference from claude-mem

This package is a **clean rewrite** of the public progressive-disclosure
pattern that `claude-mem` popularised. We:

- read only the public README / docs to learn the pattern;
- copied **no code** (`claude-mem` is AGPL with personal copyright);
- shipped under AGPL-3.0-or-later (the same family Concinno uses).

If you want the full claude-mem MCP server experience, install
[`claude-mem`](https://www.npmjs.com/package/claude-mem) directly. If
you want a tiny Python library you can embed in any agent loop and
wire into Concinno's ZIQ outcome bus, install this.

## Install

```bash
pip install concinno-skills-memory
```

## Usage

```python
from concinno_skills_memory import ProgressiveMemoryStore

store = ProgressiveMemoryStore()

# Write — all three layers populated atomically.
eid = store.add_memory(
    topic="releases",
    content="v0.1.0 shipped on 2026-04-28; first public progressive "
            "disclosure release for the Concinno ecosystem.",
    tags=["release", "0.1.0"],
)

# Step 1 — cheap scan.
hits = store.query_memory("release", layer=1)
for hit in hits:
    print(hit.render())   # "releases: v0.1.0 shipped on..."

# Step 2 — escalate the one entry that looks relevant.
summary = store.expand_memory(hits[0].entry_id, layer=2)
print(summary.summary)

# Step 3 — only if L2 is still not enough.
archive = store.expand_memory(hits[0].entry_id, layer=3)
print(archive.content)
```

## ZIQ noise-filter outcome wiring

This package exports a typed callback contract that the Concinno
`ziq_outcome_bus` uses to learn which layer to escalate to per query
class. We **do not** import `concinno` here — the wire is one-way:
Concinno reads our exported names and registers them.

```python
from concinno_skills_memory import (
    NOISE_FILTER_OUTCOME_NAME,
    NoiseFilterCallback,
    NoiseFilterOutcome,
    reference_noise_filter,
)
```

- `NoiseFilterCallback` — runtime-checkable Protocol; signature is
  `(query: str, fetched_layer: int, fetched_relevance: float) -> NoiseFilterOutcome`.
- `NoiseFilterOutcome` — float subclass clamped to `[0.0, 1.0]`.
- `reference_noise_filter` — heuristic implementation that penalises
  over-fetching (Layer 3 carries a 30 % cost penalty, Layer 2 carries
  15 %, Layer 1 carries none).
- `NOISE_FILTER_OUTCOME_NAME` — stable string the bus keys on
  (`"memory.noise_filter"`).

Production callers can swap `reference_noise_filter` for a learned
scorer or a Haiku judge. The contract is just the callable shape.

## Storage backend

The store is **in-memory only** by design. Persistence (file, SQLite,
vector store, S3) is the caller's choice. A 200-line in-memory
core is easier to embed inside any agent loop than a one-size-fits-all
backend.

## License

AGPL-3.0-or-later. See [LICENSE](LICENSE).

## Status

Alpha (0.1.0). The public API (three layers, three methods, the
outcome contract) is stable for the Concinno 4.4.0 wire. Internal
implementation may change before 1.0.
