ov-layers/skills/notebook-openrouter/SKILL.md
OpenRouter API integration notebook collection provisioned into the workspace volume at deploy time. 3 Jupyter notebooks demonstrating OpenRouter API basics, model discovery, and practical inference. Data-only layer with env_requires — first layer to use the env_requires feature. Use when working with notebook-openrouter, OpenRouter API tutorials, or Jupyter+OpenRouter integration.
npx skillsauth add overthinkos/overthink-plugins notebook-openrouterInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Property | Value |
|----------|-------|
| Dependencies | (none) |
| Packages | (none) |
| Services | (none) |
| Volumes | workspace -> ~/workspace (from jupyter) |
| Data | data/openrouter -> workspace volume, dest: openrouter |
| env_requires | OPENROUTER_API_KEY — API key for OpenRouter LLM inference |
| Install files | (none) |
This is a data layer with an env_requires declaration — it uses the data: field to map notebooks to a volume, and env_requires: to declare that the OPENROUTER_API_KEY environment variable must be present:
info: "OpenRouter API integration notebook collection"
env_requires:
- name: OPENROUTER_API_KEY
description: "API key for OpenRouter LLM inference"
data:
- src: data/openrouter
volume: workspace
dest: openrouter
At build time, the contents of data/openrouter/ are staged into /data/workspace/openrouter/ inside the image.
At deploy time, ov config copies the staged data into the workspace volume at <workspace>/openrouter/. The dest: openrouter field places the notebooks in a subdirectory rather than the volume root.
The env_requires declaration is stored as an OCI label (org.overthinkos.env_requires). At ov config time, if OPENROUTER_API_KEY is not present in the resolved environment, a warning is printed:
Warning: jupyter-ml-notebook requires OPENROUTER_API_KEY (API key for OpenRouter LLM inference) — not set
This is the first layer in the project to use the env_requires feature.
3 Jupyter notebooks covering OpenRouter API usage with the free model qwen/qwen3.6-plus:free:
| Notebook | Topic | Features |
|----------|-------|----------|
| 00_OpenRouter_Basics.ipynb | API Basics | Authentication, simple chat completion, multi-turn conversation, error handling, usage/cost tracking |
| 01_OpenRouter_Models.ipynb | Model Selection | List all models, filter free models, inspect model details (pricing, context, modality), compare responses across models |
| 02_OpenRouter_Inference.ipynb | Practical Inference | Structured JSON output, text summarization, code generation (with exec), reasoning with thinking tokens, translation pipeline |
Manifest: notebooks.yaml — structured catalog with title, description, and ordering.
The free model qwen/qwen3.6-plus:free has strict rate limits (~1 request per minute). All notebooks include an openrouter_chat() / chat() retry helper that handles 429 responses with exponential backoff:
def openrouter_chat(model, messages, retries=5, delay=15):
for attempt in range(retries):
response = requests.post(...)
if response.status_code == 429:
wait = delay * (attempt + 1)
print(f"Rate limited, waiting {wait}s...")
time.sleep(wait)
continue
response.raise_for_status()
return response.json()
The retry helper also handles transient 502 upstream errors from Alibaba (the Qwen provider) where the response is 200 but missing the choices key.
The OPENROUTER_API_KEY must be injected into the container environment:
# Via ov config (persisted in quadlet)
ov config jupyter-ml-notebook -e OPENROUTER_API_KEY=sk-or-v1-...
# Via workspace .env file
echo "OPENROUTER_API_KEY=sk-or-v1-..." >> ~/project/.env
# Via direnv .secrets (GPG-encrypted)
ov secrets gpg set OPENROUTER_API_KEY sk-or-v1-...
# image.yml
jupyter-ml-notebook:
layers:
- jupyter-ml
- notebook-templates
- notebook-finetuning
- notebook-ollama
- notebook-llm-on-supercomputers
- notebook-openrouter
# ... other layers
# Deploy with API key
ov config jupyter-ml-notebook -e OPENROUTER_API_KEY=sk-or-v1-...
ov start jupyter-ml-notebook
# Open http://localhost:8888 -> navigate to openrouter/
/ov-images:jupyter-ml-notebook/ov:layer — data field documentation, env_requires/env_accepts field documentation/ov:config — data provisioning and env_requires warning during ov config setup/ov:deploy — volume backing configuration/ov-layers:notebook-ollama — sibling data layer pattern (Ollama integration notebooks)/ov-layers:notebook-finetuning — sibling data layer pattern (Unsloth fine-tuning notebooks)/ov-layers:notebook-templates — sibling data layer pattern (starter notebooks)/ov-layers:notebook-llm-on-supercomputers — sibling data layer pattern (TU Wien course notebooks)/ov-images:jupyter-ml-notebook — the image that includes this layerUse when the user asks about:
OPENROUTER_API_KEY to Jupyter containersenv_requires feature (this is the first real consumer)qwen/qwen3.6-plus:free/ov:test — declarative testing (tests: block, ov image test, ov test)tools
Use when authoring or modifying a charly PLUGIN — a candy with a `plugin:` block that contributes Providers (verbs/kinds/deploy-targets/steps/builders/commands), its own CUE schema, builtin (compiled-in) or external (out-of-tree git repo). Covers the unified Provider model, the per-plugin CUE-schema contract (single source → Go params for dev + schema-over-Describe RPC for runtime), the SDK, and the loader.
tools
The CUE data-validation / configuration CLI (cue), pinned to v0.16.1. Use when working with the cue candy, installing the cue binary into a box or onto a target:local dev host, or running the offline schema-vendoring pipeline that feeds charly's egress validation.
tools
CUE EGRESS validation — validating (and, where it adds value, generating) the config files charly WRITES to a system BEFORE the bytes hit disk. MUST be invoked before working on charly/egress.go, the vendored schemas under candy/plugin-egress/egress-schemas/vendor/, the ValidateEgress / registerVendoredEgressKind path, the offline `task cue:vendor` pipeline, or adding an egress schema for any written artifact (cloud-init, k8s manifests, traefik routes, runtime config, install ledger, systemd/quadlet units, ssh_config, libvirt XML).
tools
Kubernetes cluster-probe declarative check verb — the `kube:` check verb (nodes, pods, ingress, storage class, addon health, apply/delete, and arbitrary resource GETs) served out-of-process by the candy/plugin-kube plugin (vendored client-go; no external kubectl required).