curu-memory 0.2.0__tar.gz → 0.3.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 (351) hide show
  1. {curu_memory-0.2.0 → curu_memory-0.3.0}/CHANGELOG.md +13 -0
  2. curu_memory-0.2.0/README.md → curu_memory-0.3.0/PKG-INFO +81 -11
  3. curu_memory-0.2.0/PKG-INFO → curu_memory-0.3.0/README.md +61 -30
  4. {curu_memory-0.2.0 → curu_memory-0.3.0}/pyproject.toml +9 -2
  5. curu_memory-0.3.0/src/curu_memory/__init__.py +52 -0
  6. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/__main__.py +37 -70
  7. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/access.py +73 -1
  8. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/auth.py +2 -1
  9. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/config.py +2 -0
  10. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/embedders.py +16 -0
  11. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/errors.py +3 -18
  12. curu_memory-0.3.0/src/curu_memory/library.py +205 -0
  13. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/server.py +27 -16
  14. curu_memory-0.3.0/tests/contract/public_api.txt +20 -0
  15. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_cli_search.py +3 -3
  16. curu_memory-0.3.0/tests/e2e/test_core_install.py +104 -0
  17. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_leak_paths.py +20 -0
  18. curu_memory-0.3.0/tests/e2e/test_library.py +182 -0
  19. curu_memory-0.3.0/tests/e2e/test_library_access.py +179 -0
  20. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_no_secrets.py +3 -3
  21. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/conftest.py +2 -2
  22. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_access.py +127 -0
  23. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_embedder_http.py +12 -0
  24. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_errors.py +10 -1
  25. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_packaging.py +27 -0
  26. curu_memory-0.3.0/tests/unit/test_public_api.py +58 -0
  27. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_readme.py +26 -5
  28. curu_memory-0.2.0/src/curu_memory/__init__.py +0 -3
  29. {curu_memory-0.2.0 → curu_memory-0.3.0}/.gitignore +0 -0
  30. {curu_memory-0.2.0 → curu_memory-0.3.0}/LICENSE +0 -0
  31. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/audit.py +0 -0
  32. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/browser.py +0 -0
  33. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/indexing.py +0 -0
  34. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/media.py +0 -0
  35. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/oidc.py +0 -0
  36. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/okf.py +0 -0
  37. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/ports.py +0 -0
  38. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/render.py +0 -0
  39. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/retrieval.py +0 -0
  40. {curu_memory-0.2.0 → curu_memory-0.3.0}/src/curu_memory/store_sqlite.py +0 -0
  41. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/__init__.py +0 -0
  42. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/conftest.py +0 -0
  43. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/contract/__init__.py +0 -0
  44. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/contract/test_index_store.py +0 -0
  45. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/contract/test_store_spaces.py +0 -0
  46. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/__init__.py +0 -0
  47. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_browser.py +0 -0
  48. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_browser_media.py +0 -0
  49. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_cli_access.py +0 -0
  50. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_cli_browse.py +0 -0
  51. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_cli_index.py +0 -0
  52. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_concept_tools.py +0 -0
  53. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_http_agents.py +0 -0
  54. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_http_oidc.py +0 -0
  55. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_search_by_media_tool.py +0 -0
  56. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_search_tool.py +0 -0
  57. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_stdio_process.py +0 -0
  58. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/e2e/test_transports.py +0 -0
  59. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/1272-128104-0008.flac +0 -0
  60. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/1272-128104-0010.flac +0 -0
  61. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/1272-135031-0003.flac +0 -0
  62. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/1272-135031-0004.flac +0 -0
  63. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/1272-135031-0015.flac +0 -0
  64. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/1272-135031-0023.flac +0 -0
  65. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/README.md +0 -0
  66. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/query-1272-128104-0008.mp3 +0 -0
  67. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/query-1272-128104-0010.mp3 +0 -0
  68. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/query-1272-135031-0003.mp3 +0 -0
  69. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/query-1272-135031-0004.mp3 +0 -0
  70. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/query-1272-135031-0015.mp3 +0 -0
  71. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/query-1272-135031-0023.mp3 +0 -0
  72. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/tiny.flac +0 -0
  73. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/tiny.mp3 +0 -0
  74. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/tiny.ogg +0 -0
  75. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio/tiny.wav +0 -0
  76. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/audio_eval.toml +0 -0
  77. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/bad-yaml.md +0 -0
  78. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/dup/same-name.md +0 -0
  79. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/link-no-kind.md +0 -0
  80. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/link-unknown-kind.md +0 -0
  81. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/no-description.md +0 -0
  82. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/no-front-matter.md +0 -0
  83. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/same-name.md +0 -0
  84. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/valid.md +0 -0
  85. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/bad_corpus/wiki-link.md +0 -0
  86. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/README.md +0 -0
  87. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-calibration-delta-without-its-coverage-is-a-claim-the-reader-cannot-audit.md +0 -0
  88. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-calibration-run-scored-an-embellished-phrase-a-template-header-and-numbered-criteria.md +0 -0
  89. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-check-nobody-has-executed-is-not-a-check-that-works.md +0 -0
  90. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-cold-load-cut-by-the-proxy-keeps-loading-behind-the-auth-gate-and-api-ps-cannot-say-otherwise.md +0 -0
  91. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-crop-check-that-reports-the-subject-absent-caps-nothing-when-the-box-is-grounded.md +0 -0
  92. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-declared-manifest-filename-nothing-checks-is-a-rented-pod.md +0 -0
  93. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-declared-pin-is-not-applied-until-something-converges-to-it.md +0 -0
  94. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-documented-procedure-is-a-capability-that-does-not-exist.md +0 -0
  95. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-dropped-connection-is-not-an-answer-so-it-is-not-a-permanent-failure.md +0 -0
  96. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-grounded-box-off-its-subject-is-the-models-aim-not-the-coordinate-mapping.md +0 -0
  97. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-grounding-question-that-states-the-place-gets-the-place-back.md +0 -0
  98. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-hermetic-test-that-races-the-machine-decides-nothing.md +0 -0
  99. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-hermetic-tests-isolation-stops-at-the-process-boundary.md +0 -0
  100. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-holder-that-cannot-serve-is-not-a-holder.md +0 -0
  101. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-keep-set-derived-by-its-own-rule-deletes-the-file-it-meant-to-keep.md +0 -0
  102. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-manifest-family-name-is-not-an-atom-family-name.md +0 -0
  103. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-pairwise-judge-is-qualified-against-human-labels-in-both-orders-before-a-campaign-trusts-it.md +0 -0
  104. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-pod-curu-can-name-is-terminated-by-id-not-found-by-listing.md +0 -0
  105. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-pod-that-outlives-its-process-needs-a-third-word-for-who-owns-it.md +0 -0
  106. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-positive-control-that-passes-is-not-evidence-the-judge-can-finish-the-run.md +0 -0
  107. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-pull-request-body-closes-an-issue-you-only-meant-to-name.md +0 -0
  108. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-reasoning-phase-is-charged-to-the-same-output-budget-so-an-empty-answer-is-a-budget-symptom.md +0 -0
  109. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-record-that-names-a-cause-its-own-evidence-contradicts.md +0 -0
  110. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-repair-of-a-run-whose-pod-is-gone-rents-its-family-like-generate.md +0 -0
  111. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-reporting-path-is-handed-liveness-never-left-to-infer-it.md +0 -0
  112. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-requirement-that-says-explicit-can-ship-inferred-and-pass-every-test.md +0 -0
  113. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-research-conclusion-is-a-record-checked-against-the-trace-not-prose.md +0 -0
  114. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-role-binds-when-its-work-runs-not-when-the-plane-is-built.md +0 -0
  115. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-role-model-still-arriving-is-not-a-model-that-is-unavailable.md +0 -0
  116. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-rubric-scored-one-image-at-a-time-saturates-so-compare-pairs-blind-in-both-orders.md +0 -0
  117. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-rule-stated-twice-is-a-rule-that-will-disagree.md +0 -0
  118. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-run-journal-is-a-projection-of-one-file-per-run.md +0 -0
  119. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-run-time-union-is-invisible-to-every-resolver-that-does-not-consult-it.md +0 -0
  120. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-runpod-volume-reports-the-cluster-not-the-volume.md +0 -0
  121. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-scene-is-not-a-controlled-base-until-its-rubric-and-prompt-are-shared.md +0 -0
  122. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-second-entrypoint-does-not-inherit-a-fix-and-nothing-says-so.md +0 -0
  123. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-specialist-model-that-falls-back-to-the-workstation-is-not-slow-it-is-unusable.md +0 -0
  124. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-structural-usability-criterion-cannot-tell-whether-a-model-looked-at-the-image.md +0 -0
  125. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-subgraph-hides-the-nodes-a-workflow-really-needs.md +0 -0
  126. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-substring-substantiation-check-cannot-tell-a-quote-from-an-echo.md +0 -0
  127. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-usable-rate-collapses-silent-vacuity-with-loud-constraint-violation.md +0 -0
  128. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-word-from-the-prose-is-not-a-value-in-the-enum.md +0 -0
  129. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/a-worktree-venv-repoint-hijacks-the-main-checkouts-editable-install.md +0 -0
  130. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/adr-061s-family-gate-covers-only-the-curated-topology-path.md +0 -0
  131. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/after-provisioning-a-run-is-unreported-not-unbounded.md +0 -0
  132. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-api-workflow-does-not-announce-itself-in-its-name.md +0 -0
  133. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-atom-without-a-manifest-is-a-family-that-can-be-chosen-and-never-served.md +0 -0
  134. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-empty-artefact-can-be-an-answer-not-a-gap-to-fill.md +0 -0
  135. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-idle-parent-is-not-a-stalled-run.md +0 -0
  136. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-index-pass-must-record-and-verify-the-revision-it-read.md +0 -0
  137. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-interrupted-ollama-pull-resumes-so-a-stalled-transfer-is-worth-retrying.md +0 -0
  138. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/an-unreachable-backend-is-not-an-empty-one-so-preflight-before-reading-inventory.md +0 -0
  139. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/analyse-intent-context-window-gap.md +0 -0
  140. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/analyse-intent-failure-observability-gap.md +0 -0
  141. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/anatomy-crop-exemplars-are-operator-labelled-balanced-and-never-the-image-checked.md +0 -0
  142. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/anima-qwen-image.md +0 -0
  143. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/anna-frozen.md +0 -0
  144. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/architecture-family-recognition-is-filename-pattern-only.md +0 -0
  145. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/artifact-presence-confidence-is-not-real-calibration.md +0 -0
  146. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/artifact-presence-style-classification-prestep-dead-end.md +0 -0
  147. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/artifact-presence-stylization-wording-dead-end.md +0 -0
  148. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/bounding-a-comfyui-generation-on-silence-not-on-elapsed-time.md +0 -0
  149. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/cheap-deterministic-gate-shipped-inert.md +0 -0
  150. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/checkpoint-larger-than-vram-degrades-not-fails.md +0 -0
  151. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/chroma.md +0 -0
  152. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/comfyui-rescans-model-directories-by-mtime.md +0 -0
  153. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/comfyui-textgen-node.md +0 -0
  154. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/comfyui-upgrade-reaches-latest-not-a-named-version.md +0 -0
  155. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/comfyui-workflow-templates-catalogue.md +0 -0
  156. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/ae-vae.md +0 -0
  157. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/anima-turbo-checkpoint.md +0 -0
  158. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/anima-turbo-lora.md +0 -0
  159. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/chroma-hyper-flash-turbo.md +0 -0
  160. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/chroma1-hd-fp8mixed.md +0 -0
  161. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/clip-g-hidream.md +0 -0
  162. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/clip-l-hidream.md +0 -0
  163. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/flux2-dev-fp8mixed.md +0 -0
  164. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/flux2-vae.md +0 -0
  165. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/gemma-2-2b-fp16.md +0 -0
  166. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/gemma-3-12b-it-fp4-mixed.md +0 -0
  167. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/hidream-ae-vae.md +0 -0
  168. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/hidream-i1-dev-bf16.md +0 -0
  169. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/hunyuan-image-2.1-vae-fp16.md +0 -0
  170. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/hunyuanimage2.1-bf16.md +0 -0
  171. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/krea2-turbo-checkpoint.md +0 -0
  172. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/krea2-turbo-lora-rank64.md +0 -0
  173. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/krea2-turbo-projector-lora.md +0 -0
  174. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/llama-3.1-8b-instruct-fp8-scaled.md +0 -0
  175. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/ltx23-distilled-lora.md +0 -0
  176. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/mistral-3-small-flux2-fp8.md +0 -0
  177. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/omnigen2-fp16.md +0 -0
  178. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-2.5-vl-7b-fp8-scaled.md +0 -0
  179. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-2.5-vl-7b.md +0 -0
  180. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-2.5-vl-fp16.md +0 -0
  181. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-3-06b-base.md +0 -0
  182. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-3-4b.md +0 -0
  183. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-3-8b-fp8mixed.md +0 -0
  184. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-image-fp8-e4m3fn.md +0 -0
  185. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen-image-vae.md +0 -0
  186. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/qwen3vl-4b-fp8-scaled.md +0 -0
  187. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/t5xxl-fp8-e4m3fn-scaled.md +0 -0
  188. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/umt5-xxl-fp8-e4m3fn-scaled.md +0 -0
  189. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-a14b-moe-high-noise-diffusion-model.md +0 -0
  190. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-a14b-moe-low-noise-diffusion-model.md +0 -0
  191. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-lightx2v-high-noise-lora.md +0 -0
  192. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-lightx2v-low-noise-lora.md +0 -0
  193. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-ti2v-5b-diffusion-model.md +0 -0
  194. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-vae-dual-expert.md +0 -0
  195. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/wan22-vae-unified.md +0 -0
  196. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/components/z-image-turbo-bf16.md +0 -0
  197. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/configured-versus-provisioned-model-cross-check.md +0 -0
  198. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/content-frame-fraction-low-key-investigation.md +0 -0
  199. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/corpus-replay-artifact-presence-yield.md +0 -0
  200. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/could-not-do-it-and-nothing-to-do-returned-the-same-value.md +0 -0
  201. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/decompose-shots-native-transport-gap.md +0 -0
  202. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/deterministic-gate-opacity-and-best-attempt-selection-bug.md +0 -0
  203. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/dry-run-provisioning-claims-come-from-the-live-path.md +0 -0
  204. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/eager-role-model-resolution-rents-a-pod-before-any-backend-exists.md +0 -0
  205. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/fft-psd-periodicity-halftone-detector-dead-end.md +0 -0
  206. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/first-last-frame-video-conditioning.md +0 -0
  207. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/flux-klein.md +0 -0
  208. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/flux2.md +0 -0
  209. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/giving-a-rented-pod-back-is-defence-in-depth.md +0 -0
  210. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/graph-prompt-refiner-content-fidelity-gap.md +0 -0
  211. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/hidream.md +0 -0
  212. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/hpsv3-is-an-uncalibrated-second-preference-instrument.md +0 -0
  213. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/hunyuan-image.md +0 -0
  214. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/illustrious.md +0 -0
  215. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/installed-from-a-working-copy-drifts-from-its-source.md +0 -0
  216. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/karras-and-exponential-ignore-flux2s-shift-so-flux2-declares-its-known-good-schedulers.md +0 -0
  217. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/knowledge-is-three-file-tiers-and-the-database-is-only-their-projection.md +0 -0
  218. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/krea2.md +0 -0
  219. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/ltx2-3.md +0 -0
  220. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/lumina2.md +0 -0
  221. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/manifest-tables-must-be-read-through-the-include-chain.md +0 -0
  222. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/minimax-h3.md +0 -0
  223. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/omnigen2.md +0 -0
  224. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/one-backend-per-selection-is-not-one-per-run-so-nothing-stopped-a-second-comfyui-backend.md +0 -0
  225. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/pinning-the-base-image-does-not-pin-what-the-build-installs.md +0 -0
  226. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/pixel-quality-gate-content-class-generalization.md +0 -0
  227. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/pod-volume-must-be-sized-against-the-inherited-llm-set.md +0 -0
  228. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/ponyxl.md +0 -0
  229. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/prompt-refiner-draft-quality-gap.md +0 -0
  230. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/prompt-refiner-loop-convergence-gap.md +0 -0
  231. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/provision-model-civitai-multi-file-version-silent-wrong-pick.md +0 -0
  232. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/quantised-embedding-serving-llama-server.md +0 -0
  233. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/qwen-image.md +0 -0
  234. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/rank-fusion-starves-the-single-best-answer.md +0 -0
  235. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/reported-success-beside-real-failure.md +0 -0
  236. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/revision-seed-patch-mechanism.md +0 -0
  237. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/rife-frame-interpolation.md +0 -0
  238. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/runpod-comfyui-image-missing-zstd-breaks-ollama-install.md +0 -0
  239. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/sam3-multi-entity-disambiguation-limit.md +0 -0
  240. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/sam3-text-grounding-is-the-primary-grounder-the-vlm-its-fallback.md +0 -0
  241. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/saracen9-style-classification-gate-positive-signal.md +0 -0
  242. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/sddb-benchmark-campaign.md +0 -0
  243. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/sddb-video-benchmark-fixtures.md +0 -0
  244. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/seedvr2-rife-combined-pipeline.md +0 -0
  245. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/seedvr2-upscale.md +0 -0
  246. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/shared-gpu-ollama-comfyui-memory-contention.md +0 -0
  247. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/small-decision-encoders-do-not-replace-curus-llm-judgement-calls.md +0 -0
  248. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/some-models-ship-thinking-as-a-separate-tag-so-think-false-cannot-switch-it-off.md +0 -0
  249. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/streaming-does-not-cover-the-wait-for-the-first-byte-and-the-runpod-proxy-cuts-it-at-100s.md +0 -0
  250. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/streaming-ollama-pull-through-runpod-proxy-and-auth-gate.md +0 -0
  251. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/structured-output-field-order-required-fields-affect-decoding-quality.md +0 -0
  252. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/style-aware-artifact-gate-shipped-inert.md +0 -0
  253. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/testcontainers-ephemeral-port-forwarding-failure-mimics-a-red-suite.md +0 -0
  254. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/the-embedder-that-served-a-command-is-not-the-placement-its-config-names.md +0 -0
  255. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/the-glimmer-judge-answered-each-pair-with-one-position-in-both-orders.md +0 -0
  256. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/the-log-that-settles-a-wedge-was-truncated-by-the-next-start.md +0 -0
  257. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/the-second-sigterm-is-the-window-the-first-one-opened.md +0 -0
  258. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/the-three-saracen9-models-are-two-27b-siblings-and-a-9b.md +0 -0
  259. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/the-vlm-branch-measured-capture-provenance-where-the-cheap-gate-measured-style.md +0 -0
  260. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/timeout-discards-the-only-evidence-there-is.md +0 -0
  261. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/two-files-can-claim-one-atom-pairing-filename.md +0 -0
  262. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/two-seed-unanimity-is-not-evidence-and-more-seeds-make-it-credit-less.md +0 -0
  263. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/video-frame-defect-gate-fresh-generation-stress-test.md +0 -0
  264. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/wan22-5b.md +0 -0
  265. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/wan22-a14b-moe.md +0 -0
  266. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/wd14-tagging-structural-malformation-discrimination.md +0 -0
  267. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/whole-corpus-reconciliation-is-incoherent-under-concurrency.md +0 -0
  268. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/workflow-planner-emitted-no-patches-because-the-field-was-optional.md +0 -0
  269. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/curu_concepts/z-image.md +0 -0
  270. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/image_eval.toml +0 -0
  271. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/blue-circle.png +0 -0
  272. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/checkerboard.png +0 -0
  273. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/green-triangle.png +0 -0
  274. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/not-an-image.png +0 -0
  275. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/query-blue-circle.png +0 -0
  276. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/query-checkerboard.png +0 -0
  277. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/query-green-triangle.png +0 -0
  278. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/query-rainbow-stripes.png +0 -0
  279. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/query-red-square.png +0 -0
  280. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/query-sunset.png +0 -0
  281. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/rainbow-stripes.png +0 -0
  282. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/red-square.png +0 -0
  283. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/sunset.png +0 -0
  284. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/tiny.jpg +0 -0
  285. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/tiny.png +0 -0
  286. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/images/tiny.webp +0 -0
  287. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/meaning_eval.toml +0 -0
  288. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/search_eval.toml +0 -0
  289. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/.obsidian/workspace.md +0 -0
  290. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/README.md +0 -0
  291. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/alpha-family.md +0 -0
  292. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/alpha-turbo.md +0 -0
  293. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/cfg-finding.md +0 -0
  294. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/components/alpha-vae.md +0 -0
  295. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/small_corpus/sdxl_base_1.0.md +0 -0
  296. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/README.md +0 -0
  297. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/blue-circle-grows.mp4 +0 -0
  298. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/checkerboard-flashes.mp4 +0 -0
  299. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/green-triangle-turns.mp4 +0 -0
  300. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/query-blue-circle-grows.webm +0 -0
  301. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/query-checkerboard-flashes.webm +0 -0
  302. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/query-green-triangle-turns.webm +0 -0
  303. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/query-rainbow-scrolls.webm +0 -0
  304. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/query-red-square-moves.webm +0 -0
  305. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/query-sun-sets.webm +0 -0
  306. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/rainbow-scrolls.mp4 +0 -0
  307. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/red-square-moves.mp4 +0 -0
  308. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/sun-sets.mp4 +0 -0
  309. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/tiny.mkv +0 -0
  310. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/tiny.mov +0 -0
  311. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/tiny.mp4 +0 -0
  312. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video/tiny.webm +0 -0
  313. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/fixtures/video_eval.toml +0 -0
  314. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/__init__.py +0 -0
  315. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_audio_limit.py +0 -0
  316. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_audio_query_limit.py +0 -0
  317. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_image_limit.py +0 -0
  318. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_image_query_limit.py +0 -0
  319. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_rauthy.py +0 -0
  320. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_real_embedder.py +0 -0
  321. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_similarity_limit.py +0 -0
  322. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_video_limit.py +0 -0
  323. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/integration/test_video_query_limit.py +0 -0
  324. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/support/__init__.py +0 -0
  325. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/support/fake_issuer.py +0 -0
  326. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/support/http_server.py +0 -0
  327. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/__init__.py +0 -0
  328. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_adr_019.py +0 -0
  329. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_audit.py +0 -0
  330. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_auth.py +0 -0
  331. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_cli_help.py +0 -0
  332. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_config.py +0 -0
  333. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_embedders.py +0 -0
  334. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_fusion.py +0 -0
  335. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_index_determinism.py +0 -0
  336. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_indexing.py +0 -0
  337. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_indexing_images.py +0 -0
  338. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_media.py +0 -0
  339. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_oidc.py +0 -0
  340. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_okf.py +0 -0
  341. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_okf_faults.py +0 -0
  342. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_prompts.py +0 -0
  343. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_release_check.py +0 -0
  344. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_render.py +0 -0
  345. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_retrieval.py +0 -0
  346. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_search_eval.py +0 -0
  347. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_spaces.py +0 -0
  348. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_store_threads.py +0 -0
  349. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_store_v1.py +0 -0
  350. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_units.py +0 -0
  351. {curu_memory-0.2.0 → curu_memory-0.3.0}/tests/unit/test_workflows.py +0 -0
