fleet-memory/hindsight-embed/test.sh
Nicolò Boschi 4b57b82301
feat(hindsight-embed): external API support + OpenClaw fixes (#263, #264) (#265)
* feat(hindsight-embed): external API support + OpenClaw fixes

Adds comprehensive external API support and fixes critical OpenClaw plugin issues.

**External API Support:**
- Add HINDSIGHT_EMBED_API_URL to connect to external Hindsight API servers
- Add HINDSIGHT_EMBED_API_TOKEN for Bearer token authentication
- Add HINDSIGHT_EMBED_API_DATABASE_URL for custom PostgreSQL databases
- Skip daemon startup when external API URL is configured
- Add 10 comprehensive unit tests for external API scenarios

**OpenClaw Plugin Fixes:**
- Fix #263: Port mismatch (DEFAULT_PORT 8888 → 8889)
- Fix #264: Add daemon recovery after OpenClaw SIGUSR1 restarts
- Fix OpenRouter support: Pass HINDSIGHT_API_LLM_BASE_URL to daemon
- Fix macOS crashes: Auto-set FORCE_CPU flags for MPS/Metal issues

**LLM Configuration Refactor:**
- Auto-detect provider from standard env vars (OPENAI_API_KEY, etc.)
- Support explicit override via HINDSIGHT_API_LLM_* env vars
- Update model defaults (gemini-2.5-flash, openai/gpt-oss-20b)
- Remove provider-specific base URL support (only HINDSIGHT_API_LLM_BASE_URL)

**Documentation Updates:**
- Rewrite OpenClaw integration docs with crystal clear examples
- Add external API usage examples
- Add OpenRouter free model examples
- Update Quick Start with simplified provider setup

Closes #263, Closes #264

* docs(openclaw): streamline docs and add config inspection

- Remove duplicate/verbose sections (468 → 216 lines)
- Add section showing how to check ~/.hindsight/embed config file
- Add daemon status checking commands
- Keep only essential configuration examples
- Consolidate troubleshooting sections

* fix(test): update daemon health check port from 8889 to 8888

The test was checking port 8889 but we changed the daemon to use port 8888.
2026-01-31 17:02:13 +01:00

236 lines
7.7 KiB
Bash
Executable file

#!/bin/bash
#
# Smoke test for hindsight-embed CLI with daemon mode
# Tests retain and recall operations via the background daemon
#
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
API_DIR="$(cd "$SCRIPT_DIR/../hindsight-api" && pwd)"
echo "=== Hindsight Embed Smoke Test (Daemon Mode) ==="
# Check required environment (load from config if not set)
if [ -f ~/.hindsight/config.env ]; then
source ~/.hindsight/config.env
fi
if [ -z "$HINDSIGHT_EMBED_LLM_API_KEY" ] && [ -z "$OPENAI_API_KEY" ]; then
echo "Error: HINDSIGHT_EMBED_LLM_API_KEY or OPENAI_API_KEY is required"
exit 1
fi
# Use a unique bank ID for this test run
BANK_ID="test-$$-$(date +%s)"
echo "Using bank ID: $BANK_ID"
echo "Script dir: $SCRIPT_DIR"
echo "API dir: $API_DIR"
# Debug: Check if hindsight CLI is available
echo ""
echo "Checking hindsight CLI availability..."
if command -v hindsight &> /dev/null; then
echo " hindsight CLI found at: $(which hindsight)"
else
echo " hindsight CLI not in PATH"
if [ -f ~/.local/bin/hindsight ]; then
echo " Found at ~/.local/bin/hindsight"
else
echo " Not found at ~/.local/bin/hindsight - attempting installation..."
# Try to install the CLI
if curl -fsSL https://hindsight.vectorize.io/get-cli | bash; then
echo " CLI installation completed"
if [ -f ~/.local/bin/hindsight ]; then
echo " CLI now available at ~/.local/bin/hindsight"
export PATH="$HOME/.local/bin:$PATH"
else
echo " WARNING: CLI still not found after installation"
ls -la ~/.local/bin/ 2>/dev/null || echo " ~/.local/bin does not exist"
fi
else
echo " WARNING: CLI installation failed"
fi
fi
fi
# Show environment info for debugging
echo ""
echo "Environment:"
echo " HINDSIGHT_EMBED_LLM_PROVIDER: ${HINDSIGHT_EMBED_LLM_PROVIDER:-not set}"
echo " HINDSIGHT_EMBED_LLM_MODEL: ${HINDSIGHT_EMBED_LLM_MODEL:-not set}"
echo " HINDSIGHT_EMBED_LLM_API_KEY: ${HINDSIGHT_EMBED_LLM_API_KEY:+set (hidden)}"
echo " PATH includes ~/.local/bin: $(echo $PATH | grep -q "$HOME/.local/bin" && echo yes || echo no)"
# Final check that CLI is available before proceeding
echo ""
echo "Final CLI check before tests..."
CLI_PATH=""
if [ -f ~/.local/bin/hindsight ]; then
CLI_PATH="$HOME/.local/bin/hindsight"
elif command -v hindsight &> /dev/null; then
CLI_PATH="$(which hindsight)"
fi
if [ -n "$CLI_PATH" ]; then
echo " CLI found at: $CLI_PATH"
echo " CLI version: $($CLI_PATH --version 2>&1 || echo 'unknown')"
else
echo " ERROR: hindsight CLI not found. Tests cannot proceed."
echo " The hindsight-embed package forwards commands to the hindsight CLI."
echo " Please ensure the CLI is installed or check the get-cli installer output above."
exit 1
fi
# Stop any existing daemon
echo ""
echo "Stopping any existing daemon..."
uv run --project "$SCRIPT_DIR" hindsight-embed daemon stop 2>/dev/null || true
sleep 1
# Test 1: Retain (this should start the daemon)
echo ""
echo "Test 1: Retaining a memory (first call - daemon will start)..."
START_TIME=$(python3 -c "import time; print(time.time())")
set +e # Temporarily disable exit on error to capture output
OUTPUT=$(uv run --project "$SCRIPT_DIR" hindsight-embed memory retain "$BANK_ID" "The user's favorite color is blue" 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(python3 -c "import time; print(time.time())")
DURATION=$(python3 -c "print(f'{$END_TIME - $START_TIME:.2f}')")
echo "$OUTPUT"
echo "Duration: ${DURATION}s"
echo "Exit code: $EXIT_CODE"
if [ $EXIT_CODE -ne 0 ]; then
echo "FAIL: Command exited with code $EXIT_CODE"
echo ""
echo "Checking daemon logs..."
if [ -f ~/.hindsight/daemon.log ]; then
echo "=== daemon.log ==="
tail -50 ~/.hindsight/daemon.log
else
echo "No daemon.log found"
fi
if [ -f ~/.hindsight/daemon.stderr ]; then
echo ""
echo "=== daemon.stderr ==="
cat ~/.hindsight/daemon.stderr
else
echo "No daemon.stderr found"
fi
echo ""
echo "Checking for hindsight-api..."
which hindsight-api 2>/dev/null || echo "hindsight-api not in PATH"
which uvx 2>/dev/null || echo "uvx not in PATH"
which uv 2>/dev/null || echo "uv not in PATH"
exit 1
fi
if ! echo "$OUTPUT" | grep -qi "retained"; then
echo "FAIL: Expected 'retained' in output"
exit 1
fi
echo "PASS: Memory retained successfully"
# Test 2: Recall (daemon already running - should be faster)
echo ""
echo "Test 2: Recalling memories (daemon already running)..."
START_TIME=$(python3 -c "import time; print(time.time())")
set +e
OUTPUT=$(uv run --project "$SCRIPT_DIR" hindsight-embed memory recall "$BANK_ID" "What is the user's favorite color?" 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(python3 -c "import time; print(time.time())")
DURATION=$(python3 -c "print(f'{$END_TIME - $START_TIME:.2f}')")
echo "$OUTPUT"
echo "Duration: ${DURATION}s"
echo "Exit code: $EXIT_CODE"
if [ $EXIT_CODE -ne 0 ]; then
echo "FAIL: Command exited with code $EXIT_CODE"
exit 1
fi
if ! echo "$OUTPUT" | grep -qi "blue"; then
echo "FAIL: Expected 'blue' in recall output"
exit 1
fi
echo "PASS: Memory recalled successfully"
# Test 3: Retain with context (daemon should still be running)
echo ""
echo "Test 3: Retaining memory with context..."
START_TIME=$(python3 -c "import time; print(time.time())")
set +e
OUTPUT=$(uv run --project "$SCRIPT_DIR" hindsight-embed memory retain "$BANK_ID" "User prefers Python over JavaScript" --context work 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(python3 -c "import time; print(time.time())")
DURATION=$(python3 -c "print(f'{$END_TIME - $START_TIME:.2f}')")
echo "$OUTPUT"
echo "Duration: ${DURATION}s"
echo "Exit code: $EXIT_CODE"
if [ $EXIT_CODE -ne 0 ]; then
echo "FAIL: Command exited with code $EXIT_CODE"
exit 1
fi
if ! echo "$OUTPUT" | grep -qi "retained"; then
echo "FAIL: Expected 'retained' in output"
exit 1
fi
echo "PASS: Memory with context retained successfully"
# Test 4: Recall with JSON output
echo ""
echo "Test 4: Recalling with JSON output..."
START_TIME=$(python3 -c "import time; print(time.time())")
set +e
JSON_OUTPUT=$(uv run --project "$SCRIPT_DIR" hindsight-embed memory recall "$BANK_ID" "programming preferences" -o json 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(python3 -c "import time; print(time.time())")
DURATION=$(python3 -c "print(f'{$END_TIME - $START_TIME:.2f}')")
echo "$JSON_OUTPUT"
echo "Duration: ${DURATION}s"
echo "Exit code: $EXIT_CODE"
if [ $EXIT_CODE -ne 0 ]; then
echo "FAIL: Command exited with code $EXIT_CODE"
exit 1
fi
if ! echo "$JSON_OUTPUT" | grep -qi "python"; then
echo "FAIL: Expected 'Python' in recall output"
exit 1
fi
if ! echo "$JSON_OUTPUT" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then
echo "FAIL: Expected valid JSON output"
exit 1
fi
echo "PASS: Memory recalled with JSON format successfully"
# Test 5: Check daemon is running
echo ""
echo "Test 5: Verifying daemon is running..."
if curl -s http://127.0.0.1:8888/health | grep -q "healthy"; then
echo "PASS: Daemon is running and healthy"
else
echo "FAIL: Daemon is not running"
exit 1
fi
# Test 6: Daemon status command
echo ""
echo "Test 6: Testing daemon status command..."
STATUS_OUTPUT=$(uv run --project "$SCRIPT_DIR" hindsight-embed daemon status 2>&1)
echo "$STATUS_OUTPUT"
if ! echo "$STATUS_OUTPUT" | grep -qi "running"; then
echo "FAIL: Expected 'running' in daemon status output"
exit 1
fi
echo "PASS: Daemon status command works"
# Cleanup: Stop daemon
echo ""
echo "Stopping daemon..."
uv run --project "$SCRIPT_DIR" hindsight-embed daemon stop 2>/dev/null || true
echo ""
echo "=== All tests passed! ==="