-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
151 lines (130 loc) · 6.14 KB
/
Copy pathMakefile
File metadata and controls
151 lines (130 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
.PHONY: up down logs psql migrate test smoke line-count clean bench-locomo bench-longmemeval bench-smoke bench-mem0-stack bench-zep-stack bench-openrouter-free local
# Bring the stack up (build first), detached
up:
docker compose up --build -d
# Tear the stack down
down:
docker compose down
# Stream app logs
logs:
docker compose logs -f app
# Open a psql session in the db container
psql:
docker compose exec db psql -U pgkg -d pgkg
# Wipe all ingested data but keep schema and migration tracking.
# Use this between experiments (e.g. switching from chunks-only to propositions mode).
wipe:
@if [ "$$CI" != "1" ]; then \
printf "This will TRUNCATE documents, propositions, entities, edges, proposition_cache. Continue? [y/N] "; \
read ans; case "$$ans" in y|Y|yes) ;; *) echo "Aborted."; exit 1 ;; esac; \
fi
docker compose exec -T db psql -U pgkg -d pgkg -c \
"TRUNCATE documents, propositions, entities, edges, proposition_cache RESTART IDENTITY CASCADE;"
@echo "Wiped. Schema and migration tracking preserved."
# Run database migrations inside the running app container
migrate:
docker compose exec app pgkg migrate
# Run the test suite locally
test:
uv run pytest -q
# Smoke test: health check + memorize + recall
smoke:
@echo "--- health ---"
@curl -sf http://localhost:${PGKG_APP_PORT:-8000}/health | python3 -m json.tool || (echo "FAIL: /health unreachable" && exit 1)
@echo ""
@echo "--- memorize ---"
@MEMO_ID=$$(curl -sf -X POST http://localhost:${PGKG_APP_PORT:-8000}/memorize \
-H 'Content-Type: application/json' \
-d '{"content": "pgkg smoke test memory", "tags": ["smoke"]}' | python3 -m json.tool); \
echo "$$MEMO_ID"; \
echo ""; \
echo "--- recall ---"; \
curl -sf -X POST http://localhost:${PGKG_APP_PORT:-8000}/recall \
-H 'Content-Type: application/json' \
-d '{"query": "smoke test memory", "top_k": 3}' | python3 -m json.tool || (echo "FAIL: recall failed" && exit 1)
@echo ""
@echo "Smoke test passed."
# Print line counts: Python vs SQL
line-count:
@bash scripts/line_count.sh
# Destroy everything including volumes, caches, and local artifacts
clean:
docker compose down -v
rm -rf .venv .pytest_cache htmlcov .coverage
# Benchmarks
bench-locomo:
uv run python -m bench.locomo --limit 2
bench-longmemeval:
uv run python -m bench.longmemeval --variant longmemeval_s --limit 5
bench-smoke:
PGKG_OFFLINE_EXTRACT=1 uv run python -m bench.locomo --dry-run --limit 1
PGKG_OFFLINE_EXTRACT=1 uv run python -m bench.longmemeval --variant longmemeval_s --dry-run --limit 1
# Stack preset benchmarks
# Each target warns the user about cost and requires confirmation unless CI=1.
bench-mem0-stack:
@if [ "$$CI" != "1" ]; then \
echo "WARNING: This benchmark will call OpenAI APIs and spend real money."; \
echo "Make sure OPENAI_API_KEY is set and you accept the cost."; \
read -p "Continue? [y/N] " ans; \
[ "$$ans" = "y" ] || [ "$$ans" = "Y" ] || (echo "Aborted." && exit 1); \
fi
set -a; source .env.bench-mem0-stack; set +a; \
uv run python -m bench.locomo && \
uv run python -m bench.longmemeval --variant longmemeval_s
bench-zep-stack:
@if [ "$$CI" != "1" ]; then \
echo "WARNING: This benchmark uses gpt-4o and is significantly more expensive."; \
echo "Make sure OPENAI_API_KEY is set and you accept the cost."; \
read -p "Continue? [y/N] " ans; \
[ "$$ans" = "y" ] || [ "$$ans" = "Y" ] || (echo "Aborted." && exit 1); \
fi
set -a; source .env.bench-zep-stack; set +a; \
uv run python -m bench.locomo && \
uv run python -m bench.longmemeval --variant longmemeval_s
# NOTE: local-claude runs the app on the HOST (not inside Docker) because the
# claude-agent-sdk shells out to the local 'claude' binary on your PATH.
# The db container runs as normal; only the app must stay on the host.
local-claude: ## Run pgkg locally with Claude Code subscription bridge (Pro/Max users)
@echo "Local experimentation mode — uses your claude CLI subscription."
@echo "Requires: claude CLI installed and logged in. Run 'claude' once first."
@command -v claude >/dev/null 2>&1 || { echo "claude CLI not found. Install from https://claude.com/claude-code"; exit 1; }
set -a; source .env.local-claude; set +a; \
./scripts/dev_db.sh && \
uv run pgkg migrate && \
uv run pgkg serve
# Ablation baseline: pure chunk RAG (no LLM extraction). Same stack as bench-mem0-stack
# but with --chunks-only on both bench commands. Quantifies the value of proposition extraction.
bench-mem0-stack-chunks:
@if [ "$$CI" != "1" ]; then \
echo "WARNING: This benchmark will call OpenAI APIs and spend real money."; \
echo "Make sure OPENAI_API_KEY is set and you accept the cost."; \
read -p "Continue? [y/N] " ans; \
[ "$$ans" = "y" ] || [ "$$ans" = "Y" ] || (echo "Aborted." && exit 1); \
fi
set -a; source .env.bench-mem0-stack; set +a; \
uv run python -m bench.locomo --chunks-only && \
uv run python -m bench.longmemeval --variant longmemeval_s --chunks-only
# Zero-LLM local mode: chunks-only ingest with hybrid retrieval. No API key, no claude CLI.
local-chunks: ## Run pgkg locally in chunks-only mode (zero LLM at ingest)
@echo "Local chunks-only mode — pure hybrid RAG. No LLM, no API key, no claude CLI required."
set -a; source .env.local-chunks; set +a; \
./scripts/dev_db.sh && \
uv run pgkg migrate && \
uv run pgkg serve
bench-openrouter-free:
@if [ "$$CI" != "1" ]; then \
echo "WARNING: Free-tier OpenRouter is rate-limited. Use --limit 5 or expect throttling."; \
echo "Make sure OPENAI_API_KEY=sk-or-v1-... (OpenRouter key) is set."; \
read -p "Continue? [y/N] " ans; \
[ "$$ans" = "y" ] || [ "$$ans" = "Y" ] || (echo "Aborted." && exit 1); \
fi
set -a; source .env.bench-openrouter-free; set +a; \
uv run python -m bench.locomo --limit 5 && \
uv run python -m bench.longmemeval --variant longmemeval_s --limit 5
# Embedded Postgres via pgserver — no Docker, no env file, no external process.
# Just works: omit PGKG_DATABASE_URL and pgserver auto-starts.
# Requires: uv sync --extra embedded
local: ## Run pgkg with auto-managed embedded Postgres (chunks-only, zero LLM)
@echo "Embedded Postgres mode — no Docker, no config needed."
@echo "Data persists in ~/.local/share/pgkg/pgdata."
uv run pgkg migrate && uv run pgkg serve