Skip to content

Merge lk v0.0.1 to main - #2

Merged
siddhu1716 merged 8 commits into
lk_v0.0.1from
main
May 27, 2026
Merged

Merge lk v0.0.1 to main #2
siddhu1716 merged 8 commits into
lk_v0.0.1from
main

Conversation

@siddhu1716

Copy link
Copy Markdown
Owner

No description provided.

Akash346 and others added 8 commits May 26, 2026 21:42
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
siddhu1716 merged commit d969957 into lk_v0.0.1 May 27, 2026
3 checks passed
siddhu1716 added a commit that referenced this pull request May 27, 2026
Merge pull request #2 from siddhu1716/main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants