mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-10 13:31:38 +00:00
Both Desktop picker surfaces (status-bar model menu, settings/onboarding dialog) only asked the connected gateway's model.options once a session existed; before that they fell back to the Desktop REST/global options, which can't see virtual providers a remote gateway exposes — including the MoA presets from #53817. Centralize the fetch rule in requestModelOptions(): prefer the connected gateway whenever one exists (no session_id needed — the RPC resolves disk config), REST only when no gateway is connected. The status-bar MoA preset section now renders from the same model.options payload (the virtual `moa` provider row) instead of the local /api/model/moa REST config, so remote presets appear correctly; the row is filtered out of the main provider groups so presets don't list twice. Preset selection keeps the persistent switchTo path from #56417 and drops the vestigial session gate — like regular model rows, a pre-session pick ships on the next session.create. Fixes #53817. Rebased and reconciled with #56417 (persistent MoA selection), which landed after this PR was opened and covered its one-shot-/moa half.
49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { getGlobalModelOptions } from '@/hermes'
|
|
|
|
import { requestModelOptions } from './model-options'
|
|
|
|
const globalOptions = { model: 'hermes-4', provider: 'nous', providers: [] }
|
|
|
|
vi.mock('@/hermes', () => ({
|
|
getGlobalModelOptions: vi.fn(() => Promise.resolve(globalOptions))
|
|
}))
|
|
|
|
describe('requestModelOptions', () => {
|
|
afterEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('uses the connected gateway even before a session exists', async () => {
|
|
const gatewayPayload = { model: 'BeastMode', provider: 'moa', providers: [] }
|
|
|
|
const gateway = {
|
|
request: vi.fn(() => Promise.resolve(gatewayPayload))
|
|
}
|
|
|
|
await expect(requestModelOptions({ gateway: gateway as never, sessionId: null })).resolves.toBe(gatewayPayload)
|
|
|
|
expect(gateway.request).toHaveBeenCalledWith('model.options', {})
|
|
expect(getGlobalModelOptions).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('passes the active session id and refresh flag through the gateway', async () => {
|
|
const gateway = {
|
|
request: vi.fn(() => Promise.resolve(globalOptions))
|
|
}
|
|
|
|
await requestModelOptions({ gateway: gateway as never, refresh: true, sessionId: 'session-1' })
|
|
|
|
expect(gateway.request).toHaveBeenCalledWith('model.options', {
|
|
refresh: true,
|
|
session_id: 'session-1'
|
|
})
|
|
})
|
|
|
|
it('falls back to REST when no gateway is connected', async () => {
|
|
await requestModelOptions({ refresh: true })
|
|
|
|
expect(getGlobalModelOptions).toHaveBeenCalledWith({ refresh: true })
|
|
})
|
|
})
|