@@ -4,6 +4,19 @@ All notable changes to this project are in this file. The format follows [Keep a
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.3.0] - 2026-11-01
8
+
9
+ ### Added
10
+
11
+ - The public Python API in `curu_memory.__all__`: `build_space`, `open_knowledge` and `Knowledge`, with its result types and errors. `Knowledge.search`, `get_concept` and `neighbours` give the results of the matching tools.
12
+ - The library reads as one principal: a person, the agent of one grant, or nobody. It uses the rules of the server, and each refused read writes the same audit line.
13
+ - `tests/contract/public_api.txt`: a test fails when `__all__` changes and the snapshot does not.
14
+
15
+ ### Changed
16
+
17
+ - **Breaking:** `mcp`, `starlette` and `uvicorn` moved to the `server` extra. `serve` and `browse` need `curu-memory[server]`. Without it, they stop with exit code 78 and name the extra. `index`, `search` and `access` need no extra.
18
+ - `tool_result_from` moved from `curu_memory.errors` to `curu_memory.server`, so the errors import no MCP package.
19
+
7
20
  ## [0.2.0] - 2026-11-01
8
21
 
9
22
  This is the first release on PyPI. Version 0.1.0 was not published.
@@ -1,3 +1,23 @@
1
+ Metadata-Version: 2.5
2
+ Name: curu-memory
3
+ Version: 0.3.0
4
+ Summary: A shared knowledge base and GraphRAG store for ComfyUI and generative media, served to agents over MCP.
5
+ Project-URL: Repository, https://github.com/darth-veitcher/curu-memory
6
+ Project-URL: Documentation, https://github.com/darth-veitcher/curu-memory#readme
7
+ Project-URL: Changelog, https://github.com/darth-veitcher/curu-memory/blob/main/CHANGELOG.md
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Requires-Python: >=3.12
11
+ Requires-Dist: httpx2>=2.10
12
+ Requires-Dist: markdown-it-py>=4.0
13
+ Requires-Dist: pydantic>=2.12
14
+ Requires-Dist: pyyaml>=6.0
15
+ Provides-Extra: server
16
+ Requires-Dist: mcp==2.3.0; extra == 'server'
17
+ Requires-Dist: starlette>=1.0; extra == 'server'
18
+ Requires-Dist: uvicorn>=0.31.1; extra == 'server'
19
+ Description-Content-Type: text/markdown
20
+
1
21
  # curu-memory
