mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-16 04:18:17 +08:00
feat(ui): gray out thinking depth button on unsupported models
This commit is contained in:
parent
c249dbcb17
commit
5c98d1120e
@ -136,14 +136,16 @@
|
|||||||
<el-icon><Paperclip /></el-icon>
|
<el-icon><Paperclip /></el-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- 深度思考开关 -->
|
<!-- 深度思考开关 (RFC-049 PR-1-UI: 不支持 reasoning_effort 的模型灰态) -->
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="action-btn thinking-btn"
|
class="action-btn thinking-btn"
|
||||||
:class="{ active: thinkingEnabled }"
|
:class="{ active: thinkingEnabled && thinkingSupported, unsupported: !thinkingSupported }"
|
||||||
:disabled="disabled"
|
:disabled="disabled || !thinkingSupported"
|
||||||
@click="emit('toggle-thinking')"
|
@click="thinkingSupported && emit('toggle-thinking')"
|
||||||
:title="thinkingEnabled ? t('chat.thinkingOn') : t('chat.thinkingOff')"
|
:title="!thinkingSupported
|
||||||
|
? t('chat.thinkingUnsupported')
|
||||||
|
: (thinkingEnabled ? t('chat.thinkingOn') : t('chat.thinkingOff'))"
|
||||||
>
|
>
|
||||||
<el-icon><MagicStick /></el-icon>
|
<el-icon><MagicStick /></el-icon>
|
||||||
</button>
|
</button>
|
||||||
@ -239,6 +241,11 @@ interface Props {
|
|||||||
enableTalkMode?: boolean
|
enableTalkMode?: boolean
|
||||||
/** 深度思考开关状态 */
|
/** 深度思考开关状态 */
|
||||||
thinkingEnabled?: boolean
|
thinkingEnabled?: boolean
|
||||||
|
/**
|
||||||
|
* RFC-049 PR-1-UI: 当前 runtime 模型是否支持 reasoning_effort。false 时按钮灰掉,
|
||||||
|
* 不响应点击,tooltip 提示当前模型不支持深度思考。默认 true 以保持向后兼容。
|
||||||
|
*/
|
||||||
|
thinkingSupported?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@ -257,6 +264,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
queueSize: 0,
|
queueSize: 0,
|
||||||
enableTalkMode: false,
|
enableTalkMode: false,
|
||||||
thinkingEnabled: false,
|
thinkingEnabled: false,
|
||||||
|
thinkingSupported: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -598,6 +606,11 @@ defineExpose({
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--el-color-primary, #409eff);
|
background: var(--el-color-primary, #409eff);
|
||||||
}
|
}
|
||||||
|
/* RFC-049 PR-1-UI: model doesn't support reasoning_effort — stronger grayed state */
|
||||||
|
.thinking-btn.unsupported {
|
||||||
|
opacity: 0.35;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
.thinking-btn:hover:not(:disabled) {
|
.thinking-btn:hover:not(:disabled) {
|
||||||
color: var(--el-color-primary, #409eff);
|
color: var(--el-color-primary, #409eff);
|
||||||
background: var(--el-color-primary-light-9, rgba(64, 158, 255, 0.08));
|
background: var(--el-color-primary-light-9, rgba(64, 158, 255, 0.08));
|
||||||
|
|||||||
@ -165,6 +165,7 @@ export default {
|
|||||||
messagePlaceholder: 'Type a message... (Enter to send, Shift+Enter for new line)',
|
messagePlaceholder: 'Type a message... (Enter to send, Shift+Enter for new line)',
|
||||||
thinkingOn: 'Deep thinking enabled',
|
thinkingOn: 'Deep thinking enabled',
|
||||||
thinkingOff: 'Click to enable deep thinking',
|
thinkingOff: 'Click to enable deep thinking',
|
||||||
|
thinkingUnsupported: 'Current model does not support deep thinking',
|
||||||
subtitle: 'Your intelligent AI assistant powered by Spring AI Alibaba',
|
subtitle: 'Your intelligent AI assistant powered by Spring AI Alibaba',
|
||||||
// Queue related
|
// Queue related
|
||||||
queuedSending: 'Sending queued message...',
|
queuedSending: 'Sending queued message...',
|
||||||
|
|||||||
@ -165,6 +165,7 @@ export default {
|
|||||||
messagePlaceholder: '输入消息... (Enter 发送, Shift+Enter 换行)',
|
messagePlaceholder: '输入消息... (Enter 发送, Shift+Enter 换行)',
|
||||||
thinkingOn: '深度思考已开启',
|
thinkingOn: '深度思考已开启',
|
||||||
thinkingOff: '点击开启深度思考',
|
thinkingOff: '点击开启深度思考',
|
||||||
|
thinkingUnsupported: '当前模型不支持深度思考',
|
||||||
subtitle: '基于 Spring AI Alibaba 的智能 AI 助手',
|
subtitle: '基于 Spring AI Alibaba 的智能 AI 助手',
|
||||||
// 排队相关
|
// 排队相关
|
||||||
queuedSending: '正在发送排队消息...',
|
queuedSending: '正在发送排队消息...',
|
||||||
|
|||||||
@ -586,6 +586,14 @@ export interface ProviderModelInfo {
|
|||||||
probeOk?: boolean
|
probeOk?: boolean
|
||||||
/** Short error message when probeOk=false */
|
/** Short error message when probeOk=false */
|
||||||
probeError?: string
|
probeError?: string
|
||||||
|
/**
|
||||||
|
* RFC-049 PR-1-UI: whether the model's `ModelFamily` accepts the
|
||||||
|
* `reasoning_effort` parameter. Derived server-side from the model name;
|
||||||
|
* true only for the OpenAI reasoning family (gpt-5, o1, o3, o4 variants).
|
||||||
|
* Used by the thinking-depth selector to gray itself out on non-reasoning
|
||||||
|
* models.
|
||||||
|
*/
|
||||||
|
supportsReasoningEffort?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProviderInfo {
|
export interface ProviderInfo {
|
||||||
|
|||||||
@ -252,6 +252,7 @@
|
|||||||
@deny="handleDeny"
|
@deny="handleDeny"
|
||||||
:enable-talk-mode="!!selectedAgentId"
|
:enable-talk-mode="!!selectedAgentId"
|
||||||
:thinking-enabled="thinkingEnabled"
|
:thinking-enabled="thinkingEnabled"
|
||||||
|
:thinking-supported="currentModelSupportsReasoningEffort"
|
||||||
@toggle-thinking="thinkingEnabled = !thinkingEnabled"
|
@toggle-thinking="thinkingEnabled = !thinkingEnabled"
|
||||||
@talk="showTalkMode = true"
|
@talk="showTalkMode = true"
|
||||||
/>
|
/>
|
||||||
@ -635,6 +636,26 @@ const currentRuntimeModel = computed(() => {
|
|||||||
return currentAgent.value?.modelName || 'default'
|
return currentAgent.value?.modelName || 'default'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RFC-049 PR-1-UI: whether the active runtime model supports `reasoning_effort`.
|
||||||
|
* Drives the enable/disable state of the thinking-depth toggle in ChatInput:
|
||||||
|
* chat-type models that don't support thinking must not honor the "deep thinking"
|
||||||
|
* selection (product contract — UI reflects the backend gate).
|
||||||
|
*
|
||||||
|
* Source of truth: ProviderModelInfo.supportsReasoningEffort (set by backend via
|
||||||
|
* ModelFamily.detect(modelName) in ModelInfoDTO).
|
||||||
|
*/
|
||||||
|
const currentModelSupportsReasoningEffort = computed<boolean>(() => {
|
||||||
|
const providerId = activeModels.value?.activeLlm?.providerId
|
||||||
|
const modelName = activeModels.value?.activeLlm?.model
|
||||||
|
if (!providerId || !modelName) return false
|
||||||
|
const provider = providers.value.find((p) => p.id === providerId)
|
||||||
|
if (!provider) return false
|
||||||
|
const all = [...(provider.models || []), ...(provider.extraModels || [])]
|
||||||
|
const hit = all.find((m) => m.id === modelName || m.name === modelName)
|
||||||
|
return Boolean(hit?.supportsReasoningEffort)
|
||||||
|
})
|
||||||
|
|
||||||
const userInitial = computed(() => (localStorage.getItem('username') || 'U').charAt(0).toUpperCase())
|
const userInitial = computed(() => (localStorage.getItem('username') || 'U').charAt(0).toUpperCase())
|
||||||
|
|
||||||
const activeModelValue = computed(() => {
|
const activeModelValue = computed(() => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user