#!/usr/bin/env bash # lore-engine-poc — end-to-end test # Calls every tool type and checks for reasonable responses. # Run with: bash test.sh # # v2.T6: every read tool now accepts an optional world_id parameter # (defaulting to "default"). These calls pass world_id="default" explicitly # to verify the v1 behaviour still works — i.e. that the world namespace # is opt-in and does not break existing callers. set -e GATEWAY=${GATEWAY:-http://localhost:8766/mcp} WORLD='"world_id":"default"' call() { local name=$1; shift local args=$1; shift curl -s -X POST "$GATEWAY" \ -H "Content-Type: application/json" \ -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"$name\",\"arguments\":$args}}" \ | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['result']['content'][0]['text'])" } echo "=== 1. entity_context(Aldric Raventhorne) ===" call entity_context "{\"name\":\"Aldric Raventhorne\",${WORLD}}" | python3 -m json.tool | head -8 echo echo "=== 2. was_true_at(House Vyr allied Merchants Guild @ 2nd_age.year_230) ===" call was_true_at "{\"relation\":\"ALLIED_WITH\",\"subject\":\"House Vyr\",\"object\":\"Merchants Guild\",\"at_time\":\"2nd_age.year_230\",${WORLD}}" echo echo "=== 3. was_true_at(Crimson Pact allied House Vyr @ 2nd_age.year_230 — should be false) ===" call was_true_at "{\"relation\":\"ALLIED_WITH\",\"subject\":\"Crimson Pact\",\"object\":\"House Vyr\",\"at_time\":\"2nd_age.year_230\",${WORLD}}" echo echo "=== 4. state_at(Aldric Raventhorne @ 2nd_age.year_260) ===" call state_at "{\"entity\":\"Aldric Raventhorne\",\"at_time\":\"2nd_age.year_260\",${WORLD}}" | python3 -m json.tool | head -10 echo echo "=== 5. ancestors_of(Aldric Raventhorne, 5 generations) ===" call ancestors_of "{\"person\":\"Aldric Raventhorne\",\"generations\":5,${WORLD}}" | python3 -c "import json,sys; print(f'ancestor count: {json.load(sys.stdin)[\"ancestors\"].__len__()}')" echo echo "=== 6. lineage_of(Aldric Raventhorne) ===" call lineage_of "{\"person\":\"Aldric Raventhorne\",${WORLD}}" echo echo "=== 7. log_trade(new) ===" call log_trade "{\"buyer_id\":\"aldric\",\"seller_id\":\"guildmaster\",\"item_id\":\"sword_eventide\",\"quantity\":1,\"unit\":\"gp\",\"unit_price\":750,\"in_fiction_time\":\"2nd_age.year_275\",\"location_id\":\"thornwall\",\"notes\":\"blacksmith of thornwall\",${WORLD}}" echo echo "=== 8. market_price(pale_ledger) ===" call market_price "{\"item_id\":\"pale_ledger\",${WORLD}}" echo echo "=== 9. recall_images(entity_id=aldric) ===" IMG=$(call recall_images "{\"entity_id\":\"aldric\",${WORLD}}") echo "$IMG" | python3 -c "import json,sys; d=json.load(sys.stdin); print(f'image count: {d[\"count\"]}'); print('first caption:', d['images'][0]['caption'][:60] if d['images'] else 'none')" URL=$(echo "$IMG" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['images'][0]['presigned_url']) if d['images'] else exit(1)") echo "first image URL: ${URL:0:80}..." echo echo "--- fetching the presigned URL ---" curl -s -o /tmp/aldric_test.png -w "HTTP %{http_code} | size %{size_download} bytes | type %{content_type}\n" "$URL" file /tmp/aldric_test.png echo echo "=== 10. search_images_by_caption(q=aldric) ===" call search_images_by_caption "{\"q\":\"aldric\",${WORLD}}" | python3 -c "import json,sys; d=json.load(sys.stdin); print(f'matches: {d[\"count\"]}'); [print(f' - {img[\"entity_type\"]}:{img[\"entity_id\"]} — {img[\"caption\"][:50]}...') for img in d['images']]" echo echo "=== 11. register_image(new) ===" call register_image "{\"image_id\":\"img_test\",\"object_key\":\"test/x.png\",\"entity_id\":\"aldric\",\"entity_type\":\"Person\",\"caption\":\"test image\",\"tags\":[\"test\"],\"era\":\"2nd_age\",${WORLD}}" echo echo "=== 12. list_worlds() — v2.T6 admin tool ===" call list_worlds '{}' | python3 -m json.tool echo echo "✅ all tool types tested"