mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-10-17 13:19:18 +02:00
* feat(AI): per-model thinking toggle with global default (off)
Stop forcing thinking on for every capable model. Adds a global default
(ai.autoThinking, ships OFF) and a per-model override in the chat window,
shown only for thinking-capable models and remembered client-side.
The /v1 (OpenAI-compat) endpoint ignores `think`; reasoning_effort is the
real lever. The controller resolves per-request preference -> global default
-> OFF (gated on capability), and the service maps that to reasoning_effort
('none' to suppress on a capable model, 'medium' for gpt-oss, unset to let a
capable model default thinking on). A new thinkingCapable flag keeps
non-Ollama backends from ever receiving reasoning_effort.
installed-models is enriched with a `thinking` flag (checkModelHasThinking,
now memoized) so the picker knows which models get the toggle.
Stacks on #1078 (reasoning-field read + client-disconnect abort).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(AI): thinking toggle as NOMAD Switch + info tooltip
Address review feedback on the per-model thinking control:
- Use the shared Switch component (matches AI Assistant settings) instead
of a raw checkbox.
- Label "Thinking:" with a colon to match the adjacent "Model:" label.
- Add an InfoTooltip explaining what thinking does and where the default
lives. Extend InfoTooltip with optional `position` ('top'|'bottom') and
`align` ('center'|'right') so it opens downward and expands leftward from
the right-edge header slot instead of being clipped/crushed against the
viewport edge. Defaults preserve existing (benchmark page) behavior.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import vine from '@vinejs/vine'
|
|
|
|
export const chatSchema = vine.compile(
|
|
vine.object({
|
|
model: vine.string().trim().minLength(1),
|
|
messages: vine.array(
|
|
vine.object({
|
|
role: vine.enum(['system', 'user', 'assistant'] as const),
|
|
content: vine.string(),
|
|
})
|
|
),
|
|
stream: vine.boolean().optional(),
|
|
sessionId: vine.number().positive().optional(),
|
|
// Effective per-request thinking preference (per-model override or global default),
|
|
// resolved client-side. Omitted -> server falls back to the ai.autoThinking KV default.
|
|
think: vine.boolean().optional(),
|
|
})
|
|
)
|
|
|
|
export const unloadChatModelsSchema = vine.compile(
|
|
vine.object({
|
|
targetModel: vine.string().trim().minLength(1).nullable().optional(),
|
|
})
|
|
)
|
|
|
|
export const getAvailableModelsSchema = vine.compile(
|
|
vine.object({
|
|
sort: vine.enum(['pulls', 'name'] as const).optional(),
|
|
recommendedOnly: vine.boolean().optional(),
|
|
query: vine.string().trim().optional(),
|
|
limit: vine.number().positive().optional(),
|
|
force: vine.boolean().optional(),
|
|
})
|
|
)
|