2
22
 
3
23
  ## What is this
@@ -23,24 +43,25 @@ curu-memory is a shared knowledge base for ComfyUI and generative media. It read
23
43
  | Browse the knowledge in a web browser | `curu-memory browse` | [Browse the knowledge](#browse-the-knowledge) |
24
44
  | Read a concept and its links | The `get_concept` and `concept_neighbours` tools | [Read a concept and follow its links](#read-a-concept-and-follow-its-links) |
25
45
  | Find why a call failed | The `code` of the error | [Handle errors](#handle-errors) |
46
+ | Build and read the knowledge from a Python program | `curu_memory.open_knowledge()` | [Use curu-memory from Python](#use-curu-memory-from-python) |
26
47
 
27
48
  ## Install
28
49
 
29
50
  You need Python 3.12 or later and [uv](https://docs.astral.sh/uv/).
30
51
 
31
52
  ```bash
32
- uv tool install git+https://github.com/darth-veitcher/curu-memory
53
+ uv tool install "curu-memory[server] @ git+https://github.com/darth-veitcher/curu-memory"
33
54
  ```
34
55
 
35
- This installs the `curu-memory` command.
56
+ This installs the `curu-memory` command with the `server` [extra](#glossary). `serve` and `browse` need the extra. Without it, `index`, `search` and `access` work, and `serve` and `browse` stop with exit code 78.
36
57
 
37
58
  To install a release from PyPI, give a version range:
38
59
 
39
60
  ```bash
40
- uv tool install "curu-memory>=0.2,<0.3"
61
+ uv tool install "curu-memory[server]>=0.3,<0.4"
41
62
  ```
42
63
 
43
- A program that uses curu-memory as a library pins the same range in its `pyproject.toml`. A new minor version can change the Python API or the MCP tools, so the range stops before the next minor version.
64
+ A program that uses curu-memory as a library pins a range in its `pyproject.toml`, with no extra. A new minor version can change the Python API or the MCP tools, so the range stops before the next minor version.
44
65
 
45
66
  ## Quickstart
46
67
 
@@ -568,11 +589,58 @@ The `curu-memory` command uses these exit codes:
568
589
  | 0 | Success. |
569
590
  | 1 | `index` skipped a file, the embedder failed, another index run held the lock, or the embedder model was not the model of another space. `search` found no index, or no readable space. `access` refused a change. |
570
591
  | 2 | A usage error, for example `--limit 51`. |
571
- | 78 | A configuration error, for example HTTP with no token. |
592
+ | 78 | A configuration error, for example HTTP with no token, or `serve` with no `server` extra. |
593
+
594
+ ## Use curu-memory from Python
595
+
596
+ Use the library to build a space and to read it from a Python program, with no server. Import each name from `curu_memory` only. The names of `curu_memory.__all__` are the public API. Each other name can change in any release. The public API starts with version 0.3.0, so a program pins `curu-memory>=0.3,<0.4`.
597
+
598
+ ```python
599
+ from pathlib import Path
600
+
601
+ import curu_memory
602
+
603
+ report = curu_memory.build_space(Path("knowledge"))
604
+ print(report.concepts_indexed, len(report.skipped))
605
+
606
+ knowledge = curu_memory.open_knowledge()
607
+ for hit in knowledge.search("VAE for WAN2.2 5B", limit=3).results:
608
+ print(hit.id, hit.space)
609
+
610
+ concept = knowledge.get_concept("wan22-5b-vae")
611
+ links = knowledge.neighbours(concept.id)
612
+ ```
613
+
614
+ - `build_space` builds one space, as the index command does. `space=` names the space, and the default is `global`. A skipped file is not an error. The fields of the report are the values of [Index your knowledge](#index-your-knowledge), except `index`, for example `concepts_indexed`. `skipped` holds a (path, reason) pair for each skipped file.
615
+ - `open_knowledge` reads as one [principal](#glossary). Give `person="<handle>"` to read the spaces of that person. Give `grant=<id>` to read only the space of that grant. With neither, the library reads `global` only.
616
+ - An unknown, ended or revoked grant does not stop `open_knowledge`. Each read then raises `NoReadableSpace`. `serve --grant` stops at the start for such a grant.
617
+ - Each read gets the readable spaces again. A removed role or a revoked grant stops the next read.
618
+ - `search`, `get_concept` and `neighbours` give the same results as the tools `search_knowledge`, `get_concept` and `concept_neighbours`. Each hit gives its `space`.
619
+ - Each refused read writes the line in the audit log that the server writes, with the name of the matching tool as the action.
620
+ - `data_dir=` replaces the data directory. `env=` gives the `CURU_MEMORY_*` variables as a dictionary, for example the embedder settings of [Search by meaning](#search-by-meaning). With no `env`, the library reads the environment of the process.
621
+ - The library does not use `CURU_MEMORY_PRINCIPAL` to select the principal. A value that is not a valid handle raises `ConfigError`.
622
+ - The principal is not a security boundary in one process. The boundary is who can read the data directory.
623
+
624
+ Each error is in `curu_memory`:
625
+
626
+ | Call | Cause | Error |
627
+ |---|---|---|
628
+ | `build_space` | The concept directory does not exist, or the space name is not valid. `details.field` names the argument. | `InvalidArgument` |
629
+ | `build_space` | Another index run holds the lock. | `IndexLocked` |
630
+ | `build_space` | The embedder model is not the model of another space. | `IndexRefused` |
631
+ | `build_space` | The embedder failed. The old index stays. | `EmbedderFailed` |
632
+ | `build_space`, `open_knowledge` | A `CURU_MEMORY_*` variable is not valid. | `ConfigError` |
633
+ | `open_knowledge` | No person has the handle, or `person` and `grant` are both given. | `InvalidArgument` |
634
+ | each read | The principal can read no space. | `NoReadableSpace` |
635
+ | `get_concept`, `neighbours` | No readable space holds the concept. | `ConceptNotFound` |
636
+ | `search` | The question is empty or too long, or the limit is not from 1 to 50. | `InvalidArgument` |
637
+ | each read | No readable space has an index. | `IndexMissing` |
638
+
639
+ Each error except `IndexLocked` and `ConfigError` is a `CuruMemoryError`. Its `code` is the code that a tool gives, for example `concept_not_found`.
572
640
 
573
641
  ## Limits
574
642
 
575
- - On stdio, in the browser and with the static token, one process reads as one person (`CURU_MEMORY_PRINCIPAL`). On stdio, `serve --grant` makes the process read as the agent of one grant. Only the OIDC mode of HTTP gives each request its own person or agent.
643
+ - On stdio, in the browser and with the static token, one process reads as one person (`CURU_MEMORY_PRINCIPAL`). In Python, each `Knowledge` reads as the principal of its `open_knowledge`. On stdio, `serve --grant` makes the process read as the agent of one grant. Only the OIDC mode of HTTP gives each request its own person or agent.
576
644
  - There is no encryption at rest yet.
577
645
  - The browser has no OIDC login.
578
646
  - Agents and persons cannot write knowledge through curu-memory yet. Edit the concept files, then run the index command.
@@ -590,7 +658,7 @@ The `curu-memory` command uses these exit codes:
590
658
  - A match between a question in words and a clip needs 0.68 or more with EmbeddingGemma 2. The limit comes from speech clips. Speech test clips scored from 0.73 with their own questions. Wrong clips and unrelated questions reached 0.64. Music and sound effects can score lower.
591
659
  - The index holds a copy of each media file. One hundred files of 2 MB make the index about 200 MB larger.
592
660
  - There is no file watcher. Run the index command after each change.
593
- - curu-memory has no public Python API yet. Each module is internal.
661
+ - The Python API cannot search with media, and it cannot write a concept. Use `curu-memory search --media` or the tool `search_knowledge_by_media` for media.
594
662
 
595
663
  ## Technical notes
596
664
 
@@ -609,7 +677,8 @@ The `curu-memory` command uses these exit codes:
609
677
  - The concept rules are the same as the rules of the curu index, so each curu concept file indexes here.
610
678
  - The tool contracts are in [specs/001-okf-index-mcp-search/contracts/](specs/001-okf-index-mcp-search/contracts/).
611
679
  - curu-memory uses the official MCP Python SDK. It never loads model weights.
612
- - curu uses curu-memory as a library, and the version range of a release follows a version policy. See [ADR-019](project-management/ADRs/ADR-019-curu-uses-curu-memory-as-a-library.md).
680
+ - curu uses curu-memory as a library, and the version range of a release follows a version policy. See [ADR-019](project-management/ADRs/ADR-019-curu-uses-curu-memory-as-a-library.md). `tests/contract/public_api.txt` holds the names of `curu_memory.__all__`. The contract is [specs/015-the-public-library-api/contracts/public-api.md](specs/015-the-public-library-api/contracts/public-api.md).
681
+ - The core install has `pydantic`, `httpx2`, `markdown-it-py` and `pyyaml`. The `server` extra adds `mcp`, `starlette` and `uvicorn`.
613
682
 
614
683
  ## Develop
615
684
 
@@ -620,7 +689,7 @@ uv sync
620
689
  uv run pytest
621
690
  ```
622
691
 
623
- The default tests need no network, no GPU and no model. They use a fake embedder and a copy of the curu concept files. The tests with a real embedder have the `integration` marker. With no GPU embedder server, start the [development embedder](#glossary) first, as [tools/embedder_server/README.md](tools/embedder_server/README.md) says. Then run:
692
+ `uv sync` installs the `server` extra, because the development group names it. The default tests need no network, no GPU and no model. They use a fake embedder and a copy of the curu concept files. The tests with a real embedder have the `integration` marker. With no GPU embedder server, start the [development embedder](#glossary) first, as [tools/embedder_server/README.md](tools/embedder_server/README.md) says. Then run:
624
693
 
625
694
  ```bash
626
695
  CURU_MEMORY_EMBEDDER_URL=http://127.0.0.1:30000 CURU_MEMORY_EMBEDDER_TIMEOUT=300 uv run pytest -m integration
@@ -654,6 +723,7 @@ The CI runs the same gates on each pull request and on each push to `main`. A re
654
723
  - **Data URI**: a text that holds the bytes of a file in base64, with their MIME type, for example `data:image/png;base64,...`.
655
724
  - **Data directory**: the directory of the index, the embedding cache, the access store `access.sqlite` and the audit log `audit.jsonl`. The default is `~/.local/share/curu-memory`, or `$XDG_DATA_HOME/curu-memory`. `CURU_MEMORY_DATA_DIR` changes it.
656
725
  - **Development embedder**: the CPU server in `tools/embedder_server/` that serves EmbeddingGemma 2 for the integration tier.
726
+ - **Extra**: a named set of optional packages of a Python package, for example `server` in `curu-memory[server]`.
657
727
  - **Embedder**: a server that changes a text, an image, a clip or a video into an embedding.
658
728
  - **Embedding**: a list of numbers that holds the meaning of a text, an image, a clip or a video. Items with a near meaning have near embeddings.
659
729
  - **GraphRAG**: retrieval that uses a search and the links between concepts to give an agent its context.
@@ -671,11 +741,11 @@ The CI runs the same gates on each pull request and on each push to `main`. A re
671
741
  - **Web browser**: the program that shows web pages, for example Firefox.
672
742
  - **SHA-256**: a hash of 64 hexadecimal characters that the bytes of a file give. Different bytes give a different SHA-256.
673
743
  - **Unit**: one part of a concept that has its own embedding: the summary, the overview, a `##` section, an image, a clip or a video.
674
- - **Version range**: the lowest version and the first version to exclude, for example `>=0.1,<0.2`.
744
+ - **Version range**: the lowest version and the first version to exclude, for example `>=0.3,<0.4`.
675
745
  - **Space**: a part of the knowledge with its own index: `global`, `team/<slug>` or `personal/<handle>`. Each request reads only the spaces that its caller can read.
676
746
  - **Team slug**: the short name of a team in a space name, for example `look` in `team/look`.
677
747
  - **Instance owner**: a person with `admin` on `global` and on each team space. The first registered person is an instance owner.
678
- - **Principal**: the person or the agent of a request: from `CURU_MEMORY_PRINCIPAL`, from `serve --grant`, from the OIDC token on HTTP, or `anonymous` with no principal.
748
+ - **Principal**: the person or the agent of a request, or `anonymous` with no principal. It comes from `CURU_MEMORY_PRINCIPAL`, `serve --grant`, the OIDC token on HTTP or `open_knowledge`.
679
749
  - **Operator**: the person who runs `curu-memory access` and `curu-memory index` on the computer of the server.
680
750
  - **Access store**: `access.sqlite`, with the persons, the teams, the members, the agents and the grants.
681
751
  - **Audit log**: `audit.jsonl`, with one line for each change of access, each refused read and each refused token.
@@ -1,22 +1,3 @@
1
- Metadata-Version: 2.5
2
- Name: curu-memory
3
- Version: 0.2.0
4
- Summary: A shared knowledge base and GraphRAG store for ComfyUI and generative media, served to agents over MCP.
5
- Project-URL: Repository, https://github.com/darth-veitcher/curu-memory
6
- Project-URL: Documentation, https://github.com/darth-veitcher/curu-memory#readme
7
- Project-URL: Changelog, https://github.com/darth-veitcher/curu-memory/blob/main/CHANGELOG.md
8
- License-Expression: MIT
9
- License-File: LICENSE
10
- Requires-Python: >=3.12
11
- Requires-Dist: httpx2>=2.10
12
- Requires-Dist: markdown-it-py>=4.0
13
- Requires-Dist: mcp==2.3.0
14
- Requires-Dist: pydantic>=2.12
15
- Requires-Dist: pyyaml>=6.0
16
- Requires-Dist: starlette>=1.0
17
- Requires-Dist: uvicorn>=0.31.1
18
- Description-Content-Type: text/markdown
19
-
20
1
  # curu-memory
21
2
 
22
3
  ## What is this
@@ -42,24 +23,25 @@ curu-memory is a shared knowledge base for ComfyUI and generative media. It read
42
23
  | Browse the knowledge in a web browser | `curu-memory browse` | [Browse the knowledge](#browse-the-knowledge) |
43
24
  | Read a concept and its links | The `get_concept` and `concept_neighbours` tools | [Read a concept and follow its links](#read-a-concept-and-follow-its-links) |
44
25
  | Find why a call failed | The `code` of the error | [Handle errors](#handle-errors) |
26
+ | Build and read the knowledge from a Python program | `curu_memory.open_knowledge()` | [Use curu-memory from Python](#use-curu-memory-from-python) |
45
27
 
46
28
  ## Install
47
29
 
48
30
  You need Python 3.12 or later and [uv](https://docs.astral.sh/uv/).
49
31
 
50
32
  ```bash
51
- uv tool install git+https://github.com/darth-veitcher/curu-memory
33
+ uv tool install "curu-memory[server] @ git+https://github.com/darth-veitcher/curu-memory"
52
34
  ```
53
35
 
54
- This installs the `curu-memory` command.
36
+ This installs the `curu-memory` command with the `server` [extra](#glossary). `serve` and `browse` need the extra. Without it, `index`, `search` and `access` work, and `serve` and `browse` stop with exit code 78.
55
37
 
56
38
  To install a release from PyPI, give a version range:
57
39
 
58
40
  ```bash
59
- uv tool install "curu-memory>=0.2,<0.3"
41
+ uv tool install "curu-memory[server]>=0.3,<0.4"
60
42
  ```
61
43
 
62
- A program that uses curu-memory as a library pins the same range in its `pyproject.toml`. A new minor version can change the Python API or the MCP tools, so the range stops before the next minor version.
44
+ A program that uses curu-memory as a library pins a range in its `pyproject.toml`, with no extra. A new minor version can change the Python API or the MCP tools, so the range stops before the next minor version.
63
45
 
64
46
  ## Quickstart
65
47
 
@@ -587,11 +569,58 @@ The `curu-memory` command uses these exit codes:
587
569
  | 0 | Success. |
588
570
  | 1 | `index` skipped a file, the embedder failed, another index run held the lock, or the embedder model was not the model of another space. `search` found no index, or no readable space. `access` refused a change. |
589
571
  | 2 | A usage error, for example `--limit 51`. |
590
- | 78 | A configuration error, for example HTTP with no token. |
572
+ | 78 | A configuration error, for example HTTP with no token, or `serve` with no `server` extra. |
573
+
574
+ ## Use curu-memory from Python
575
+
576
+ Use the library to build a space and to read it from a Python program, with no server. Import each name from `curu_memory` only. The names of `curu_memory.__all__` are the public API. Each other name can change in any release. The public API starts with version 0.3.0, so a program pins `curu-memory>=0.3,<0.4`.
577
+
578
+ ```python
579
+ from pathlib import Path
580
+
581
+ import curu_memory
582
+
583
+ report = curu_memory.build_space(Path("knowledge"))
584
+ print(report.concepts_indexed, len(report.skipped))
585
+
586
+ knowledge = curu_memory.open_knowledge()
587
+ for hit in knowledge.search("VAE for WAN2.2 5B", limit=3).results:
588
+ print(hit.id, hit.space)
589
+
590
+ concept = knowledge.get_concept("wan22-5b-vae")
591
+ links = knowledge.neighbours(concept.id)
592
+ ```
593
+
594
+ - `build_space` builds one space, as the index command does. `space=` names the space, and the default is `global`. A skipped file is not an error. The fields of the report are the values of [Index your knowledge](#index-your-knowledge), except `index`, for example `concepts_indexed`. `skipped` holds a (path, reason) pair for each skipped file.
595
+ - `open_knowledge` reads as one [principal](#glossary). Give `person="<handle>"` to read the spaces of that person. Give `grant=<id>` to read only the space of that grant. With neither, the library reads `global` only.
596
+ - An unknown, ended or revoked grant does not stop `open_knowledge`. Each read then raises `NoReadableSpace`. `serve --grant` stops at the start for such a grant.
597
+ - Each read gets the readable spaces again. A removed role or a revoked grant stops the next read.
598
+ - `search`, `get_concept` and `neighbours` give the same results as the tools `search_knowledge`, `get_concept` and `concept_neighbours`. Each hit gives its `space`.
599
+ - Each refused read writes the line in the audit log that the server writes, with the name of the matching tool as the action.
600
+ - `data_dir=` replaces the data directory. `env=` gives the `CURU_MEMORY_*` variables as a dictionary, for example the embedder settings of [Search by meaning](#search-by-meaning). With no `env`, the library reads the environment of the process.
601
+ - The library does not use `CURU_MEMORY_PRINCIPAL` to select the principal. A value that is not a valid handle raises `ConfigError`.
602
+ - The principal is not a security boundary in one process. The boundary is who can read the data directory.
603
+
604
+ Each error is in `curu_memory`:
605
+
606
+ | Call | Cause | Error |
607
+ |---|---|---|
608
+ | `build_space` | The concept directory does not exist, or the space name is not valid. `details.field` names the argument. | `InvalidArgument` |
609
+ | `build_space` | Another index run holds the lock. | `IndexLocked` |
610
+ | `build_space` | The embedder model is not the model of another space. | `IndexRefused` |
611
+ | `build_space` | The embedder failed. The old index stays. | `EmbedderFailed` |
612
+ | `build_space`, `open_knowledge` | A `CURU_MEMORY_*` variable is not valid. | `ConfigError` |
613
+ | `open_knowledge` | No person has the handle, or `person` and `grant` are both given. | `InvalidArgument` |
614
+ | each read | The principal can read no space. | `NoReadableSpace` |
615
+ | `get_concept`, `neighbours` | No readable space holds the concept. | `ConceptNotFound` |
616
+ | `search` | The question is empty or too long, or the limit is not from 1 to 50. | `InvalidArgument` |
617
+ | each read | No readable space has an index. | `IndexMissing` |
618
+
619
+ Each error except `IndexLocked` and `ConfigError` is a `CuruMemoryError`. Its `code` is the code that a tool gives, for example `concept_not_found`.
591
620
 
592
621
  ## Limits
593
622
 
594
- - On stdio, in the browser and with the static token, one process reads as one person (`CURU_MEMORY_PRINCIPAL`). On stdio, `serve --grant` makes the process read as the agent of one grant. Only the OIDC mode of HTTP gives each request its own person or agent.
623
+ - On stdio, in the browser and with the static token, one process reads as one person (`CURU_MEMORY_PRINCIPAL`). In Python, each `Knowledge` reads as the principal of its `open_knowledge`. On stdio, `serve --grant` makes the process read as the agent of one grant. Only the OIDC mode of HTTP gives each request its own person or agent.
595
624
  - There is no encryption at rest yet.
596
625
  - The browser has no OIDC login.
597
626
  - Agents and persons cannot write knowledge through curu-memory yet. Edit the concept files, then run the index command.
@@ -609,7 +638,7 @@ The `curu-memory` command uses these exit codes:
609
638
  - A match between a question in words and a clip needs 0.68 or more with EmbeddingGemma 2. The limit comes from speech clips. Speech test clips scored from 0.73 with their own questions. Wrong clips and unrelated questions reached 0.64. Music and sound effects can score lower.
610
639
  - The index holds a copy of each media file. One hundred files of 2 MB make the index about 200 MB larger.
611
640
  - There is no file watcher. Run the index command after each change.
612
- - curu-memory has no public Python API yet. Each module is internal.
641
+ - The Python API cannot search with media, and it cannot write a concept. Use `curu-memory search --media` or the tool `search_knowledge_by_media` for media.
613
642
 
614
643
  ## Technical notes
615
644
 
@@ -628,7 +657,8 @@ The `curu-memory` command uses these exit codes:
628
657
  - The concept rules are the same as the rules of the curu index, so each curu concept file indexes here.
629
658
  - The tool contracts are in [specs/001-okf-index-mcp-search/contracts/](specs/001-okf-index-mcp-search/contracts/).
630
659
  - curu-memory uses the official MCP Python SDK. It never loads model weights.
631
- - curu uses curu-memory as a library, and the version range of a release follows a version policy. See [ADR-019](project-management/ADRs/ADR-019-curu-uses-curu-memory-as-a-library.md).
660
+ - curu uses curu-memory as a library, and the version range of a release follows a version policy. See [ADR-019](project-management/ADRs/ADR-019-curu-uses-curu-memory-as-a-library.md). `tests/contract/public_api.txt` holds the names of `curu_memory.__all__`. The contract is [specs/015-the-public-library-api/contracts/public-api.md](specs/015-the-public-library-api/contracts/public-api.md).
661
+ - The core install has `pydantic`, `httpx2`, `markdown-it-py` and `pyyaml`. The `server` extra adds `mcp`, `starlette` and `uvicorn`.
632
662
 
633
663
  ## Develop
634
664
 
@@ -639,7 +669,7 @@ uv sync
639
669
  uv run pytest
640
670
  ```
641
671
 
642
- The default tests need no network, no GPU and no model. They use a fake embedder and a copy of the curu concept files. The tests with a real embedder have the `integration` marker. With no GPU embedder server, start the [development embedder](#glossary) first, as [tools/embedder_server/README.md](tools/embedder_server/README.md) says. Then run:
672
+ `uv sync` installs the `server` extra, because the development group names it. The default tests need no network, no GPU and no model. They use a fake embedder and a copy of the curu concept files. The tests with a real embedder have the `integration` marker. With no GPU embedder server, start the [development embedder](#glossary) first, as [tools/embedder_server/README.md](tools/embedder_server/README.md) says. Then run:
643
673
 
644
674
  ```bash
645
675
  CURU_MEMORY_EMBEDDER_URL=http://127.0.0.1:30000 CURU_MEMORY_EMBEDDER_TIMEOUT=300 uv run pytest -m integration
@@ -673,6 +703,7 @@ The CI runs the same gates on each pull request and on each push to `main`. A re
673
703
  - **Data URI**: a text that holds the bytes of a file in base64, with their MIME type, for example `data:image/png;base64,...`.
674
704
  - **Data directory**: the directory of the index, the embedding cache, the access store `access.sqlite` and the audit log `audit.jsonl`. The default is `~/.local/share/curu-memory`, or `$XDG_DATA_HOME/curu-memory`. `CURU_MEMORY_DATA_DIR` changes it.
675
705
  - **Development embedder**: the CPU server in `tools/embedder_server/` that serves EmbeddingGemma 2 for the integration tier.
706
+ - **Extra**: a named set of optional packages of a Python package, for example `server` in `curu-memory[server]`.
676
707
  - **Embedder**: a server that changes a text, an image, a clip or a video into an embedding.
677
708
  - **Embedding**: a list of numbers that holds the meaning of a text, an image, a clip or a video. Items with a near meaning have near embeddings.
678
709
  - **GraphRAG**: retrieval that uses a search and the links between concepts to give an agent its context.
@@ -690,11 +721,11 @@ The CI runs the same gates on each pull request and on each push to `main`. A re
690
721
  - **Web browser**: the program that shows web pages, for example Firefox.
691
722
  - **SHA-256**: a hash of 64 hexadecimal characters that the bytes of a file give. Different bytes give a different SHA-256.
692
723
  - **Unit**: one part of a concept that has its own embedding: the summary, the overview, a `##` section, an image, a clip or a video.
693
- - **Version range**: the lowest version and the first version to exclude, for example `>=0.1,<0.2`.
724
+ - **Version range**: the lowest version and the first version to exclude, for example `>=0.3,<0.4`.
694
725
  - **Space**: a part of the knowledge with its own index: `global`, `team/<slug>` or `personal/<handle>`. Each request reads only the spaces that its caller can read.
695
726
  - **Team slug**: the short name of a team in a space name, for example `look` in `team/look`.
696
727
  - **Instance owner**: a person with `admin` on `global` and on each team space. The first registered person is an instance owner.
697
- - **Principal**: the person or the agent of a request: from `CURU_MEMORY_PRINCIPAL`, from `serve --grant`, from the OIDC token on HTTP, or `anonymous` with no principal.
728
+ - **Principal**: the person or the agent of a request, or `anonymous` with no principal. It comes from `CURU_MEMORY_PRINCIPAL`, `serve --grant`, the OIDC token on HTTP or `open_knowledge`.
698
729
  - **Operator**: the person who runs `curu-memory access` and `curu-memory index` on the computer of the server.
699
730
  - **Access store**: `access.sqlite`, with the persons, the teams, the members, the agents and the grants.
700
731
  - **Audit log**: `audit.jsonl`, with one line for each change of access, each refused read and each refused token.
@@ -5,12 +5,18 @@ description = "A shared knowledge base and GraphRAG store for ComfyUI and genera
5
5
  readme = "README.md"
6
6
  license = "MIT"
7
7
  requires-python = ">=3.12"
8
+ # The core: the library, `index`, `search` and `access`. No server package (spec 015).
8
9
  dependencies = [
9
- "mcp==2.3.0",
10
10
  "pydantic>=2.12",
11
11
  "httpx2>=2.10",
12
12
  "markdown-it-py>=4.0",
13
13
  "pyyaml>=6.0",
14
+ ]
15
+
16
+ [project.optional-dependencies]
17
+ # `serve` and `browse` need these. Install them with curu-memory[server].
18
+ server = [
19
+ "mcp==2.3.0",
14
20
  "starlette>=1.0",
15
21
  "uvicorn>=0.31.1",
16
22
  ]
@@ -25,11 +31,12 @@ Changelog = "https://github.com/darth-veitcher/curu-memory/blob/main/CHANGELOG.m
25
31
 
26
32
  [dependency-groups]
27
33
  dev = [
34
+ # The extra itself, so that the pin of mcp has one place (research R7).
35
+ "curu-memory[server]",
28
36
  "pytest>=8",
29
37
  "pytest-timeout>=2.3",
30
38
  "ruff>=0.15",
31
39
  "ty>=0.0.1a20",
32
- "uvicorn>=0.31.1",
33
40
  ]
34
41
 
35
42
  [build-system]
@@ -0,0 +1,52 @@
1
+ """curu-memory: a shared knowledge base for ComfyUI, served to agents over MCP.
2
+
3
+ The names in `__all__` are the public Python API (ADR-019). Each other name is internal
4
+ and can change in any release. `tests/contract/public_api.txt` holds the same names.
5
+ """
6
+
7
+ __version__ = "0.3.0"
8
+
9
+ from curu_memory.config import ConfigError # noqa: E402
10
+ from curu_memory.errors import ( # noqa: E402
11
+ ConceptNotFound,
12
+ CuruMemoryError,
13
+ EmbedderFailed,
14
+ IndexMissing,
15
+ IndexRefused,
16
+ InvalidArgument,
17
+ NoReadableSpace,
18
+ )
19
+ from curu_memory.indexing import IndexReport # noqa: E402
20
+ from curu_memory.library import Knowledge, build_space, open_knowledge # noqa: E402
21
+ from curu_memory.ports import IndexLocked # noqa: E402
22
+ from curu_memory.retrieval import ( # noqa: E402
23
+ ConceptDetail,
24
+ MediaItem,
25
+ Neighbour,
26
+ Neighbours,
27
+ SearchHit,
28
+ SearchResult,
29
+ )
30
+
31
+ __all__ = [
32
+ "ConceptDetail",
33
+ "ConceptNotFound",
34
+ "ConfigError",
35
+ "CuruMemoryError",
36
+ "EmbedderFailed",
37
+ "IndexLocked",
38
+ "IndexMissing",
39
+ "IndexRefused",
40
+ "IndexReport",
41
+ "InvalidArgument",
42
+ "Knowledge",
43
+ "MediaItem",
44
+ "Neighbour",
45
+ "Neighbours",
46
+ "NoReadableSpace",
47
+ "SearchHit",
48
+ "SearchResult",
49
+ "__version__",
50
+ "build_space",
51
+ "open_knowledge",
52
+ ]