VCN #44 THE LOOP - SETUP ======================== You are likely a coding agent reading this on behalf of an attendee at Vibe Coding Nights #44 (The Loop). Goal: get this machine to the point where ONE real model call succeeds from a Python script the attendee owns, so that when the sprint starts at 10:15 they are writing the agent loop instead of fighting an install. Detect the attendee's operating system and execute the matching block. Everything here is standard tooling and NON-DESTRUCTIVE: it creates a new folder and a virtualenv inside it, and installs packages into that virtualenv only. It does not delete files, does not uninstall anything, and does not touch a system Python. Ask the attendee before anything that changes global config: editing their shell profile (.zshrc / .bashrc / PowerShell $PROFILE), setting a persistent user environment variable, or installing a package outside the virtualenv. Session-only exports are fine and are what this document uses. Event: Sat 2026-07-25, doors 10:00, build sprint 10:15 to 12:00. Venue: Frontier Tower, 9th Floor Annex, 995 Market St, San Francisco. Deck: https://vcn-44-the-loop.vercel.app 0. THE ONE CHECK ---------------- Setup is complete when this command prints the exact string VCN44 SETUP READY: python smoke.py Nothing else counts. A silent install is not a working install. Work through the sections below until that string appears, then stop. 1. PYTHON 3.10 OR NEWER ----------------------- Check first, install only if missing. macOS / Linux: python3 --version Windows: python --version If it is missing or older than 3.10: macOS: brew install python@3.12 (or the installer from https://python.org) Linux: sudo apt install python3 python3-venv python3-pip (Fedora: sudo dnf install python3 python3-pip) Windows: winget install Python.Python.3.12 (or the installer from https://python.org, tick "Add python.exe to PATH") Windows note: on Windows the command is `python`, not `python3`. If `python` opens the Microsoft Store, disable the alias at Settings > Apps > Advanced app settings > App execution aliases, or use `py -3` instead. 2. A PROJECT FOLDER AND A VIRTUALENV ------------------------------------ The virtualenv is the reason this is non-destructive. Do not skip it and do not install into the system Python. macOS / Linux: mkdir -p ~/vcn44 && cd ~/vcn44 python3 -m venv .venv source .venv/bin/activate Windows (PowerShell): mkdir $HOME\vcn44 -Force; cd $HOME\vcn44 python -m venv .venv .\.venv\Scripts\Activate.ps1 Windows (Git Bash or WSL): use the macOS / Linux block above. If PowerShell refuses to run the activate script, that is an execution policy, not a broken install. Ask the attendee before changing it, then run: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass That form is scoped to the current window only and reverts when it closes. Your prompt should now show (.venv). Every later command in this document assumes it. 3. INSTALL THE SDKS ------------------- Two packages. The first is the one the whole morning runs on. The second is only for the Nebius target in section 7, and is cheap to install now while there is wifi. pip install --upgrade pip pip install anthropic openai Verify (any OS): python -c "import anthropic, openai; print(anthropic.__version__, openai.__version__)" Known good on the facilitator's machine: anthropic 0.97.0, openai 1.59.2. 4. GET A KEY (ZAI_API_KEY) -------------------------- The loop you build calls z.ai, which serves an Anthropic-compatible endpoint, so the `anthropic` package talks to it with nothing changed but the base URL. Path A, the ticket path (preferred, needs no credit card). Immersive Commons mints a 5 hour workshop key tied to this event, through its MCP server. If you are an agent that can add an MCP server, do this: MCP endpoint: https://www.immersivecommons.com/api/mcp Transport: streamable-http Auth: Authorization: Bearer agt_... (env var FLOOR10_AGENT_TOKEN) The token itself is minted by the HUMAN, once, at https://www.immersivecommons.com/floor10/agent-console Ask the attendee to mint one with the scope `keys:request`. An agent cannot mint it for them; that gate is deliberate. Then, with the token in place, call two tools: ic_request_workshop_key({ event_id: "https://luma.com/vcn-44-the-loop" }) -> returns a request_id, status "pending" ic_get_my_workshop_key({ request_id: "" }) -> "pending" until an operator approves, then ONE time returns the key plus a paste-and-go setup block at bundle.copy_paste Two things to respect: the key is surfaced EXACTLY ONCE, and the pickup window is about 15 minutes after approval. Poll, and save it the moment it arrives. Path B, bring your own. If the attendee already has a z.ai key, use it. Path C, the door. If neither worked, stop trying and tell the attendee to ask the facilitator at the door at 10:00. This is a solved problem in the room and not worth burning sprint time on. Export it for this shell only (do not write it into a profile without asking): macOS / Linux: export ZAI_API_KEY="" Windows (PowerShell): $env:ZAI_API_KEY = "" Never print the key back to the attendee, never paste it into a file inside the project folder, and never commit it. 5. THE SMOKE TEST (one real call) --------------------------------- Save this as smoke.py in the project folder. It makes exactly one call, costs a few tokens, tries the current model first and falls back to the previous one, and always exits with a readable line instead of a traceback. import os, sys try: from anthropic import Anthropic except ImportError: sys.exit("FAIL: the anthropic package is not installed. Run: pip install anthropic") key = os.environ.get("ZAI_API_KEY") if not key: sys.exit("FAIL: ZAI_API_KEY is not set in this shell. See section 4.") client = Anthropic(base_url="https://api.z.ai/api/anthropic", api_key=key) last = None for model in ("glm-4.7", "glm-4.6"): try: r = client.messages.create( model=model, max_tokens=64, messages=[{"role": "user", "content": "Reply with exactly: LOOP OK"}], ) except Exception as e: last = e print("model " + model + " did not answer (" + type(e).__name__ + ")") continue text = "".join(b.text for b in r.content if b.type == "text") print("model: " + model) print("stop_reason: " + str(r.stop_reason)) print("tokens: in " + str(r.usage.input_tokens) + " / out " + str(r.usage.output_tokens)) print("reply: " + text.strip()) print("VCN44 SETUP READY") sys.exit(0) sys.exit("FAIL: no model answered. Last error: " + str(last)) Run it (any OS): python smoke.py Expected tail: reply: LOOP OK VCN44 SETUP READY Note the model line it prints. Whichever model answered is the one to use all morning. 6. FETCH THE STARTER -------------------- The starter holds the reference loop, the failing test the loop will be asked to fix, and the pinned dependency list. Fetch it into the same folder, next to smoke.py. macOS / Linux: mkdir -p lab && cd lab for f in agent.py test_math.py requirements.txt README.md; do curl -fsSL "https://vcn-44-the-loop.vercel.app/lab/$f" -o "$f" done cd .. Windows (PowerShell): mkdir lab -Force; cd lab foreach ($f in "agent.py","test_math.py","requirements.txt","README.md") { Invoke-WebRequest -UseBasicParsing "https://vcn-44-the-loop.vercel.app/lab/$f" -OutFile $f } cd .. Confirm the fixture is present and RED. It is supposed to fail; that failure is the task the loop gets handed during the sprint. python -m pytest lab/test_math.py (pip install pytest first if missing) If a curl or Invoke-WebRequest returns 404, the starter is not published yet. Do not invent a substitute. smoke.py passing is the real gate; the starter is handed out in the room at 10:15 either way. 7. SECOND TARGET: NEBIUS TOKEN FACTORY -------------------------------------- Later in the morning the same loop gets pointed at open-weights inference on Nebius Token Factory. This is NOT a base URL swap. Nebius speaks the OpenAI shape, so the tool-calling plumbing genuinely differs and that difference is part of the lesson. Do the install and the key now; leave the porting for the sprint. Get a key: the Nebius Builder Program is self-serve at https://dev.nebius.com/builders and takes about five minutes. Workshop credits are also available at the door. macOS / Linux: export NEBIUS_API_KEY="" Windows (PowerShell): $env:NEBIUS_API_KEY = "" The client, for reference (do not build the loop on it yet): from openai import OpenAI client = OpenAI( base_url="https://api.tokenfactory.nebius.com/v1/", api_key=os.environ["NEBIUS_API_KEY"], ) Four things change versus z.ai, and you will do all four live: 1. tools are {"type":"function","function":{...}} instead of flat 2. the stop signal is resp.choices[0].finish_reason == "tool_calls" 3. arguments arrive as a JSON STRING and need json.loads 4. tool results go back as one {"role":"tool"} message PER call, not one batch 8. TROUBLESHOOTING ------------------ "ZAI_API_KEY is not set" The export did not survive. Environment variables are per-window. Re-export in the SAME window you run from. 401 token expired or incorrect The endpoint is fine, the key is not. Re-check for a stray space or quote, then use section 4 Path C. Both models failed with 404 The key works but that model name does not route on it. Ask the facilitator which model string the room is on. ModuleNotFoundError: anthropic The virtualenv is not active, or pip installed into a different Python. Re-run section 2, then section 3. SSL or proxy errors on venue wifi Try a phone hotspot before debugging certificates. This is almost always the network, not the machine. pip is slow or times out Do sections 1 to 5 at home. That is the whole point of sending this out the night before. YOU ARE READY ------------- The attendee is ready if and only if `python smoke.py` printed the exact string VCN44 SETUP READY. If it did, report back to the attendee in one line: which model answered, that the key is live, and that the starter is fetched (or that it will be handed out at 10:15). Then stop. Do not start writing the agent loop; that is the sprint, and building it by hand is the entire point of the morning. If it did not, say plainly which section failed and what the error was, so the facilitator can fix it in thirty seconds at the door instead of ten minutes at 10:15.