Merge lk v0.0.1 to main - #2
Merged
Merged
Conversation
Black 24.3 runs identically on 3.11 and 3.12 — the pin only forced pre-commit to spawn a python3.11 interpreter for its hook environment, which broke `pre-commit install` on machines without 3.11 (CI matrix still covers both versions independently).
…ation demo
Bug: LearnKit(scope=...) was stored on the instance but never propagated
to records created in _post_process_now. Distiller-produced skills/facts/
failures/traces and the low-quality FailureRecord fallback all inherited
the schema default ("team"). Any user who configured a non-default scope
wrote records as "team" but retrieved with their custom scope -> zero hits
forever. Discovered while building the LangChain demo, where run 2 kept
getting `Context injected: 0 chars` despite 17 records being written by
run 1.
- learnkit/core.py: set `.scope = self.scope` on every record before backend.add()
- tests/test_phase3.py: regression test exercising the full sync loop and
reading both a skill and a failure back to assert scope round-trips
- examples/langchain_demo.py: real LangChain 1.x integration (create_agent
+ ChatAnthropic + tool calls) wrapped with @memory.agent. Same task run
twice against a file-backed SQLite store; demonstrates the compounding-
memory thesis: RUN 1 Context=0, RUN 2 Context=610 chars.
- pyproject.toml: add [langchain] optional extra
(langchain, langchain-anthropic, langchain-core).
- improvements.md: log this fix; add two follow-ups discovered along the
way (post-process worker-pool shutdown race; scope validation deferred
to read-time poisons the row).
Tests: 33 passed.
Per Shiva's first ask ("first README marchu how to run learnkit and
integrate to your agents"), replace the conceptual-only README with
runnable instructions. Existing 'Fine-Tuning Without Fine-Tuning' intro
and three-loop philosophy section are preserved verbatim; everything
below is new.
New sections, all grounded in what is verified to work today:
- Install: pip install -e . [+ extras], persistent ANTHROPIC_API_KEY setup
- 60-second quick start: maps quick_start.py's 5 parts to what they exercise
- Wrap your agent — 5 lines: the @memory.agent decorator pattern from
agents.md §1283
- Integrate with LangChain: points to examples/langchain_demo.py with the
cold/warm context comparison (0 vs 610 chars)
- How it works — the 8-step loop: lifted from agents.md, condensed
- Memory model: the 7 record types and which activate immediately vs
go to quarantine (per ReaComp)
- Maintenance: maintain_memory(weeks, decay_rate, quarantine_hours)
- Architecture & contributing: pointers to agents.md / AGENTS_V2.md /
improvements.md, pytest + pre-commit setup
- Status: marks v0.1.0 MVP, points at AGENTS_V2.md for hardening plan
Tests still 33 passing.
The build-test job was installing only 'hatchling' (the PEP 517 backend), but the wheel step runs 'python -m build' which requires the 'build' package as the frontend. All 7 CI runs since the workflow landed failed on the "Build package (wheel)" step for this reason. Reproduced locally: with 'build' present, 'python -m build' produces learnkit-0.1.0.tar.gz and learnkit-0.1.0-py3-none-any.whl cleanly.
The publish job has been failing red on every push because TEST_PYPI_TOKEN is not configured as a repo secret. Workflow already had a "remove or replace with real PyPI config when ready" comment on it, so this is a placeholder rather than a real release pipeline. Fix: expose the secret as a job-level env var (secrets context isn't available in job-level `if`) and gate the upload step on env.TEST_PYPI_TOKEN being non-empty. Now: - Token unset: build + sdist + wheel still run (verifying the publish path), upload step is skipped, job conclusion is success. - Token set: upload runs automatically. No further workflow change needed when shipping starts.
Two cleanups against the annotations on CI run #9. 1. mypy: type self.scope properly The scope-plumbing fix in 0b7f3fe introduced 5 mypy errors because self.scope was typed as str (the __init__ default) but record.scope is Literal['user','team','public']. Import MemoryScope from schemas/base and use it on the __init__ parameter -- mypy now infers self.scope correctly and all 6 introduced errors go away (overall: 25 -> 19 mypy errors; the remaining 19 are pre-existing Shiva code + missing library stubs, deferred to lk_v0.0.1). Also rename the for-loop variables in _post_process_now from `f` to `fact`/`failure` so mypy stops conflating the two list element types. 2. ci: bump checkout@v4 -> v5 and setup-python@v5 -> v6 GitHub is forcing all Node.js 20 actions to Node.js 24 on 2026-06-02 (5 days). Both checkout and setup-python have shipped versions that support Node 24. Silences the 3 deprecation warnings. Tests still 33 passing. mypy on learnkit/core.py now clean.
…oken budget
First tier of AGENTS_V2 production hardening on a new
production-hardening branch (lk_v0.0.1 stays the MVP snapshot).
A1 - Quarantine excluded from active retrieval (already done, verified)
SQLiteBackend.search at lines 374/385 already filters
AND r.status != 'quarantine'. tests/test_backend_contract.py:194 pins it.
A2 - Write-time scope validation
SQLiteBackend.add now raises BackendError if record.scope is not in
{"user","team","public"}. Pydantic validates on construction but
validate_assignment defaults to False, so a post-construction mutation
could previously write a poison row that blew up on the next read.
A3 - atexit drain of post-processing worker pool
LearnKit.__init__ registers a weakref-based atexit handler that calls
self.shutdown(wait=True). New shutdown() method is idempotent.
_post_process_async falls back to sync if pool is already shut down.
Eliminates the LearnKit-pool "after shutdown" warning class. A narrower
race remains when the evaluator's in-flight LLM client schedules
sub-tasks after sys.is_finalizing() returns True - error becomes
"after interpreter shutdown" and evaluator's heuristic fallback kicks in.
A4 - Router token budget enforcement (AGENTS_V2 Task H8)
MemoryRouter.route now caps results at both max_records (8) AND
max_tokens (~1200). Char-cost estimator mirrors composer output.
Priority preserved: failure > skill > fact > others. Always admits
at least one record even if oversized.
LangChain demo run 2 went from 610 to 924 chars (better packing).
Tests: 33 -> 41 passing (+8 in tests/test_production_hardening.py).
Mypy on touched files: only 4 pre-existing errors in sqlite.py
(Path union-attr, sqlite_vec stubs, _bm25_score dynamic attr).
production-hardening Tier A: scope validation, worker drain, router t…
siddhu1716
added a commit
that referenced
this pull request
May 27, 2026
Merge pull request #2 from siddhu1716/main
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.