Skip to content

openfantasymap/inspector

Repository files navigation

inspector

ci docker license

Affordance extraction for embodied scenes. Given an object or situation description and a perspective, returns a structured list of affordances — actions, required capabilities, preconditions, expected outcomes, risks/side-effects, confidence. Suitable for agent planning, LLM tool-use filtering, or game-design analysis.

Speaks the OpenAI chat-completions API: works with OpenAI, OpenRouter (default), Ollama, Groq, Together, or any compatible backend.

Quick start

docker run --rm -p 8000:8000 \
  -e INSPECTOR_OPENAI_API_KEY=sk-or-... \
  -e INSPECTOR_OPENAI_MODEL=anthropic/claude-sonnet-4.6 \
  ghcr.io/openfantasymap/inspector:latest
curl -sS http://localhost:8000/inspect \
  -H "content-type: application/json" \
  -d '{
        "obj": "a rusty iron sword, the hilt wrapped in worn leather",
        "world_facts": "The Sword Coast of Faerûn, near Phandalin.",
        "perspective": "a sixteen-year-old apprentice blacksmith",
        "context": "the boy is alone in the back of the smithy after dusk"
      }' | jq .

Returns:

{
  "affordances": [
    {
      "action": "strike with the flat",
      "target": "an attacker at arm's reach",
      "required_capabilities": ["strength", "intent"],
      "preconditions": ["weapon held two-handed", "attacker within 1m"],
      "expected_outcome": "stun or distract; will not cut through padded armour",
      "possible_failure_modes": ["sword slips from grip", "miss"],
      "confidence_level": "medium"
    },
    ...
  ],
  "model": "anthropic/claude-sonnet-4.6"
}

API

POST /inspect

Body:

{
  "obj":         "a rusty iron sword...",
  "world_facts": "free-text narrative grounding (optional)",
  "perspective": "who is doing the analysis (default: \"Human adult\")",
  "context":     "current situation (default: \"generic\")",
  "model":       "optional model override",
  "temperature": 0.7
}

Returns {"affordances": [...], "model": "..."}. If the model returns invalid JSON the response is HTTP 502 with the diagnostic in detail.

Affordance shape

Each entry in affordances is a dict with these fields (the model is asked to populate them; missing fields are acceptable):

field meaning
action the verb / what is done
target what the action is performed on
applies_to the subset of the object the affordance applies to
combination_of other affordances this composes
required_capabilities skills / tools the agent must have
preconditions what must be true beforehand
constraints physical / social / legal / cultural limits
expected_outcome the intended result
possible_failure_modes how it can go wrong
confidence_level one of high / medium / low

GET /healthz

Returns {"status": "ok"} once env is validated.

Configuration

Env Required Default Purpose
INSPECTOR_OPENAI_API_KEY yes OpenAI-compatible API key.
INSPECTOR_OPENAI_MODEL yes Default model id.
INSPECTOR_OPENAI_BASE_URL no https://openrouter.ai/api/v1 Override for any OpenAI-compatible endpoint.
INSPECTOR_TEMPERATURE no 0.7 Default sampling temperature.
INSPECTOR_HOST no 0.0.0.0 Bind address.
INSPECTOR_PORT no 8000 Bind port.

Development

python -m venv .venv && . .venv/bin/activate
pip install -e .[test]
pytest
uvicorn inspector.app:app --reload

License

Dual-licensed under either of MIT or Apache-2.0, at your option.

About

Affordance extraction for embodied scenes. Given an object or situation, returns a structured list of affordances suitable for agent planning.

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors