fix: host-side LLM extraction (claude CLI not in container)

The claude CLI is installed on the Dalidou HOST but not inside
the Docker container. The /admin/extract-batch API endpoint with
mode=llm silently returned 0 candidates because
shutil.which('claude') was None inside the container.

Fix: extraction runs host-side via deploy/dalidou/batch-extract.sh
which calls scripts/batch_llm_extract_live.py with the host's
PYTHONPATH pointing at the repo's src/. The script:

- Fetches interactions from the API (GET /interactions?since=...)
- Runs extract_candidates_llm() locally (host has claude CLI)
- POSTs candidates back to the API (POST /memory, status=candidate)
- Tracks last-run timestamp via project state

The cron now calls the host-side script instead of the container
API endpoint for LLM mode. Rule-mode extraction in the container
still works via /admin/extract-batch.

The API endpoint retains the mode=llm option for environments
where claude IS inside the container (future Docker image with
claude CLI, or a different deployment model).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 10:55:22 -04:00
parent c67bec095c
commit cd0fd390a8
3 changed files with 219 additions and 12 deletions

View File

@@ -83,22 +83,18 @@ else
fi
# Step 4: Batch LLM extraction on recent interactions (optional).
# Runs the LLM extractor (claude -p sonnet) against interactions
# captured since the last batch run. Candidates land as
# status=candidate for human or auto-triage review.
# Runs HOST-SIDE because claude CLI is on the host, not inside the
# Docker container. The script fetches interactions from the API,
# runs claude -p locally, and POSTs candidates back.
# Fail-open: extraction failure never blocks backup.
# The endpoint tracks its own last-run timestamp in project state.
EXTRACT="${ATOCORE_EXTRACT_BATCH:-true}"
if [[ "$EXTRACT" == "true" ]]; then
log "Step 4: running batch LLM extraction"
EXTRACT_RESULT=$(curl -sf -X POST \
-H "Content-Type: application/json" \
-d '{"mode": "llm", "persist": true, "limit": 50}' \
--max-time 600 \
"$ATOCORE_URL/admin/extract-batch" 2>&1) && {
log "Extraction result: $EXTRACT_RESULT"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
log "Step 4: running host-side batch LLM extraction"
bash "$SCRIPT_DIR/batch-extract.sh" 2>&1 && {
log "Extraction complete"
} || {
log "WARN: batch extraction failed (this is non-blocking): $EXTRACT_RESULT"
log "WARN: batch extraction failed (this is non-blocking)"
}
else
log "Step 4: ATOCORE_EXTRACT_BATCH not set to true, skipping extraction"