Commit Graph
5 Commits
Author SHA1 Message Date
amosblomqvist b48821309b feat: finish donor-led custom endpoint integration 2026-10-29 04:43:53 +02:00
iamabhishekt b4a13f5c3b feat: manual model IDs when /models is unavailable
Hosted OpenAI-compatible APIs often serve chat but not GET /models
(Volcengine Ark Agent Plan returns 404), so connect failed. Accept a
typed list of model IDs: merged into discovered models when /models
works, used alone when it does not. The typed list is stored as
customProvider.manualModels so reconnects and pin saves keep it.
2026-10-28 16:16:30 -04:00
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 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 07b6403d94 feat: custom OpenAI-compatible endpoint as a first-class provider (vision + context from /models) 2026-10-27 15:48:16 -07:00