Commit Graph
7 Commits
Author SHA1 Message Date
Daniel Buckner 695948271f feat: user pins for local model limits (context, max output, thinking)
A local endpoint that publishes no limits — LM Studio's /models says nothing —
left every model on the 8192/4096 defaults with no way to say "this one has a
131k window". Each discovered model now gets three optional pins in the
endpoint editor: context window, max output tokens, thinking (auto/on/off).

A pin always wins: user pin → what the endpoint published → compiled default.
Blank means no opinion, so discovery keeps ruling wherever you don't pin. Pins
live in customProvider.overrides keyed by model id, stored apart from the
discovery snapshot: a reconnect refreshes the models and prunes the pins of
models that vanished while keeping the rest.

Pins are written by PATCH /api/custom-provider, which never probes — the whole
point is configuring a server that isn't answering /models correctly. Connect
still probes and still fails loudly when the endpoint is down. A pin under 2048
tokens is rejected on the write side and clamped up on the read path, matching
the compaction-floor discipline.
2026-10-27 16:25:03 -07:00
Daniel Buckner 286a95ba04 feat: disconnect a custom endpoint (DELETE /api/custom-provider + Disconnect in its editor)
Connecting was one-way: POST could only replace the base URL, and the only
escape was hand-editing settings.json. DELETE now mirrors POST — drop the
stored section, delete the reserved key, unregister the provider from
piModels() — and the connect editor grows a Disconnect beside Connect,
following the stored-key rows' Delete pattern (quiet text, one click, no
confirm, only once there is an endpoint to remove).
2026-10-27 15:56:17 -07:00
Daniel Buckner 1b01919482 feat: thinking levels for custom models (reasoning detected from /models metadata)
Custom models were pinned reasoning:false, so every one of them offered a
single thinking level ("off") while built-in reasoning models offered the
standard ladder. The endpoint's /models metadata now decides:

- detectReasoning() trusts explicit metadata only — a boolean
  reasoning / supports_reasoning / thinking, or a reasoning token in
  supported_parameters (vLLM, OpenRouter), capabilities, tags or
  architecture.output_modalities. No name guessing: a false positive would
  send reasoning_effort to a server that rejects it.
- CustomModel carries the detected flag (persisted, sanitizer keeps it),
  toPiModel passes it through, and pi-ai does the rest — default
  off/minimal/low/medium/high set, reasoning_effort on the wire.

Verified in the browser against a local OpenAI-compatible mock: the
reasoning-capable model exposes off/minimal/low/medium/high, the plain one
stays at off, and a prompt with medium actually arrives as
reasoning_effort=medium.
2026-10-27 15:56:17 -07:00
Daniel Buckner 5b1fd81815 fix: vision slot filters to image-capable + custom models (was relaxing for all providers)
The prior change made the vision slot show every model (image-capable first),
which relaxed the filter for built-in providers too — built-in text-only models
became selectable for Vision. Centralize the vision rule in ModelMenuList:
built-ins must report image input; custom-endpoint models stay selectable (their
capability may be unreported). Image-capable still float first.
2026-10-27 15:56:17 -07:00
Daniel Buckner dbf80803cc refactor: trim custom-endpoint comments and share synthetic provider const
Review pass: shorten verbose doc comments across the custom-endpoint code,
merge duplicate imports, share one synthetic provider entry between the keys
section and setup dialog, collapse the duplicated connect-editor block, revert
an unrelated settings-route drive-by.
2026-10-27 15:56:17 -07:00
Daniel Buckner 870a1ad343 feat: custom endpoint as a first-class provider (add via dropdown, required key, vision ordering) 2026-10-27 15:50:51 -07:00
Daniel Buckner 07b6403d94 feat: custom OpenAI-compatible endpoint as a first-class provider (vision + context from /models) 2026-10-27 15:48:16 -07:00