Python client library for the Case Closed detective game API.
pip install git+https://github.com/RailtownAI/case-closed.gitThen set your token in the environment before running:
# macOS / Linux
export DETECTIVE_TOKEN=your_token_here
# Windows PowerShell
$env:DETECTIVE_TOKEN = "your_token_here"Or drop it in a .env file in your working directory and python-dotenv will pick it up automatically:
DETECTIVE_TOKEN=your_token_here
git clone https://github.com/RailtownAI/case-closed.git
cd case-closed
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -r requirements.txtCopy .env.example to .env and fill in your token:
cp .env.example .env
# edit .env and set DETECTIVE_TOKEN=your_token_herefrom detective_client import DetectiveClient
client = DetectiveClient() # reads DETECTIVE_TOKEN from .env
session = client.start_session("S001")
print(session.briefing.synopsis)
# Navigate
obs = client.move("loc_office")
print(obs.description)
# Gather evidence
obs = client.search()
for clue in obs.clues:
print(clue.clue_id, clue.text)
# Interview a character
obs = client.interview("char_finn")
print(obs.testimony)
# Present evidence to unlock guarded clues
obs = client.present("char_mara", ref_id="clue_04")
# Commit your solution
result = client.commit(
culprit_id="char_silas",
means_id="means_blade",
evidence_notes=[
{"clue_id": "clue_04", "note": "Silas signed the midnight delivery himself, placing him at the warehouse."},
{"clue_id": "clue_S2", "note": "He confessed when confronted with the ledger and the knife."},
],
process_explanation=(
"Silas arranged the cargo run to lure Marsh to the warehouse, then stabbed him "
"when Marsh threatened to report the illegal operation to the authorities."
),
)
print(f"Score: {result.score:.2f} Culprit correct: {result.culprit_correct}")
print(f"Notes: {result.notes_score:.2f} Explanation: {result.explanation_score:.2f}")seeds = client.list_seeds()
for s in seeds.seeds:
print(s.seed_id, s.title)| Method | Description |
|---|---|
start_session(seed_id) |
Begin a new investigation; returns SessionInfo |
get_state() |
Current location and remaining actions |
move(location_id) |
Move to an adjacent location |
search() |
Search the current location for evidence |
interview(character_id) |
Ask a character for free testimony |
present(character_id, ref_id) |
Show a clue/item to unlock guarded testimony |
commit(culprit_id, means_id, process_explanation) |
Submit your solution |
list_seeds() |
List available game seeds |
knowledge_summary() |
Formatted summary of clues and inventory |
agent_random.py— baseline agent that submits without investigating (useful for API smoke-testing)agent_template.py— production template using therailtracksframework for LLM-driven investigationhuman_agent.ipynb— interactive Jupyter notebook walkthrough
To run the random agent:
python agent_random.py # runs against S001
python agent_random.py S002 # specify a seedTo use the railtracks agent template, install extras first:
python agent_template.py| Variable | Description |
|---|---|
DETECTIVE_TOKEN |
Your Case Closed API token (required) |