Skip to content
AI & Agents
Skill

/droid-model-setup

Configure any third-party model as a custom model in Factory Droid (~/.factory/settings.json): resolve specs (context window, max output tokens, reasoning efforts), write a safe config entry, set session defaults, and prove the wiring with a live droid exec run and, when needed,

BOOST
From plugin
droidproxy
1233 skills
Install
$ npx -y skills add nikships/droidproxy --skill droid-model-setup --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/droid-model-setup

Context preview

The summary Claude sees to decide when to auto-load this skill.

Configure any third-party model as a custom model in Factory Droid (~/.factory/settings.json): resolve specs (context window, max output tokens, reasoning efforts), write a safe config entry, set session defaults, and prove the wiring with a live droid exec run and, when needed,

SKILL.md

droid-model-setup.SKILL.md
name: droid-model-setup
description: >
  Configure any third-party model as a custom model in Factory Droid (~/.factory/settings.json):
  resolve specs (context window, max output tokens, reasoning efforts), write a safe config entry,
  set session defaults, and prove the wiring with a live droid exec run and, when needed, an exact
  request-body capture. Fully open-ended: use whenever the user asks to "set X, Y, Z models up for
  a Droid", add/register a custom model, fix a model that ignores its reasoning setting, raise max
  tokens or context for BYOK models, or verify what parameters Droid actually sends. Triggers
  include "set up <model> for droid", "configure droid models", "add custom model",
  "which models does droid support", and "verify my droid model config".

Droid model setup

Turns any OpenAI-compatible (and most Anthropic-compatible) endpoint into a first-class Droid model. Covers spec lookup, safe writes to `~/.factory/settings.json`, session-default effort wiring, and empirical verification. Knowledge below was verified Aug 2026 against the real binary by capturing Droid's outgoing request bodies.

Workflow for "set X, Y, Z models up for a Droid"

1. **Resolve specs per model** (ask only what cannot be looked up; be agentic otherwise).

  • OpenRouter-hosted model: fetch `https://openrouter.ai/<vendor>/<slug>` — gives context

window, max completion tokens, supported reasoning efforts, pricing.

  • Other providers: check their docs/API reference for context length and output cap.
  • Note whether thinking/reasoning can be toggled and via which parameter.

2. **Determine endpoint + credentials.**

  • Same provider already registered in settings? Reuse its key with the script's

`--reuse-key-from <existing-model-id>` (reads the real stored bytes; the asterisks you see in file reads are display-only redaction, and Python sees through them).

  • New provider: ask the user for the base URL and API key if genuinely unknown. Defaults:

OpenRouter `https://openrouter.ai/api/v1`, LM Studio `http://127.0.0.1:1234/v1`, llama.cpp/vLLM/Ollama-OpenAI `http://127.0.0.1:<port>/v1`.

  • Provider field: `generic-chat-completion-api` covers every OpenAI-compatible endpoint

tested (OpenRouter, W&B, LM Studio, MTPLX). `openai` also works for OpenAI-compat APIs. 3. **Write entries with the helper script** (never hand-edit settings.json — see gotchas). Model `id` in settings becomes the CLI-facing name: `-m custom:<id>`. 4. **Set session defaults** if the user wants one of them as the daily driver (`set-defaults` subcommand sets model + matching reasoningEffort together). 5. **Verify live**, then report exactly what was configured and proven.

Hard rules

**Never text-edit `~/.factory/settings.json`.** Existing `apiKey` values render as runs of asterisks inside the agent's file viewer; a string-replacement edit that touches those lines writes literal asterisks to disk and destroys real keys. Use `scripts/droid_models.py`, which mutates parsed JSON (untouched values stay byte-identical), backs the file up first, and afterward diffs every pre-existing key — restoring automatically and failing loudly if anything changed. If you must edit manually anyway (new top-level keys etc.), anchor edits far away from apiKey lines, then diff `{id: len(apiKey)}` old-vs-new via Python before declaring success.

**Config is not verification.** A written entry proves nothing. Always finish with:

droid exec -m custom:<model-id> 'Reply with exactly: config-ok'

A successful run also re-proves the API key survived whatever edit preceded it.

How Droid actually sends requests (wire facts)

Captured exact body for a `generic-chat-completion-api` custom model:

{"model":"<slug>","stream":true,"max_tokens":<N>,"temperature":1,"reasoning_effort":"<effort>"}
  • **Streaming is always on** (`stream:true` is hardcoded, plus `stream_options.include_usage`);

there is no settings knob and none needed.

  • **No separate thinking object** on this path: `reasoning_effort` alone carries the intent;

OpenRouter maps it to `reasoning.effort`. Anthropic-style paths instead get `reasoning_effort` verbatim plus `budget_tokens` (low 4096, medium 12288, high/xhigh 24576, max = uncapped/0).

  • **`maxOutputTokens` maps 1:1 to `max_tokens`.** Omit it and Droid falls back to small built-in

ceilings — always set it to the model's real max completion tokens.

  • **Effort ladder:** `none, minimal, low, medium, high, xhigh, max, dynamic, off`.
  • **Resolution order beats model entry:** exec `-r/--reasoning-effort` flag >

`sessionDefaultSettings.reasoningEffort` > `customModels[].reasoningEffort`. Classic bug: model entry says `max`, session default says `none` → sessions run with thinking off. When configuring for real use, set BOTH (the script's `set-defaults` does this atomically).

  • **`extraArgs` is the escape hatch:** arbitrary JSON merged last into every request body

(wins over everything). Example: `"extraArgs": {"top_p": 0.9}`. No `--stream` style toggles — only body params.

full schema of a customModel entry

All fields observed in the binary's zod schema (optional unless noted): `model`* (upstream slug), `id`*, `index`* (unique int — script auto-picks), `baseUrl`, `apiKey` | `apiKeyHelper`(+`apiKeyHelperTtlMs`), `authMode` ("bearer" for Anthropic SDK token path), `provider`*, `displayName`, `maxContextLimit`, `maxOutputTokens`, `enableThinking`, `thinkingMaxTokens`, `reasoningEffort`, `noImageSupport`, `extraHeaders`, `extraArgs`, `bedrock`, `baseModelId`.

Verification beyond config-ok

Token counts between efforts are NOT reliable proof of transmission (tiny prompts barely trigger thinking at any effort). To prove exact request bodies, do a wire capture:

1. Run a tiny dump server that records POST bodies to JSONL and returns a canned chat-completion response (a ~30-line Python http.server is enough; return one fixed JSON body an

Read more
Ships withdroidproxy

A native macOS menu bar app that proxies Claude Code, Codex, Gemini, Kimi, GitHub Copilot, Junie, and Grok authentication for use with Droids. Built on CLIProxyAPI.

Get the whole plugin
Stats
123
Stars
21
Forks
Active
Maintenance
Swift
Language
MIT
License
14h ago
Last commit
7mo ago
Created
3h ago
Added

Repo: nikships/droidproxy

Other skills on droidproxy.