pan

Setup guide

pan is the school's LLM gateway: one LearningHub login, a personal budget, and the models your role unlocks — in the chat, in your editor and from your own code.

Chat in the browser

everyone

Open the chat and choose Login with LearningHub. Nothing to configure.

The tutor explains, asks questions and gives hints and pseudocode — it doesn't hand out finished solutions. Sprinters work with the tutor only; keys unlock at level 1. Anyone can pick tutor when they'd rather be guided than handed an answer.

Create your personal key

level 1 and up

On My access, create your personal key. It's shown once — copy it straight into your shell profile or secret manager.

Connect your tool

Claude Code

Add these to your shell profile, then run claude.

~/.zshrc
export ANTHROPIC_BASE_URL=https://ai.42hn.dev
export ANTHROPIC_AUTH_TOKEN=<personal key>
export ANTHROPIC_MODEL=sonnet-5.5
export ANTHROPIC_DEFAULT_SONNET_MODEL=sonnet-5.5
export ANTHROPIC_DEFAULT_HAIKU_MODEL=haiku-4.5
# level 2 and up; otherwise set it to sonnet-5.5
export ANTHROPIC_DEFAULT_OPUS_MODEL=opus-5.5
  • Set all four model variables. The gateway only knows its own names (sonnet-5.5, haiku-4.5, opus-5.5 from level 2) — without the DEFAULT_* ones Claude Code asks for names it rejects.
  • A startup note that the model is unrecognized is harmless.
  • The cost Claude Code prints is its own estimate. Your real spend is under Usage.

Codex

Add pan as a provider, then export your key and run codex.

~/.codex/config.toml
model = "gpt-5.6-terra"
model_provider = "pan"

[model_providers.pan]
name = "pan"
base_url = "https://ai.42hn.dev/v1"
env_key = "PAN_API_KEY"
wire_api = "responses"
shell
export PAN_API_KEY=<personal key>
codex
  • Swap model for any chat model your role unlocks on Models.

OpenAI SDK

pan speaks the OpenAI API, so any OpenAI client works with a different base URL.

main.py
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://ai.42hn.dev/v1",
    api_key=os.environ["PAN_API_KEY"],
)

reply = client.chat.completions.create(
    model="gpt-5.6-luna",
    messages=[{"role": "user", "content": "Explain pointers in C"}],
)
print(reply.choices[0].message.content)
  • Most OpenAI clients also read OPENAI_BASE_URL and OPENAI_API_KEY from the environment, so existing code runs unchanged.
  • For a side project, use your project key — it is capped at $10 per 30 days.
  • To see the models your role may use, GET /v1/models with your key.

Continue, Zed, Cursor

In Continue, Zed or Cursor, add an OpenAI-compatible provider with these settings.

SettingValue
Provideropenai
API basehttps://ai.42hn.dev/v1
API keyyour personal key
Modelany name from Models
  • Next to Claude and GPT there are open models such as kimi-k2.7-code and qwen3.8-27b that cost a fraction, and qwen3.5-9b for almost nothing.

Images and audio

Images and audio go through the same gateway and the same budget. In the chat they power image generation, voice input and read-aloud.

shell
# flash-image also answers chat requests
curl https://ai.42hn.dev/v1/images/generations -H "Authorization: Bearer <personal key>" \
  -H "Content-Type: application/json" -d '{"model": "flash-image", "prompt": "a lighthouse at dusk"}'

curl https://ai.42hn.dev/v1/audio/speech -H "Authorization: Bearer <personal key>" -o hello.mp3 \
  -H "Content-Type: application/json" \
  -d '{"model": "voice", "input": "Hello!", "voice": "en_paul_neutral", "response_format": "mp3"}'

curl https://ai.42hn.dev/v1/audio/transcriptions -H "Authorization: Bearer <personal key>" \
  -F model=whisper -F file=@recording.wav