mirror of
https://github.com/rohitg00/agentmemory.git
synced 2026-09-14 20:16:33 +08:00
7fb72f4010
* feat(eval): pluggable benchmark harness with in-house coding-agent corpus Adds eval/ tree (outside files field so npm tarball stays thin) with Adapter interface, three reference adapters (grep / vector / agentmemory-hybrid), two benchmarks (LongMemEval _s public, coding-agent-life-v1 in-house 15 sessions), scoring (P@K, R@K, hit, top-gold-rank), NDJSON output, sandbox script. coding-agent-life-v1 published scorecard at docs/benchmarks/2026-05-20-coding-agent-life-v1.md: agentmemory-hybrid R@5=0.967 P@5=0.578 (100% hit) vs grep R@5=0.967 P@5=0.267. 2.2x better precision on identical input, sandbox-reproducible. Adapter contract: init(sessions, config) -> State; query(q, state, k) -> RankedDoc[] npm scripts: npm run eval:coding-life (no download, no API key for grep) npm run eval:longmemeval (needs OPENAI key + 278MB download) eval/scripts/sandbox.sh boots clean agentmemory + iii-engine on ports 3411/3412 with isolated data dir; tears down on exit. README headline updated. 1072/1072 tests pass + 5 new eval tests. * fix(eval): address review findings on benchmark harness - agentmemory adapter: prefer row.sessionId before observationToSession lookup - vector adapter: validate embedBatch response (length, indexes, non-empty rows) - coding-life: positive-int guard on --k; wrap query loop in try/finally so teardown runs - longmemeval: positive-int guards on --k/--limit/--stratify; per-question try/finally - load: throw on haystack_session_ids vs haystack_sessions length mismatch - score: P@K denominator is k (requested cutoff) not topK.length - sandbox.sh: guard rm -rf with non-empty + /tmp/ prefix check - README: drop unsafe rm "$(which iii)"; instruct ~/.local/bin + PATH instead; add language tag to repo-layout fenced block - sessions.json: fix "two-phase" -> "three-phase" wording mismatch
118 lines
3.3 KiB
Bash
Executable File
118 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Boot a sandboxed agentmemory + iii-engine on alt ports with a clean data dir,
|
|
# so eval runs aren't polluted by (and don't pollute) your real ~/.agentmemory.
|
|
# Source it: `source eval/scripts/sandbox.sh` then run eval scripts;
|
|
# the sandbox is torn down on EXIT.
|
|
|
|
set -euo pipefail
|
|
|
|
SANDBOX_ROOT="${SANDBOX_ROOT:-/tmp/agentmemory-eval-sandbox}"
|
|
SANDBOX_PORT="${SANDBOX_PORT:-3411}"
|
|
SANDBOX_STREAM_PORT="${SANDBOX_STREAM_PORT:-3412}"
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
|
|
if ! command -v iii >/dev/null 2>&1; then
|
|
echo "iii binary not on PATH. Install pinned version:"
|
|
echo " curl -fsSL https://github.com/iii-hq/iii/releases/download/iii/v0.11.2/iii-aarch64-apple-darwin.tar.gz | tar -xz -C ~/.local/bin"
|
|
exit 1
|
|
fi
|
|
|
|
iii_ver=$(iii --version 2>&1 | head -1)
|
|
if [[ "$iii_ver" != "0.11.2" ]]; then
|
|
echo "warning: iii version on PATH is $iii_ver; agentmemory pins 0.11.2"
|
|
fi
|
|
|
|
if [[ ! -f "$REPO_ROOT/dist/index.mjs" ]]; then
|
|
echo "dist/ missing. Run: npm run build" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${SANDBOX_ROOT:-}" || "$SANDBOX_ROOT" == "/" || "$SANDBOX_ROOT" != /tmp/* ]]; then
|
|
echo "refusing to wipe SANDBOX_ROOT='$SANDBOX_ROOT' — must be non-empty and under /tmp/" >&2
|
|
exit 1
|
|
fi
|
|
rm -rf "$SANDBOX_ROOT"
|
|
mkdir -p "$SANDBOX_ROOT/data" "$SANDBOX_ROOT/.agentmemory"
|
|
|
|
cat > "$SANDBOX_ROOT/iii-config.yaml" <<EOF
|
|
workers:
|
|
- name: iii-http
|
|
config:
|
|
port: $SANDBOX_PORT
|
|
host: 127.0.0.1
|
|
default_timeout: 180000
|
|
cors:
|
|
allowed_origins: ["http://localhost:$SANDBOX_PORT", "http://127.0.0.1:$SANDBOX_PORT"]
|
|
allowed_methods: [GET, POST, PUT, DELETE, OPTIONS]
|
|
- name: iii-state
|
|
config:
|
|
adapter:
|
|
name: kv
|
|
config:
|
|
store_method: file_based
|
|
file_path: $SANDBOX_ROOT/data/state_store.db
|
|
- name: iii-queue
|
|
config:
|
|
adapter:
|
|
name: builtin
|
|
- name: iii-pubsub
|
|
config:
|
|
adapter:
|
|
name: local
|
|
- name: iii-cron
|
|
config:
|
|
adapter:
|
|
name: kv
|
|
- name: iii-stream
|
|
config:
|
|
port: $SANDBOX_STREAM_PORT
|
|
host: 127.0.0.1
|
|
adapter:
|
|
name: kv
|
|
config:
|
|
store_method: file_based
|
|
file_path: $SANDBOX_ROOT/data/stream_store
|
|
- name: iii-observability
|
|
config:
|
|
enabled: true
|
|
service_name: agentmemory-eval
|
|
exporter: memory
|
|
sampling_ratio: 1.0
|
|
metrics_enabled: true
|
|
logs_enabled: false
|
|
logs_console_output: false
|
|
- name: iii-exec
|
|
config:
|
|
exec:
|
|
- node $REPO_ROOT/dist/index.mjs
|
|
EOF
|
|
|
|
cd "$SANDBOX_ROOT"
|
|
HOME="$SANDBOX_ROOT" iii --config "$SANDBOX_ROOT/iii-config.yaml" > "$SANDBOX_ROOT/iii.log" 2>&1 &
|
|
SANDBOX_PID=$!
|
|
|
|
cleanup() {
|
|
echo "tearing down sandbox (pid $SANDBOX_PID)"
|
|
kill "$SANDBOX_PID" 2>/dev/null || true
|
|
sleep 1
|
|
kill -9 "$SANDBOX_PID" 2>/dev/null || true
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# wait for livez
|
|
for i in $(seq 1 30); do
|
|
if curl -sS --max-time 1 "http://localhost:$SANDBOX_PORT/agentmemory/livez" 2>/dev/null | grep -q '"status":"ok"'; then
|
|
export AGENTMEMORY_BASE_URL="http://localhost:$SANDBOX_PORT"
|
|
echo "sandbox ready: $AGENTMEMORY_BASE_URL"
|
|
echo " state: $SANDBOX_ROOT/data/"
|
|
echo " logs: $SANDBOX_ROOT/iii.log"
|
|
return 0 2>/dev/null || exit 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo "sandbox failed to come up within 30s. last log lines:" >&2
|
|
tail -10 "$SANDBOX_ROOT/iii.log" >&2
|
|
exit 1
|