recall-rag 0.5.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.
- recall_rag-0.5.0/.env.example +46 -0
- recall_rag-0.5.0/.gitattributes +20 -0
- recall_rag-0.5.0/.github/ISSUE_TEMPLATE/bug_report.yml +109 -0
- recall_rag-0.5.0/.github/ISSUE_TEMPLATE/feature_request.yml +68 -0
- recall_rag-0.5.0/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- recall_rag-0.5.0/.github/dependabot.yml +27 -0
- recall_rag-0.5.0/.github/workflows/ci.yml +165 -0
- recall_rag-0.5.0/.github/workflows/release.yml +103 -0
- recall_rag-0.5.0/.gitignore +21 -0
- recall_rag-0.5.0/.hypothesis/.gitignore +9 -0
- recall_rag-0.5.0/.hypothesis/constants/09ae28b390a241d0 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/1b03421aacbc7cd8 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/4f680edac8831786 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/58bfffd74f8d33bb +4 -0
- recall_rag-0.5.0/.hypothesis/constants/7b04dce73625ffce +4 -0
- recall_rag-0.5.0/.hypothesis/constants/82006d59dbfd9f8c +4 -0
- recall_rag-0.5.0/.hypothesis/constants/93fc2ddbc371af6f +4 -0
- recall_rag-0.5.0/.hypothesis/constants/aacd188e88fdb02c +4 -0
- recall_rag-0.5.0/.hypothesis/constants/b9060cae8ecc85e4 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/c2e77a59fc774cb4 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/c3e2bf835012a270 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/eb9c6a606edd1539 +4 -0
- recall_rag-0.5.0/.hypothesis/constants/f13ade3695328b0e +4 -0
- recall_rag-0.5.0/.hypothesis/constants/fdf737c1084b7f57 +4 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/0acf2657c27e4359 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/20aabcc12c229c24 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/24db4dde1625ca09 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/35ae207c7fba4696 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/3d6dbf469bc8fc50 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/4b871946bc8e9dca +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/4b97561a20df69bc +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/5186f6250de73032 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/52ca6365b96b50a0 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/746fda09b9ff7660 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/784d670915229774 +1 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/acc561fc7c60456c +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/b6cf898a1bbe9eb0 +1 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/d0e5fb1dd2c01256 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/d696659ccddf82d0 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/df7ff1a7abd09303 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/e08bb4347a57c700 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/e6fa97c332a04542 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/e93938e97562e74f +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/ebe313e158984126 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/f2bcb1b9df56c641 +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/f66eb38a279831ed +0 -0
- recall_rag-0.5.0/.hypothesis/examples/037c25897bbedebf/fe8c824900eca5fc +0 -0
- recall_rag-0.5.0/.hypothesis/examples/04e6b3400353b141/037c25897bbedebf +1 -0
- recall_rag-0.5.0/.hypothesis/examples/04e6b3400353b141/0a3b3322a194053a +1 -0
- recall_rag-0.5.0/.hypothesis/examples/0a3b3322a194053a/d86d3c1cf466522d +0 -0
- recall_rag-0.5.0/CHANGELOG.md +351 -0
- recall_rag-0.5.0/CITATION.cff +14 -0
- recall_rag-0.5.0/CODE_OF_CONDUCT.md +108 -0
- recall_rag-0.5.0/CONTRIBUTING.md +99 -0
- recall_rag-0.5.0/LICENSE +21 -0
- recall_rag-0.5.0/Makefile +11 -0
- recall_rag-0.5.0/PKG-INFO +542 -0
- recall_rag-0.5.0/README.md +486 -0
- recall_rag-0.5.0/SECURITY.md +189 -0
- recall_rag-0.5.0/corpus/decisions.md +10 -0
- recall_rag-0.5.0/corpus/hypotheses.md +11 -0
- recall_rag-0.5.0/corpus/infra.md +4 -0
- recall_rag-0.5.0/corpus/rate_limits_v1.md +4 -0
- recall_rag-0.5.0/corpus/rate_limits_v2.md +8 -0
- recall_rag-0.5.0/docker-compose.yml +14 -0
- recall_rag-0.5.0/docs/AUTH.md +151 -0
- recall_rag-0.5.0/docs/CASE_STUDY.md +118 -0
- recall_rag-0.5.0/docs/ENTAILMENT_SUPERSESSION_STUDY.md +193 -0
- recall_rag-0.5.0/docs/RAG_TRAINING_STUDY.md +114 -0
- recall_rag-0.5.0/docs/USING_WITH_CLAUDE.md +89 -0
- recall_rag-0.5.0/docs/WRITEUP.md +215 -0
- recall_rag-0.5.0/docs/banner.png +0 -0
- recall_rag-0.5.0/docs/banner.svg +37 -0
- recall_rag-0.5.0/docs/superseded-catch.svg +44 -0
- recall_rag-0.5.0/examples/README.md +15 -0
- recall_rag-0.5.0/examples/__init__.py +0 -0
- recall_rag-0.5.0/examples/self_recall_agent.py +51 -0
- recall_rag-0.5.0/finetune/README.md +27 -0
- recall_rag-0.5.0/finetune/confusable_corpus/aster.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/basil.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/clove.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/dill.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/elm.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/fern.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/gorse.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/holly.md +1 -0
- recall_rag-0.5.0/finetune/confusable_corpus/iris.md +1 -0
- recall_rag-0.5.0/finetune/confusable_queries.json +33 -0
- recall_rag-0.5.0/finetune/hard_queries.json +30 -0
- recall_rag-0.5.0/finetune/train.py +150 -0
- recall_rag-0.5.0/hooks/pre-commit +16 -0
- recall_rag-0.5.0/pyproject.toml +157 -0
- recall_rag-0.5.0/recall/__init__.py +3 -0
- recall_rag-0.5.0/recall/_env.py +25 -0
- recall_rag-0.5.0/recall/cache.py +84 -0
- recall_rag-0.5.0/recall/calibration.py +165 -0
- recall_rag-0.5.0/recall/check.py +87 -0
- recall_rag-0.5.0/recall/cli.py +377 -0
- recall_rag-0.5.0/recall/embeddings.py +288 -0
- recall_rag-0.5.0/recall/entailment.py +114 -0
- recall_rag-0.5.0/recall/eval/__init__.py +1 -0
- recall_rag-0.5.0/recall/eval/__main__.py +121 -0
- recall_rag-0.5.0/recall/eval/_show_ids.py +24 -0
- recall_rag-0.5.0/recall/eval/bm25.py +149 -0
- recall_rag-0.5.0/recall/eval/calibrate.py +140 -0
- recall_rag-0.5.0/recall/eval/corpus/anti_relitigation.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/autoscaling.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/backups.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/browser_support.md +7 -0
- recall_rag-0.5.0/recall/eval/corpus/cache_decision.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/cache_ttl_v1.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/cache_ttl_v2.md +7 -0
- recall_rag-0.5.0/recall/eval/corpus/corpus_gap_definition.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/datastore_choice.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/deploy_freeze.md +7 -0
- recall_rag-0.5.0/recall/eval/corpus/h014_prompt_injection.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/h021_reranking.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/incident_checkout_500.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/incident_stale_flag.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/indexer_freshness.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/retry_policy.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/rollout_flag_v1.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/rollout_flag_v2.md +7 -0
- recall_rag-0.5.0/recall/eval/corpus/rrf_definition.md +5 -0
- recall_rag-0.5.0/recall/eval/corpus/search_engine_v1.md +4 -0
- recall_rag-0.5.0/recall/eval/corpus/search_engine_v2.md +7 -0
- recall_rag-0.5.0/recall/eval/corpus/secrets_handling.md +4 -0
- recall_rag-0.5.0/recall/eval/harness.py +677 -0
- recall_rag-0.5.0/recall/eval/labelled.py +215 -0
- recall_rag-0.5.0/recall/eval/locomo.py +442 -0
- recall_rag-0.5.0/recall/eval/metrics.py +176 -0
- recall_rag-0.5.0/recall/eval/near_miss.json +52 -0
- recall_rag-0.5.0/recall/eval/peps_questions.json +113 -0
- recall_rag-0.5.0/recall/eval/queries.json +212 -0
- recall_rag-0.5.0/recall/eval/scale.py +209 -0
- recall_rag-0.5.0/recall/eval/synthetic.py +305 -0
- recall_rag-0.5.0/recall/fix.py +295 -0
- recall_rag-0.5.0/recall/frontmatter.py +86 -0
- recall_rag-0.5.0/recall/guards.py +37 -0
- recall_rag-0.5.0/recall/index.py +511 -0
- recall_rag-0.5.0/recall/lint.py +202 -0
- recall_rag-0.5.0/recall/observability.py +210 -0
- recall_rag-0.5.0/recall/rerank.py +53 -0
- recall_rag-0.5.0/recall/retriever.py +122 -0
- recall_rag-0.5.0/recall/semantic_lint.py +184 -0
- recall_rag-0.5.0/recall/store.py +1201 -0
- recall_rag-0.5.0/recall/timing.py +81 -0
- recall_rag-0.5.0/recall/trust.py +239 -0
- recall_rag-0.5.0/recall/types.py +91 -0
- recall_rag-0.5.0/recall_mcp/__init__.py +1 -0
- recall_rag-0.5.0/recall_mcp/auth.py +361 -0
- recall_rag-0.5.0/recall_mcp/limits.py +236 -0
- recall_rag-0.5.0/recall_mcp/server.py +524 -0
- recall_rag-0.5.0/recall_mcp/service.py +350 -0
- recall_rag-0.5.0/recall_mcp/stores.py +125 -0
- recall_rag-0.5.0/results/FINDINGS.md +590 -0
- recall_rag-0.5.0/results/RESULTS.md +58 -0
- recall_rag-0.5.0/results/guard_effect.png +0 -0
- recall_rag-0.5.0/results/locomo_fastembed_k5.json +512 -0
- recall_rag-0.5.0/results/ndcg_by_config.png +0 -0
- recall_rag-0.5.0/results/nearmiss_effect.png +0 -0
- recall_rag-0.5.0/results/scale/SCALE.md +31 -0
- recall_rag-0.5.0/results/scale-pressure/SCALE.md +31 -0
- recall_rag-0.5.0/results/trust_effect.png +0 -0
- recall_rag-0.5.0/tests/__init__.py +0 -0
- recall_rag-0.5.0/tests/conftest.py +132 -0
- recall_rag-0.5.0/tests/test_auth.py +273 -0
- recall_rag-0.5.0/tests/test_cache.py +52 -0
- recall_rag-0.5.0/tests/test_calibration.py +114 -0
- recall_rag-0.5.0/tests/test_check.py +89 -0
- recall_rag-0.5.0/tests/test_cli.py +166 -0
- recall_rag-0.5.0/tests/test_embeddings.py +33 -0
- recall_rag-0.5.0/tests/test_embeddings_batch.py +119 -0
- recall_rag-0.5.0/tests/test_embeddings_cloud.py +23 -0
- recall_rag-0.5.0/tests/test_entailment.py +142 -0
- recall_rag-0.5.0/tests/test_env_loader.py +21 -0
- recall_rag-0.5.0/tests/test_eval_bm25.py +208 -0
- recall_rag-0.5.0/tests/test_eval_calibrate.py +56 -0
- recall_rag-0.5.0/tests/test_eval_calibrate_heldout.py +77 -0
- recall_rag-0.5.0/tests/test_eval_harness.py +86 -0
- recall_rag-0.5.0/tests/test_eval_locomo.py +120 -0
- recall_rag-0.5.0/tests/test_eval_metrics.py +161 -0
- recall_rag-0.5.0/tests/test_eval_nearmiss.py +146 -0
- recall_rag-0.5.0/tests/test_eval_synthetic.py +203 -0
- recall_rag-0.5.0/tests/test_example_agent.py +40 -0
- recall_rag-0.5.0/tests/test_fix.py +286 -0
- recall_rag-0.5.0/tests/test_frontmatter.py +75 -0
- recall_rag-0.5.0/tests/test_guards.py +41 -0
- recall_rag-0.5.0/tests/test_hnsw_filtered_recall.py +295 -0
- recall_rag-0.5.0/tests/test_index.py +244 -0
- recall_rag-0.5.0/tests/test_index_incremental.py +281 -0
- recall_rag-0.5.0/tests/test_index_quota.py +188 -0
- recall_rag-0.5.0/tests/test_index_unreachable_sources.py +279 -0
- recall_rag-0.5.0/tests/test_limits.py +298 -0
- recall_rag-0.5.0/tests/test_lint.py +202 -0
- recall_rag-0.5.0/tests/test_mcp_auth_http.py +167 -0
- recall_rag-0.5.0/tests/test_mcp_auth_wiring.py +259 -0
- recall_rag-0.5.0/tests/test_mcp_concurrency.py +92 -0
- recall_rag-0.5.0/tests/test_mcp_service_forget.py +92 -0
- recall_rag-0.5.0/tests/test_mcp_service_index.py +123 -0
- recall_rag-0.5.0/tests/test_mcp_service_search.py +90 -0
- recall_rag-0.5.0/tests/test_mcp_service_stats.py +22 -0
- recall_rag-0.5.0/tests/test_mcp_smoke.py +8 -0
- recall_rag-0.5.0/tests/test_mcp_tool_forget.py +92 -0
- recall_rag-0.5.0/tests/test_observability.py +207 -0
- recall_rag-0.5.0/tests/test_percentiles.py +76 -0
- recall_rag-0.5.0/tests/test_prune_guard.py +240 -0
- recall_rag-0.5.0/tests/test_rate_limit_http.py +261 -0
- recall_rag-0.5.0/tests/test_rerank.py +54 -0
- recall_rag-0.5.0/tests/test_retriever.py +133 -0
- recall_rag-0.5.0/tests/test_schema_lock_timeout.py +136 -0
- recall_rag-0.5.0/tests/test_security_hardening.py +192 -0
- recall_rag-0.5.0/tests/test_semantic_lint.py +273 -0
- recall_rag-0.5.0/tests/test_smoke.py +12 -0
- recall_rag-0.5.0/tests/test_store.py +810 -0
- recall_rag-0.5.0/tests/test_store_pool.py +144 -0
- recall_rag-0.5.0/tests/test_supersession_freshness.py +149 -0
- recall_rag-0.5.0/tests/test_tenancy.py +473 -0
- recall_rag-0.5.0/tests/test_tenancy_retrieval.py +168 -0
- recall_rag-0.5.0/tests/test_timing.py +67 -0
- recall_rag-0.5.0/tests/test_trust.py +161 -0
- recall_rag-0.5.0/tests/test_trusted_search.py +135 -0
- recall_rag-0.5.0/uv.lock +4330 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copy to .env (gitignored) and fill in. The .env is only read by local entry points via
|
|
2
|
+
# recall/_env.py — it is never committed.
|
|
3
|
+
|
|
4
|
+
# Optional: enables the Voyage cloud embedder row in the evaluation (`make eval`).
|
|
5
|
+
# Everything else in the project runs key-free with the local FastEmbed embedder.
|
|
6
|
+
VOYAGE_API_KEY=
|
|
7
|
+
|
|
8
|
+
# Optional overrides (defaults shown):
|
|
9
|
+
# RECALL_DSN=postgresql://recall:recall@localhost:5432/recall
|
|
10
|
+
# RECALL_EMBEDDER=fastembed # or "hashing" for the fully-offline embedder
|
|
11
|
+
# RECALL_INDEX_ROOT=. # bounds where the MCP recall_index tool may read
|
|
12
|
+
# RECALL_CALIBRATION=calibration.json # path to the per-embedder calibration written by `recall calibrate`
|
|
13
|
+
|
|
14
|
+
# --- MCP transport & authentication (see docs/AUTH.md) ---
|
|
15
|
+
# Default is stdio: a private pipe to one client, which needs no authentication.
|
|
16
|
+
# The HTTP transports open a socket and REFUSE TO START without a token file.
|
|
17
|
+
# RECALL_TRANSPORT=stdio # or streamable-http / sse
|
|
18
|
+
# RECALL_AUTH_TOKENS_FILE=/etc/recall/tokens.json # chmod 600; there is deliberately NO
|
|
19
|
+
# # env var that accepts a raw token
|
|
20
|
+
# RECALL_AUTH_ISSUER_URL=https://recall.example.com
|
|
21
|
+
# RECALL_AUTH_RESOURCE_URL=https://recall.example.com
|
|
22
|
+
# RECALL_TENANT=default # stdio only; on HTTP the token carries the tenant
|
|
23
|
+
|
|
24
|
+
# --- Abuse bounds (see SECURITY.md) ---
|
|
25
|
+
# Per-request caps bound ONE call; the budgets below bound the aggregate, per TENANT, so a
|
|
26
|
+
# client staying under the per-request cap cannot simply issue it in a loop.
|
|
27
|
+
# RECALL_INDEX_MAX_FILES=2000 # per request: candidate file count
|
|
28
|
+
# RECALL_INDEX_MAX_BYTES=20000000 # per request: candidate bytes (~20 MB)
|
|
29
|
+
# RECALL_RATE_READ_PER_MIN=120 # per tenant: recall_search / recall_stats calls
|
|
30
|
+
# RECALL_RATE_WRITE_PER_MIN=20 # per tenant: recall_index calls
|
|
31
|
+
# RECALL_RATE_FORGET_PER_MIN=10 # per tenant: recall_forget calls
|
|
32
|
+
# RECALL_INDEX_BYTES_PER_HOUR=209715200 # per tenant: aggregate indexed bytes (200 MiB).
|
|
33
|
+
# # Keep this >= RECALL_INDEX_MAX_BYTES, or requests between
|
|
34
|
+
# # the two sizes can never succeed.
|
|
35
|
+
# Each of the four budgets takes a number or the literal `off`. A malformed value, a non-finite
|
|
36
|
+
# one, or one too small to yield a non-zero rate falls back to its default rather than being read
|
|
37
|
+
# as "unlimited" — only `off` disables a limit.
|
|
38
|
+
# Read once at startup: changing a budget takes effect on restart.
|
|
39
|
+
|
|
40
|
+
# --- Schema DDL ---
|
|
41
|
+
# RECALL_SCHEMA_LOCK_TIMEOUT_MS=5000 # how long ensure_schema() may WAIT FOR A LOCK before
|
|
42
|
+
# # giving up. NOT a bound on the work — an HNSW build is
|
|
43
|
+
# # deliberately unbounded — only on queueing behind another
|
|
44
|
+
# # transaction. `0` waits forever. The DDL is idempotent and
|
|
45
|
+
# # retried on the next store open, so failing fast here
|
|
46
|
+
# # loses nothing and is diagnosable where a stall is not.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Normalize all text files to LF in the repo, regardless of author OS.
|
|
2
|
+
# Prevents the CRLF/LF churn that shows up when committing from Windows.
|
|
3
|
+
* text=auto eol=lf
|
|
4
|
+
|
|
5
|
+
# Explicit rules for common types (belt-and-suspenders).
|
|
6
|
+
*.py text eol=lf
|
|
7
|
+
*.md text eol=lf
|
|
8
|
+
*.toml text eol=lf
|
|
9
|
+
*.json text eol=lf
|
|
10
|
+
*.yml text eol=lf
|
|
11
|
+
*.yaml text eol=lf
|
|
12
|
+
*.sh text eol=lf
|
|
13
|
+
Makefile text eol=lf
|
|
14
|
+
|
|
15
|
+
# Binary assets — never touch line endings.
|
|
16
|
+
*.png binary
|
|
17
|
+
*.jpg binary
|
|
18
|
+
*.jpeg binary
|
|
19
|
+
*.ico binary
|
|
20
|
+
*.gz binary
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something in RE-call is broken or behaving incorrectly.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for filing a bug. This project runs against a real PostgreSQL + pgvector database
|
|
9
|
+
and several swappable embedder backends, so the fields below cut straight to the questions
|
|
10
|
+
that would otherwise take a round-trip to ask.
|
|
11
|
+
|
|
12
|
+
- type: input
|
|
13
|
+
id: recall-version
|
|
14
|
+
attributes:
|
|
15
|
+
label: recall version
|
|
16
|
+
description: "`pip show recall` or the commit SHA if installed from source."
|
|
17
|
+
placeholder: "0.5.0"
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: input
|
|
22
|
+
id: python-version
|
|
23
|
+
attributes:
|
|
24
|
+
label: Python version
|
|
25
|
+
placeholder: "3.12.4"
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: input
|
|
30
|
+
id: pg-version
|
|
31
|
+
attributes:
|
|
32
|
+
label: PostgreSQL version
|
|
33
|
+
description: "`SELECT version();` — or the tag from your `pgvector/pgvector:pgNN` image."
|
|
34
|
+
placeholder: "PostgreSQL 16 (pgvector/pgvector:pg16), or PostgreSQL 17 if a bare-metal install"
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: input
|
|
39
|
+
id: pgvector-version
|
|
40
|
+
attributes:
|
|
41
|
+
label: pgvector extension version
|
|
42
|
+
description: "`SELECT extversion FROM pg_extension WHERE extname = 'vector';`"
|
|
43
|
+
placeholder: "0.8.2"
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: dropdown
|
|
48
|
+
id: embedder
|
|
49
|
+
attributes:
|
|
50
|
+
label: Embedder backend
|
|
51
|
+
description: Which `Embedder` implementation is in use.
|
|
52
|
+
options:
|
|
53
|
+
- fastembed (local, default)
|
|
54
|
+
- voyage (cloud)
|
|
55
|
+
- hashing (offline/deterministic)
|
|
56
|
+
- other / custom Embedder implementation
|
|
57
|
+
validations:
|
|
58
|
+
required: true
|
|
59
|
+
|
|
60
|
+
- type: input
|
|
61
|
+
id: corpus-size
|
|
62
|
+
attributes:
|
|
63
|
+
label: Corpus size
|
|
64
|
+
description: Roughly how many files/chunks are indexed. Retrieval behavior differs a lot
|
|
65
|
+
between a handful of docs and tens of thousands of chunks.
|
|
66
|
+
placeholder: "e.g. ~800 files / ~6,500 chunks"
|
|
67
|
+
|
|
68
|
+
- type: textarea
|
|
69
|
+
id: what-happened
|
|
70
|
+
attributes:
|
|
71
|
+
label: What happened
|
|
72
|
+
description: What you did, what you expected, and what happened instead.
|
|
73
|
+
validations:
|
|
74
|
+
required: true
|
|
75
|
+
|
|
76
|
+
- type: textarea
|
|
77
|
+
id: retrieval-detail
|
|
78
|
+
attributes:
|
|
79
|
+
label: If this is a retrieval/trust-layer issue — the query and the returned verdict
|
|
80
|
+
description: >-
|
|
81
|
+
For "the wrong chunk came back" or "it abstained when it shouldn't have" (or vice versa):
|
|
82
|
+
the exact query text, and the JSON your search call actually returned (or at minimum each
|
|
83
|
+
hit's `verdict`, `confidence`/`score`, and whether `abstained` was true). Redact anything
|
|
84
|
+
sensitive from your corpus — paraphrase the shape of the memory rather than pasting it
|
|
85
|
+
verbatim if it's private.
|
|
86
|
+
render: text
|
|
87
|
+
|
|
88
|
+
- type: textarea
|
|
89
|
+
id: repro
|
|
90
|
+
attributes:
|
|
91
|
+
label: Minimal reproduction
|
|
92
|
+
description: Smallest command/script that reproduces it. A snippet using `HashingEmbedder`
|
|
93
|
+
against a couple of throwaway markdown files reproduces most retrieval bugs without needing
|
|
94
|
+
your real corpus or an API key.
|
|
95
|
+
render: shell
|
|
96
|
+
|
|
97
|
+
- type: textarea
|
|
98
|
+
id: logs
|
|
99
|
+
attributes:
|
|
100
|
+
label: Relevant logs / traceback
|
|
101
|
+
render: shell
|
|
102
|
+
|
|
103
|
+
- type: checkboxes
|
|
104
|
+
id: checks
|
|
105
|
+
attributes:
|
|
106
|
+
label: Checks
|
|
107
|
+
options:
|
|
108
|
+
- label: I ran this against a real pgvector database (not a mock) — this project has no mock DB path.
|
|
109
|
+
- label: I checked this isn't already covered in `README.md`'s "What this does not do" section or `results/FINDINGS.md`.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose new behavior, a new guard, or a new evaluation for RE-call.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
This project's rule for a new claim is: measure it, and publish the negative result if it
|
|
9
|
+
doesn't hold up (see `results/FINDINGS.md`'s "Claims that were withdrawn"). The same bar
|
|
10
|
+
applies to feature requests — a proposal that includes how it would be measured gets
|
|
11
|
+
triaged faster.
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: problem
|
|
15
|
+
attributes:
|
|
16
|
+
label: What problem does this solve
|
|
17
|
+
description: What's missing today, and what failure or friction it causes.
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: proposal
|
|
23
|
+
attributes:
|
|
24
|
+
label: Proposed behavior
|
|
25
|
+
description: What you'd want RE-call to do instead.
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: dropdown
|
|
30
|
+
id: area
|
|
31
|
+
attributes:
|
|
32
|
+
label: Area
|
|
33
|
+
options:
|
|
34
|
+
- Retrieval (dense/sparse/RRF fusion)
|
|
35
|
+
- Trust layer (verdicts, supersession, validity, calibration)
|
|
36
|
+
- Embedders (fastembed / voyage / hashing / new backend)
|
|
37
|
+
- MCP server (recall_search / recall_index / recall_stats)
|
|
38
|
+
- CLI (index / search / demo / lint / check / calibrate)
|
|
39
|
+
- Evaluation harness (recall/eval)
|
|
40
|
+
- Multi-tenancy / RLS
|
|
41
|
+
- Observability (logging, metrics)
|
|
42
|
+
- Other
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
|
|
46
|
+
- type: input
|
|
47
|
+
id: embedder-context
|
|
48
|
+
attributes:
|
|
49
|
+
label: Embedder(s) this affects, if relevant
|
|
50
|
+
description: Some behavior (e.g. calibration thresholds) does not transfer across embedders —
|
|
51
|
+
say which backend(s) you're thinking about.
|
|
52
|
+
placeholder: "e.g. fastembed only, or all embedders"
|
|
53
|
+
|
|
54
|
+
- type: textarea
|
|
55
|
+
id: measurement
|
|
56
|
+
attributes:
|
|
57
|
+
label: How would this be measured
|
|
58
|
+
description: >-
|
|
59
|
+
If this is a retrieval or trust-layer change: what metric would move (hit@5, superseded-
|
|
60
|
+
trust rate, false-confident rate, latency), and against which corpus (the 14-doc demo
|
|
61
|
+
corpus, the real 792-memo corpus, or a generated corpus at scale)? If it's not measurable in
|
|
62
|
+
that sense (e.g. a CLI ergonomics change), say so — that's a legitimate answer too.
|
|
63
|
+
|
|
64
|
+
- type: textarea
|
|
65
|
+
id: alternatives
|
|
66
|
+
attributes:
|
|
67
|
+
label: Alternatives considered
|
|
68
|
+
description: Anything you already tried or ruled out, and why.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## What this does and why
|
|
2
|
+
|
|
3
|
+
<!-- The "why" matters more than the "what" here — see CONTRIBUTING.md and the commit-message
|
|
4
|
+
convention in `git log` (`type(scope): what changed — the reason`). -->
|
|
5
|
+
|
|
6
|
+
## Area touched
|
|
7
|
+
|
|
8
|
+
<!-- Retrieval / trust layer / embedders / MCP server / CLI / eval harness / multi-tenancy / other -->
|
|
9
|
+
|
|
10
|
+
## Checklist
|
|
11
|
+
|
|
12
|
+
- [ ] `ruff check .` passes
|
|
13
|
+
- [ ] `pytest -v` passes against a real pgvector database (`docker compose up -d --wait` — no mock
|
|
14
|
+
DB in this project)
|
|
15
|
+
- [ ] If a dependency changed: `uv lock` was run and the updated `uv.lock` is included (CI runs
|
|
16
|
+
`uv lock --check` as a hard gate)
|
|
17
|
+
- [ ] New behavior has a test that would fail without this change — and the test asserts the actual
|
|
18
|
+
invariant, not a value a shortcut fix could also satisfy (see the README's "Engineering"
|
|
19
|
+
section for examples from this repo)
|
|
20
|
+
- [ ] If this changes a published number (README claims table, `results/FINDINGS.md`,
|
|
21
|
+
`docs/WRITEUP.md`) — the doc is updated in this PR, not left to drift
|
|
22
|
+
- [ ] If this changes calibration, retrieval quality, or the trust layer — `make eval` was re-run
|
|
23
|
+
and the result reviewed, not assumed unchanged
|
|
24
|
+
|
|
25
|
+
## Evaluation impact (if applicable)
|
|
26
|
+
|
|
27
|
+
<!-- Paste the relevant row(s) from results/RESULTS.md or results/SCALE.md before/after, or state
|
|
28
|
+
"no retrieval/trust-layer impact". -->
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# `uv`, not `pip`. This project is uv-managed and CI runs `uv lock --check`, so a bump that
|
|
4
|
+
# edits pyproject.toml without regenerating uv.lock fails the audit job and can never merge —
|
|
5
|
+
# which is exactly what the first `pip` batch did (#44-#48: all red on lockfile drift, while
|
|
6
|
+
# their test jobs passed). The `uv` ecosystem updates the lockfile alongside the manifest.
|
|
7
|
+
#
|
|
8
|
+
# If a Dependabot run ever reports this ecosystem as unsupported, delete this block rather than
|
|
9
|
+
# reverting to `pip`: no dependency PRs is better than a permanent queue of unmergeable ones,
|
|
10
|
+
# and the `audit` job already runs pip-audit over the resolved dependency set, so vulnerability
|
|
11
|
+
# scanning does not depend on this file.
|
|
12
|
+
- package-ecosystem: "uv"
|
|
13
|
+
directory: "/"
|
|
14
|
+
schedule:
|
|
15
|
+
interval: "weekly"
|
|
16
|
+
labels:
|
|
17
|
+
- "dependencies"
|
|
18
|
+
|
|
19
|
+
# This half is proven: the first batch (#41-#43) bumped checkout, setup-python and setup-uv,
|
|
20
|
+
# and merged green.
|
|
21
|
+
- package-ecosystem: "github-actions"
|
|
22
|
+
directory: "/"
|
|
23
|
+
schedule:
|
|
24
|
+
interval: "weekly"
|
|
25
|
+
labels:
|
|
26
|
+
- "dependencies"
|
|
27
|
+
- "ci"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
# Integration tests hit a real pgvector database — no mock DB. Spin one up as a service.
|
|
13
|
+
services:
|
|
14
|
+
db:
|
|
15
|
+
image: pgvector/pgvector:pg16
|
|
16
|
+
env:
|
|
17
|
+
POSTGRES_USER: recall
|
|
18
|
+
POSTGRES_PASSWORD: recall
|
|
19
|
+
POSTGRES_DB: recall
|
|
20
|
+
ports:
|
|
21
|
+
- 5432:5432
|
|
22
|
+
options: >-
|
|
23
|
+
--health-cmd "pg_isready -U recall"
|
|
24
|
+
--health-interval 2s
|
|
25
|
+
--health-timeout 3s
|
|
26
|
+
--health-retries 30
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
# The suite DROPs tables, so it reads RECALL_TEST_DSN and never RECALL_DSN — see
|
|
30
|
+
# tests/conftest.py. RECALL_DSN is deliberately left unset here.
|
|
31
|
+
RECALL_TEST_DSN: postgresql://recall:recall@localhost:5432/recall
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v7
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v7
|
|
37
|
+
with:
|
|
38
|
+
python-version: "3.12"
|
|
39
|
+
cache: pip
|
|
40
|
+
|
|
41
|
+
# Engine + dev tooling only. The optional heavy extras are exercised locally:
|
|
42
|
+
# rerank/entail -> sentence-transformers (their real-model tests self-skip here)
|
|
43
|
+
# voyage -> cloud embedder (its one test skips without VOYAGE_API_KEY)
|
|
44
|
+
- name: Install
|
|
45
|
+
run: pip install -e ".[dev]"
|
|
46
|
+
|
|
47
|
+
- name: Lint (ruff)
|
|
48
|
+
run: ruff check .
|
|
49
|
+
|
|
50
|
+
# Coverage over the SHIPPED packages only (`recall`, `recall_mcp`) — putting the tests in
|
|
51
|
+
# the denominator inflates the number with code that is 100% covered by definition.
|
|
52
|
+
#
|
|
53
|
+
# The floor is 70, measured against ~75% in exactly this environment (the `[dev]` extra,
|
|
54
|
+
# no fastembed/voyage/rerank — the model-backed tests self-skip here, so their modules read
|
|
55
|
+
# lower than a local run with the extras installed). It is a RATCHET, not a target: set
|
|
56
|
+
# below the observed number so a normal PR never trips it on noise, and raised deliberately
|
|
57
|
+
# when a real jump lands. A gate nobody fails on drifts down one PR at a time; a gate pinned
|
|
58
|
+
# to the exact current number fails on the first unlucky rounding.
|
|
59
|
+
- name: Test (pytest on real pgvector, with coverage)
|
|
60
|
+
run: pytest -q --cov=recall --cov=recall_mcp --cov-report=term-missing --cov-report=xml --cov-fail-under=70
|
|
61
|
+
|
|
62
|
+
# Static typing, in its own job: it needs no database, so a type error surfaces in ~30s instead
|
|
63
|
+
# of behind the full integration suite, and a red DB service never hides a red type check.
|
|
64
|
+
#
|
|
65
|
+
# Optional extras are deliberately NOT installed here. `recall.rerank` / `recall.entailment` /
|
|
66
|
+
# `recall.embeddings` import theirs lazily behind a guard, and pyproject's mypy overrides pin
|
|
67
|
+
# those modules to `follow_imports = skip` so this job's result does not depend on whether a
|
|
68
|
+
# 2 GB torch wheel happens to be present.
|
|
69
|
+
typecheck:
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v7
|
|
73
|
+
|
|
74
|
+
- uses: actions/setup-python@v7
|
|
75
|
+
with:
|
|
76
|
+
python-version: "3.12"
|
|
77
|
+
cache: pip
|
|
78
|
+
|
|
79
|
+
- name: Install
|
|
80
|
+
run: pip install -e ".[dev]" mypy
|
|
81
|
+
|
|
82
|
+
- name: Type check (mypy)
|
|
83
|
+
run: mypy
|
|
84
|
+
|
|
85
|
+
# The declared floors, actually installed and actually run.
|
|
86
|
+
#
|
|
87
|
+
# Every other job resolves the NEWEST of everything, so the `>=` bounds in pyproject.toml were
|
|
88
|
+
# never exercised: `mcp>=1.7`, `>=1.10` and `>=1.27.2` are indistinguishable to a green build,
|
|
89
|
+
# and two of those three were wrong — 1.10-1.27.1 installs cleanly and then fails on every
|
|
90
|
+
# authenticated call, because `AccessToken.claims` only exists from 1.27.2. `pgvector>=0.3` was
|
|
91
|
+
# wrong the same way: `from pgvector import Vector` is a 0.4.0 export, so the declared floor
|
|
92
|
+
# named versions where `import recall.store` raises ImportError. A floor nothing resolves at is
|
|
93
|
+
# documentation, not a constraint, and it is documentation that was false.
|
|
94
|
+
#
|
|
95
|
+
# Lowest supported Python as well as lowest dependencies: this is the whole floor, not half of
|
|
96
|
+
# it. Verified green at py3.11.15 + mcp 1.27.2 + pgvector 0.4.0 + psycopg 3.3.4 + pytest 8.0.0,
|
|
97
|
+
# and verified RED against the previous `mcp>=1.10` (auth wiring fails at collection).
|
|
98
|
+
floor:
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
|
|
101
|
+
services:
|
|
102
|
+
db:
|
|
103
|
+
image: pgvector/pgvector:pg16
|
|
104
|
+
env:
|
|
105
|
+
POSTGRES_USER: recall
|
|
106
|
+
POSTGRES_PASSWORD: recall
|
|
107
|
+
POSTGRES_DB: recall
|
|
108
|
+
ports:
|
|
109
|
+
- 5432:5432
|
|
110
|
+
options: >-
|
|
111
|
+
--health-cmd "pg_isready -U recall"
|
|
112
|
+
--health-interval 2s
|
|
113
|
+
--health-timeout 3s
|
|
114
|
+
--health-retries 30
|
|
115
|
+
|
|
116
|
+
env:
|
|
117
|
+
RECALL_TEST_DSN: postgresql://recall:recall@localhost:5432/recall
|
|
118
|
+
|
|
119
|
+
steps:
|
|
120
|
+
- uses: actions/checkout@v7
|
|
121
|
+
|
|
122
|
+
# The `requires-python` floor, not the version the other job happens to use.
|
|
123
|
+
- uses: actions/setup-python@v7
|
|
124
|
+
with:
|
|
125
|
+
python-version: "3.11"
|
|
126
|
+
|
|
127
|
+
- name: Install uv
|
|
128
|
+
uses: astral-sh/setup-uv@v7
|
|
129
|
+
|
|
130
|
+
# `--resolution lowest-direct`: oldest version of each DIRECT dependency, transitives
|
|
131
|
+
# resolved normally. `lowest` would also pin every transitive to its floor, which tests
|
|
132
|
+
# other projects' constraint hygiene rather than ours.
|
|
133
|
+
- name: Install the declared minimums
|
|
134
|
+
run: uv pip install --system --resolution lowest-direct -e ".[dev,mcp]"
|
|
135
|
+
|
|
136
|
+
- name: Show what actually resolved
|
|
137
|
+
run: uv pip list --system
|
|
138
|
+
|
|
139
|
+
- name: Test (pytest on real pgvector)
|
|
140
|
+
run: pytest -q
|
|
141
|
+
|
|
142
|
+
# Dependency vulnerability scan against the committed uv.lock. Runs independently of the
|
|
143
|
+
# test job (no DB needed) so a CVE advisory never blocks the functional suite and vice versa.
|
|
144
|
+
audit:
|
|
145
|
+
runs-on: ubuntu-latest
|
|
146
|
+
steps:
|
|
147
|
+
- uses: actions/checkout@v7
|
|
148
|
+
|
|
149
|
+
- name: Install uv
|
|
150
|
+
uses: astral-sh/setup-uv@v7
|
|
151
|
+
|
|
152
|
+
# Verify the lockfile is in sync with pyproject.toml — a drifted lock would audit stale
|
|
153
|
+
# versions. Then resolve the full dependency set (all extras) to a hashed requirements file
|
|
154
|
+
# and scan it with pip-audit.
|
|
155
|
+
- name: Check lockfile is current
|
|
156
|
+
run: uv lock --check
|
|
157
|
+
|
|
158
|
+
- name: Export locked dependencies
|
|
159
|
+
run: uv export --frozen --all-extras --no-emit-project --format requirements-txt -o requirements.lock.txt
|
|
160
|
+
|
|
161
|
+
# --no-deps: the exported file already pins the full transitive set, so audit exactly
|
|
162
|
+
# those versions instead of re-resolving. This is a real gate (a known CVE fails CI); if
|
|
163
|
+
# it proves too noisy, add `continue-on-error: true` to downgrade it to advisory.
|
|
164
|
+
- name: Audit dependencies (pip-audit)
|
|
165
|
+
run: uvx pip-audit --requirement requirements.lock.txt --no-deps
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when a tag is pushed, and to TestPyPI on demand.
|
|
4
|
+
#
|
|
5
|
+
# Authentication is **Trusted Publishing** (OIDC), so there is no API token in this repository's
|
|
6
|
+
# secrets — nothing to leak, nothing to rotate, and a stolen `contents: write` cannot publish. It
|
|
7
|
+
# does require one-time setup on PyPI before the first run:
|
|
8
|
+
#
|
|
9
|
+
# PyPI -> the `recall-rag` project (or "pending publisher" if it does not exist yet)
|
|
10
|
+
# -> Publishing -> Add a new publisher -> GitHub
|
|
11
|
+
# owner: GiulioDER repository: RE-call workflow: release.yml environment: pypi
|
|
12
|
+
#
|
|
13
|
+
# Without that, the `publish` job fails on authentication — it never publishes to the wrong place.
|
|
14
|
+
# The `environment:` is what lets a required reviewer sit between a pushed tag and a release that
|
|
15
|
+
# can never be un-published: a version number on PyPI is permanent, even after a yank.
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
push:
|
|
19
|
+
tags: ["v*"]
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
inputs:
|
|
22
|
+
target:
|
|
23
|
+
description: "Where to publish"
|
|
24
|
+
required: true
|
|
25
|
+
default: testpypi
|
|
26
|
+
type: choice
|
|
27
|
+
options: [testpypi, pypi]
|
|
28
|
+
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
# Build ONCE and hand the same artifacts to every downstream job. Rebuilding per job would mean
|
|
34
|
+
# the thing that was verified is not bit-for-bit the thing that was published.
|
|
35
|
+
build:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v7
|
|
39
|
+
|
|
40
|
+
- name: Install uv
|
|
41
|
+
uses: astral-sh/setup-uv@v7
|
|
42
|
+
|
|
43
|
+
- name: Build sdist and wheel
|
|
44
|
+
run: uv build
|
|
45
|
+
|
|
46
|
+
# Metadata errors (an unreadable README, a bad classifier) are rejected by PyPI at UPLOAD
|
|
47
|
+
# time, which is the worst moment to discover them: on a tag push, the tag already exists.
|
|
48
|
+
- name: Check metadata
|
|
49
|
+
run: uvx twine check dist/*
|
|
50
|
+
|
|
51
|
+
- uses: actions/upload-artifact@v5
|
|
52
|
+
with:
|
|
53
|
+
name: dist
|
|
54
|
+
path: dist/
|
|
55
|
+
|
|
56
|
+
# Install the built wheel into a clean environment and exercise it. `uv build` succeeding only
|
|
57
|
+
# proves the metadata parses — it says nothing about whether the wheel's contents import, or
|
|
58
|
+
# whether a module was left out of `[tool.hatch.build.targets.wheel].packages`.
|
|
59
|
+
smoke:
|
|
60
|
+
needs: build
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
strategy:
|
|
63
|
+
matrix:
|
|
64
|
+
python: ["3.11", "3.13"] # the declared floor and the newest supported
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/download-artifact@v5
|
|
67
|
+
with:
|
|
68
|
+
name: dist
|
|
69
|
+
path: dist/
|
|
70
|
+
|
|
71
|
+
- uses: actions/setup-python@v7
|
|
72
|
+
with:
|
|
73
|
+
python-version: ${{ matrix.python }}
|
|
74
|
+
|
|
75
|
+
# From the wheel, NOT from the checkout — `pip install -e .` would import the source tree
|
|
76
|
+
# and pass even if the wheel shipped an empty package.
|
|
77
|
+
- name: Install the built wheel
|
|
78
|
+
run: pip install dist/*.whl
|
|
79
|
+
|
|
80
|
+
- name: Import and run the console script
|
|
81
|
+
run: |
|
|
82
|
+
cd "$(mktemp -d)" # away from the source tree, so nothing resolves by accident
|
|
83
|
+
python -c "import recall, recall_mcp; from recall.trust import trusted_search; print(recall.__name__, 'ok')"
|
|
84
|
+
recall --help > /dev/null
|
|
85
|
+
echo "console script ok"
|
|
86
|
+
|
|
87
|
+
publish:
|
|
88
|
+
needs: [build, smoke]
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
environment: ${{ github.event_name == 'push' && 'pypi' || inputs.target }}
|
|
91
|
+
permissions:
|
|
92
|
+
id-token: write # the OIDC token Trusted Publishing exchanges for an upload credential
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/download-artifact@v5
|
|
95
|
+
with:
|
|
96
|
+
name: dist
|
|
97
|
+
path: dist/
|
|
98
|
+
|
|
99
|
+
- name: Publish
|
|
100
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
101
|
+
with:
|
|
102
|
+
# A tag push always goes to PyPI. A manual run goes wherever it was asked to.
|
|
103
|
+
repository-url: ${{ (github.event_name == 'push' || inputs.target == 'pypi') && 'https://upload.pypi.org/legacy/' || 'https://test.pypi.org/legacy/' }}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.pytest_cache/
|
|
4
|
+
.ruff_cache/
|
|
5
|
+
.mypy_cache/
|
|
6
|
+
.coverage
|
|
7
|
+
coverage.xml
|
|
8
|
+
*.egg-info/
|
|
9
|
+
build/
|
|
10
|
+
dist/
|
|
11
|
+
.venv/
|
|
12
|
+
.venv-ci/
|
|
13
|
+
.env
|
|
14
|
+
finetune/model*/
|
|
15
|
+
calibration.json
|
|
16
|
+
.claude/
|
|
17
|
+
results/scale*/corpus/
|
|
18
|
+
results/scale*/.recall-synthetic
|
|
19
|
+
|
|
20
|
+
# LOCOMO benchmark data — fetched on demand, not vendored (see recall/eval/locomo.py)
|
|
21
|
+
locomo10.json
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# This .gitignore file was automatically created by Hypothesis. Hypothesis gitignores
|
|
2
|
+
# .hypothesis by default, because we generally recommend that .hypothesis not be checked
|
|
3
|
+
# into version control.
|
|
4
|
+
#
|
|
5
|
+
# If you *would* like to check .hypothesis into version control, you should delete this
|
|
6
|
+
# file. Hypothesis will not re-create this .gitignore unless .hypothesis is deleted (and
|
|
7
|
+
# if it does, that's a bug - please report it!)
|
|
8
|
+
|
|
9
|
+
*
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: C:\Users\gde00\AppData\Roaming\Python\Python314\site-packages\sortedcontainers\sorteddict.py
|
|
2
|
+
# hypothesis_version: 6.158.0
|
|
3
|
+
|
|
4
|
+
[50331648, ', ', '<not-given>', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'values', 'viewitems', 'viewkeys', 'viewvalues', '{0!r}, ', '{0!r}: {1!r}', '{0}({1}{{{2}}})']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: C:\Users\gde00\AppData\Roaming\Python\Python314\site-packages\sortedcontainers\__init__.py
|
|
2
|
+
# hypothesis_version: 6.158.0
|
|
3
|
+
|
|
4
|
+
[132096, '2.4.0', 'Apache 2.0', 'Grant Jenks', 'SortedDict', 'SortedItemsView', 'SortedKeyList', 'SortedKeysView', 'SortedList', 'SortedListWithKey', 'SortedSet', 'SortedValuesView', 'sortedcontainers']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: C:\Users\gde00\AppData\Roaming\Python\Python314\site-packages\sortedcontainers\sortedlist.py
|
|
2
|
+
# hypothesis_version: 6.158.0
|
|
3
|
+
|
|
4
|
+
[1000, 50331648, '!=', '...', '<', '<=', '==', '>', '>=', '__{0}__', 'equal to', 'greater than', 'index', 'keys', 'len', 'len_index', 'len_keys', 'len_lists', 'len_maxes', 'less than', 'lists', 'load', 'maxes', 'not equal to', 'offset', '{0!r} is not in list', '{0!r} not in list', '{0}({1!r})']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: C:\Users\gde00\AppData\Roaming\Python\Python314\site-packages\_distutils_hack\__init__.py
|
|
2
|
+
# hypothesis_version: 6.158.0
|
|
3
|
+
|
|
4
|
+
['__file__', '_distutils', 'distutils', 'distutils.', 'distutils.core', 'local', 'pybuilddir.txt', 'setup.py', 'spec_for_{fullname}', 'stdlib', 'test.', 'test.test_distutils', 'test.test_importlib']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: C:\Users\gde00\AppData\Local\Temp\claude\C--Users-gde00-Documents-progetto-sentimental--claude-worktrees-audit-fix-deep-79a8a0\7795ded5-981e-4f82-b805-70af4d8da051\scratchpad\prop_bucket.py
|
|
2
|
+
# hypothesis_version: 6.158.0
|
|
3
|
+
|
|
4
|
+
[0.0, 1e-06, 0.001, 0.01, 1.0, 100.0, 1000.0, 2000, '.']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: C:\Users\gde00\Documents\RE-call\recall\observability.py
|
|
2
|
+
# hypothesis_version: 6.158.0
|
|
3
|
+
|
|
4
|
+
[0.5, 0.95, 0.99, 1000.0, 1024, '%Y-%m-%dT%H:%M:%S%z', ',', 'INFO', 'RECALL_LOG_FORMAT', 'RECALL_LOG_LEVEL', '_', 'asctime', 'count', 'counters', 'exc', 'histograms', 'json', 'level', 'logger', 'message', 'nan', 'p50', 'p95', 'p99', 'recall', 'taskName', 'text', 'ts']
|