mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-30 04:40:18 +08:00
feat(hermes): add base model config
This commit is contained in:
@@ -83,6 +83,12 @@ const QUICK_COMMANDS_DEFAULTS = {
|
||||
quickCommandsJson: '{}',
|
||||
}
|
||||
|
||||
const MODEL_DEFAULTS = {
|
||||
modelDefault: '',
|
||||
modelProvider: 'auto',
|
||||
modelBaseUrl: '',
|
||||
}
|
||||
|
||||
const MODEL_ALIASES_DEFAULTS = {
|
||||
modelAliasesJson: '{}',
|
||||
}
|
||||
@@ -300,6 +306,7 @@ export function render() {
|
||||
let memoryValues = { ...MEMORY_DEFAULTS }
|
||||
let skillsValues = { ...SKILLS_DEFAULTS }
|
||||
let quickCommandsValues = { ...QUICK_COMMANDS_DEFAULTS }
|
||||
let modelValues = { ...MODEL_DEFAULTS }
|
||||
let modelAliasesValues = { ...MODEL_ALIASES_DEFAULTS }
|
||||
let hooksValues = { ...HOOKS_DEFAULTS }
|
||||
let providerOverridesValues = { ...PROVIDER_OVERRIDES_DEFAULTS }
|
||||
@@ -333,6 +340,7 @@ export function render() {
|
||||
let memoryLoading = true
|
||||
let skillsLoading = true
|
||||
let quickCommandsLoading = true
|
||||
let modelLoading = true
|
||||
let modelAliasesLoading = true
|
||||
let hooksLoading = true
|
||||
let providerOverridesLoading = true
|
||||
@@ -366,6 +374,7 @@ export function render() {
|
||||
let memorySaving = false
|
||||
let skillsSaving = false
|
||||
let quickCommandsSaving = false
|
||||
let modelSaving = false
|
||||
let modelAliasesSaving = false
|
||||
let hooksSaving = false
|
||||
let providerOverridesSaving = false
|
||||
@@ -399,6 +408,7 @@ export function render() {
|
||||
let memoryError = null
|
||||
let skillsError = null
|
||||
let quickCommandsError = null
|
||||
let modelError = null
|
||||
let modelAliasesError = null
|
||||
let hooksError = null
|
||||
let providerOverridesError = null
|
||||
@@ -431,7 +441,7 @@ export function render() {
|
||||
}
|
||||
|
||||
function isBusy() {
|
||||
return loading || runtimeLoading || compressionLoading || promptCachingLoading || openrouterCacheLoading || providerRoutingLoading || auxiliaryLoading || toolGuardrailsLoading || memoryLoading || skillsLoading || quickCommandsLoading || modelAliasesLoading || hooksLoading || providerOverridesLoading || mcpServersLoading || agentToolsetsLoading || platformToolsetsLoading || agentRuntimeLoading || unauthorizedDmLoading || securityLoading || displayLoading || humanDelayLoading || streamingLoading || executionLimitsLoading || ioSafetyLoading || checkpointsLoading || cronLoading || loggingLoading || approvalsLoading || privacyLoading || browserLoading || sttLoading || terminalLoading || saving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || quickCommandsSaving || modelAliasesSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || platformToolsetsSaving || agentRuntimeSaving || unauthorizedDmSaving || securitySaving || displaySaving || humanDelaySaving || streamingSaving || executionLimitsSaving || ioSafetySaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || privacySaving || browserSaving || sttSaving || terminalSaving
|
||||
return loading || runtimeLoading || compressionLoading || promptCachingLoading || openrouterCacheLoading || providerRoutingLoading || auxiliaryLoading || toolGuardrailsLoading || memoryLoading || skillsLoading || quickCommandsLoading || modelLoading || modelAliasesLoading || hooksLoading || providerOverridesLoading || mcpServersLoading || agentToolsetsLoading || platformToolsetsLoading || agentRuntimeLoading || unauthorizedDmLoading || securityLoading || displayLoading || humanDelayLoading || streamingLoading || executionLimitsLoading || ioSafetyLoading || checkpointsLoading || cronLoading || loggingLoading || approvalsLoading || privacyLoading || browserLoading || sttLoading || terminalLoading || saving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || quickCommandsSaving || modelSaving || modelAliasesSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || platformToolsetsSaving || agentRuntimeSaving || unauthorizedDmSaving || securitySaving || displaySaving || humanDelaySaving || streamingSaving || executionLimitsSaving || ioSafetySaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || privacySaving || browserSaving || sttSaving || terminalSaving
|
||||
}
|
||||
|
||||
function option(labelKey, value, selected) {
|
||||
@@ -893,7 +903,7 @@ export function render() {
|
||||
}
|
||||
|
||||
function renderQuickCommandsConfigPanel() {
|
||||
const disabled = loading || saving || quickCommandsLoading || quickCommandsSaving || modelAliasesSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || agentRuntimeSaving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || streamingSaving || executionLimitsSaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || terminalSaving
|
||||
const disabled = loading || saving || quickCommandsLoading || quickCommandsSaving || modelSaving || modelAliasesSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || agentRuntimeSaving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || streamingSaving || executionLimitsSaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || terminalSaving
|
||||
return `
|
||||
<div class="hm-panel hm-config-runtime-panel hm-config-quick-commands-panel">
|
||||
<div class="hm-panel-header">
|
||||
@@ -918,8 +928,44 @@ export function render() {
|
||||
`
|
||||
}
|
||||
|
||||
function renderModelConfigPanel() {
|
||||
const disabled = loading || saving || modelLoading || modelSaving || quickCommandsSaving || modelAliasesSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || agentRuntimeSaving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || streamingSaving || executionLimitsSaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || terminalSaving
|
||||
return `
|
||||
<div class="hm-panel hm-config-runtime-panel hm-config-model-panel">
|
||||
<div class="hm-panel-header">
|
||||
<div>
|
||||
<div class="hm-panel-title">${t('engine.hermesModelConfigTitle')}</div>
|
||||
<div class="hm-channel-panel-desc">${t('engine.hermesModelConfigDesc')}</div>
|
||||
</div>
|
||||
<div class="hm-panel-actions">
|
||||
<span class="hm-muted">${modelSaving ? t('engine.hermesConfigStatusSaving') : modelLoading ? t('engine.hermesConfigStatusLoading') : t('engine.hermesModelConfigStatusReady')}</span>
|
||||
<button class="hm-btn hm-btn--cta hm-btn--sm" id="hm-model-config-save" ${disabled ? 'disabled' : ''}>${t('engine.hermesModelConfigSave')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hm-panel-body">
|
||||
${renderError(modelError)}
|
||||
<div class="hm-config-runtime-grid">
|
||||
<label class="hm-field">
|
||||
<span class="hm-field-label">${t('engine.hermesModelConfigDefault')}</span>
|
||||
<input id="hm-model-default" class="hm-input" value="${esc(modelValues.modelDefault)}" placeholder="anthropic/claude-opus-4.6" ${disabled ? 'disabled' : ''}>
|
||||
</label>
|
||||
<label class="hm-field">
|
||||
<span class="hm-field-label">${t('engine.hermesModelConfigProvider')}</span>
|
||||
<input id="hm-model-provider" class="hm-input" value="${esc(modelValues.modelProvider)}" placeholder="auto" ${disabled ? 'disabled' : ''}>
|
||||
</label>
|
||||
<label class="hm-field hm-field--wide">
|
||||
<span class="hm-field-label">${t('engine.hermesModelConfigBaseUrl')}</span>
|
||||
<input id="hm-model-base-url" class="hm-input" value="${esc(modelValues.modelBaseUrl)}" placeholder="https://openrouter.ai/api/v1" ${disabled ? 'disabled' : ''}>
|
||||
</label>
|
||||
</div>
|
||||
<div class="hm-channel-footnote">${t('engine.hermesModelConfigFootnote')}</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
function renderModelAliasesConfigPanel() {
|
||||
const disabled = loading || saving || modelAliasesLoading || modelAliasesSaving || quickCommandsSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || agentRuntimeSaving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || streamingSaving || executionLimitsSaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || terminalSaving
|
||||
const disabled = loading || saving || modelAliasesLoading || modelAliasesSaving || quickCommandsSaving || modelSaving || hooksSaving || providerOverridesSaving || mcpServersSaving || agentToolsetsSaving || agentRuntimeSaving || runtimeSaving || compressionSaving || promptCachingSaving || openrouterCacheSaving || providerRoutingSaving || auxiliarySaving || toolGuardrailsSaving || memorySaving || skillsSaving || streamingSaving || executionLimitsSaving || checkpointsSaving || cronSaving || loggingSaving || approvalsSaving || terminalSaving
|
||||
return `
|
||||
<div class="hm-panel hm-config-runtime-panel hm-config-model-aliases-panel">
|
||||
<div class="hm-panel-header">
|
||||
@@ -1974,6 +2020,7 @@ export function render() {
|
||||
${renderMemoryPanel()}
|
||||
${renderSkillsConfigPanel()}
|
||||
${renderQuickCommandsConfigPanel()}
|
||||
${renderModelConfigPanel()}
|
||||
${renderModelAliasesConfigPanel()}
|
||||
${renderHooksConfigPanel()}
|
||||
${renderProviderOverridesConfigPanel()}
|
||||
@@ -2014,6 +2061,7 @@ export function render() {
|
||||
el.querySelector('#hm-memory-save')?.addEventListener('click', saveMemory)
|
||||
el.querySelector('#hm-skills-config-save')?.addEventListener('click', saveSkillsConfig)
|
||||
el.querySelector('#hm-quick-commands-save')?.addEventListener('click', saveQuickCommandsConfig)
|
||||
el.querySelector('#hm-model-config-save')?.addEventListener('click', saveModelConfig)
|
||||
el.querySelector('#hm-model-aliases-save')?.addEventListener('click', saveModelAliasesConfig)
|
||||
el.querySelector('#hm-hooks-save')?.addEventListener('click', saveHooksConfig)
|
||||
el.querySelector('#hm-provider-overrides-save')?.addEventListener('click', saveProviderOverridesConfig)
|
||||
@@ -2093,6 +2141,11 @@ export function render() {
|
||||
quickCommandsValues = { ...QUICK_COMMANDS_DEFAULTS, ...(data?.values || {}) }
|
||||
}
|
||||
|
||||
async function loadModelConfig() {
|
||||
const data = await api.hermesModelConfigRead()
|
||||
modelValues = { ...MODEL_DEFAULTS, ...(data?.values || {}) }
|
||||
}
|
||||
|
||||
async function loadModelAliasesConfig() {
|
||||
const data = await api.hermesModelAliasesConfigRead()
|
||||
modelAliasesValues = { ...MODEL_ALIASES_DEFAULTS, ...(data?.values || {}) }
|
||||
@@ -2215,6 +2268,7 @@ export function render() {
|
||||
memoryLoading = true
|
||||
skillsLoading = true
|
||||
quickCommandsLoading = true
|
||||
modelLoading = true
|
||||
modelAliasesLoading = true
|
||||
hooksLoading = true
|
||||
providerOverridesLoading = true
|
||||
@@ -2248,6 +2302,7 @@ export function render() {
|
||||
memoryError = null
|
||||
skillsError = null
|
||||
quickCommandsError = null
|
||||
modelError = null
|
||||
modelAliasesError = null
|
||||
hooksError = null
|
||||
providerOverridesError = null
|
||||
@@ -2446,6 +2501,14 @@ export function render() {
|
||||
quickCommandsLoading = false
|
||||
draw()
|
||||
}
|
||||
try {
|
||||
await loadModelConfig()
|
||||
} catch (err) {
|
||||
modelError = humanizeError(err, t('engine.hermesModelConfigLoadFailed') || 'Load model config failed')
|
||||
} finally {
|
||||
modelLoading = false
|
||||
draw()
|
||||
}
|
||||
try {
|
||||
await loadModelAliasesConfig()
|
||||
} catch (err) {
|
||||
@@ -2944,6 +3007,33 @@ export function render() {
|
||||
}
|
||||
}
|
||||
|
||||
async function saveModelConfig() {
|
||||
const form = {
|
||||
modelDefault: el.querySelector('#hm-model-default')?.value || '',
|
||||
modelProvider: el.querySelector('#hm-model-provider')?.value || 'auto',
|
||||
modelBaseUrl: el.querySelector('#hm-model-base-url')?.value || '',
|
||||
}
|
||||
modelSaving = true
|
||||
modelError = null
|
||||
draw()
|
||||
try {
|
||||
const result = await api.hermesModelConfigSave(form)
|
||||
modelValues = { ...MODEL_DEFAULTS, ...(result?.values || form) }
|
||||
await refreshRawAfterStructuredSave()
|
||||
const backup = result?.backup || ''
|
||||
toast({
|
||||
message: t('engine.hermesModelConfigSaveSuccess'),
|
||||
hint: backup ? t('engine.hermesConfigBackupHint', { path: backup }) : '',
|
||||
}, 'success')
|
||||
} catch (err) {
|
||||
modelError = humanizeError(err, t('engine.hermesModelConfigSaveFailed') || 'Save model config failed')
|
||||
toast(modelError, 'error')
|
||||
} finally {
|
||||
modelSaving = false
|
||||
draw()
|
||||
}
|
||||
}
|
||||
|
||||
async function saveModelAliasesConfig() {
|
||||
const form = {
|
||||
modelAliasesJson: el.querySelector('#hm-model-aliases-json')?.value || '{}',
|
||||
|
||||
@@ -529,6 +529,8 @@ export const api = {
|
||||
hermesSkillsConfigSave: (form) => invoke('hermes_skills_config_save', { form }),
|
||||
hermesQuickCommandsConfigRead: () => invoke('hermes_quick_commands_config_read'),
|
||||
hermesQuickCommandsConfigSave: (form) => invoke('hermes_quick_commands_config_save', { form }),
|
||||
hermesModelConfigRead: () => invoke('hermes_model_config_read'),
|
||||
hermesModelConfigSave: (form) => invoke('hermes_model_config_save', { form }),
|
||||
hermesModelAliasesConfigRead: () => invoke('hermes_model_aliases_config_read'),
|
||||
hermesModelAliasesConfigSave: (form) => invoke('hermes_model_aliases_config_save', { form }),
|
||||
hermesHooksConfigRead: () => invoke('hermes_hooks_config_read'),
|
||||
|
||||
@@ -823,6 +823,17 @@ export default {
|
||||
hermesQuickCommandsConfigSaveFailed: _('保存快捷命令失败', 'Save quick commands failed', '儲存快捷命令失敗'),
|
||||
hermesQuickCommandsConfigJson: _('quick_commands JSON 映射', 'quick_commands JSON map', 'quick_commands JSON 映射'),
|
||||
hermesQuickCommandsConfigFootnote: _('键名会变成斜杠命令,例如 status 对应 /status。每个命令必须是对象,type 只能为 exec 或 alias;exec 需要 command,alias 的 target 必须以 / 开头。', 'Keys become slash commands, for example status maps to /status. Each command must be an object with type exec or alias; exec needs command, and alias target must start with /.', '鍵名會變成斜線命令,例如 status 對應 /status。每個命令必須是物件,type 只能是 exec 或 alias;exec 需要 command,alias 的 target 必須以 / 開頭。'),
|
||||
hermesModelConfigTitle: _('基础模型', 'Base model', '基礎模型'),
|
||||
hermesModelConfigDesc: _('配置 Hermes 默认使用的模型、provider 和兼容接口地址。API Key 仍在安装向导或环境变量中管理,这里不会展示密钥。', 'Configure the default model, provider, and compatible API base URL for Hermes. API keys still live in setup or environment variables and are not shown here.', '設定 Hermes 預設使用的模型、provider 和相容介面位址。API Key 仍在安裝精靈或環境變數中管理,這裡不會顯示金鑰。'),
|
||||
hermesModelConfigStatusReady: _('结构化表单', 'structured form', '結構化表單'),
|
||||
hermesModelConfigSave: _('保存基础模型', 'Save base model', '儲存基礎模型'),
|
||||
hermesModelConfigSaveSuccess: _('基础模型已保存,建议重启 Hermes Gateway 生效', 'Base model saved. Restart Hermes Gateway to take effect.', '基礎模型已儲存,建議重啟 Hermes Gateway 生效'),
|
||||
hermesModelConfigLoadFailed: _('加载基础模型失败', 'Load base model failed', '載入基礎模型失敗'),
|
||||
hermesModelConfigSaveFailed: _('保存基础模型失败', 'Save base model failed', '儲存基礎模型失敗'),
|
||||
hermesModelConfigDefault: _('默认模型', 'Default model', '預設模型'),
|
||||
hermesModelConfigProvider: _('Provider', 'Provider', 'Provider'),
|
||||
hermesModelConfigBaseUrl: _('兼容接口地址(可选)', 'Compatible API base URL (optional)', '相容介面位址(可選)'),
|
||||
hermesModelConfigFootnote: _('默认模型不能为空;provider 为空时建议填 auto。兼容接口地址留空会移除 model.base_url,并保留 model 下其它高级字段。', 'Default model is required; use auto when no provider is pinned. Leaving the base URL blank removes model.base_url while preserving other advanced model fields.', '預設模型不可為空;未固定 provider 時建議填 auto。相容介面位址留空會移除 model.base_url,並保留 model 下其他進階欄位。'),
|
||||
hermesModelAliasesConfigTitle: _('模型别名', 'Model aliases', '模型別名'),
|
||||
hermesModelAliasesConfigDesc: _('配置 /model 命令可用的短别名,把常用模型、provider 和自定义 base_url 固定下来,减少手输错误。', 'Configure short aliases for the /model command, pinning common models, providers, and custom base_url values to reduce manual input errors.', '設定 /model 命令可用的短別名,把常用模型、provider 和自訂 base_url 固定下來,減少手動輸入錯誤。'),
|
||||
hermesModelAliasesConfigStatusReady: _('结构化 JSON', 'structured JSON', '結構化 JSON'),
|
||||
|
||||
Reference in New Issue
Block a user