fmt(js): npm run fix on merge (#95365)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
25d46c7887
commit
1a19c52dd2
@@ -726,6 +726,7 @@ test('roster: unique profiles keep bare handles; duplicates get @name-device', (
|
||||
test('roster: source profile metadata follows the connection-qualified row', () => {
|
||||
const local = { id: 'local', kind: 'local' as const, label: 'This device' }
|
||||
const vps = { id: 'vps', kind: 'remote' as const, label: 'VPS', url: 'http://vps:8642' }
|
||||
|
||||
const vpsMeta = {
|
||||
display_name: 'Emma',
|
||||
ui_meta: { 'hermes-bots': { title: 'Emma', shape: 'blobatar::sun', color: '#8b5cf6' } },
|
||||
|
||||
@@ -9542,9 +9542,7 @@ async function teardownSshConnection(profile) {
|
||||
// connectWindowsRemote does not share POSIX lock/kill. Stay
|
||||
// silent on the kill path, but leave a log so quit is not a
|
||||
// mysterious no-op on Windows remotes.
|
||||
sshRememberLog(
|
||||
'[ssh] skip remote serve teardown on Windows remotes; POSIX disconnect does not apply'
|
||||
)
|
||||
sshRememberLog('[ssh] skip remote serve teardown on Windows remotes; POSIX disconnect does not apply')
|
||||
}
|
||||
: remoteLifecycle.disconnect
|
||||
}
|
||||
@@ -14099,11 +14097,7 @@ ipcMain.handle('hermes:connection-config:oauth-login', async (_event, rawUrl) =>
|
||||
|
||||
return { ok: true, baseUrl, connected: true }
|
||||
} catch (error) {
|
||||
rememberLog(
|
||||
`[native-oauth] native login failed (${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
})`
|
||||
)
|
||||
rememberLog(`[native-oauth] native login failed (${error instanceof Error ? error.message : String(error)})`)
|
||||
|
||||
return { ok: false, error: error instanceof Error ? error.message : String(error), connected: false }
|
||||
}
|
||||
|
||||
@@ -134,7 +134,6 @@ test('oauthGuardMayHardFail keeps the strict guard when the list is unusable', (
|
||||
assert.equal(oauthGuardMayHardFail([{ supportsPassword: true }]), true)
|
||||
})
|
||||
|
||||
|
||||
test('oauthGuardMayHardFail treats status-shaped string basic as password-only', () => {
|
||||
assert.equal(oauthGuardMayHardFail(['basic'] as any), false)
|
||||
assert.equal(oauthGuardMayHardFail([' basic '] as any), false)
|
||||
|
||||
@@ -168,6 +168,7 @@ export function normalizeAdvertisedAuthProviders(providers: unknown): Advertised
|
||||
}
|
||||
|
||||
out.push({ name, supportsPassword: PASSWORD_PROVIDER_NAMES.has(name) })
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -286,9 +286,9 @@ describe('localRouteFallbackProfiles', () => {
|
||||
})
|
||||
|
||||
it('synthesizes local routes for a genuine local enumeration error', () => {
|
||||
expect(
|
||||
localRouteFallbackProfiles([], 'local', ['default'], isLocalEnumerationFailure('ECONNREFUSED'))
|
||||
).toEqual(['default'])
|
||||
expect(localRouteFallbackProfiles([], 'local', ['default'], isLocalEnumerationFailure('ECONNREFUSED'))).toEqual([
|
||||
'default'
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -68,9 +68,7 @@ export class RemoteRevalidationCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
interface EnsureHealthyPooledRemoteBackendForDispatchOptions<
|
||||
TConnection extends RemoteConnectionDescriptor
|
||||
> {
|
||||
interface EnsureHealthyPooledRemoteBackendForDispatchOptions<TConnection extends RemoteConnectionDescriptor> {
|
||||
connectionPromise: Promise<TConnection>
|
||||
currentConnectionPromise: () => null | Promise<TConnection>
|
||||
probe: (connection: TConnection, path: string, options: { timeoutMs: number }) => Promise<unknown>
|
||||
@@ -86,9 +84,7 @@ interface EnsureHealthyPooledRemoteBackendForDispatchOptions<
|
||||
* caller. The caller should single-flight this function per cached promise so
|
||||
* concurrent dispatches share one retire/reconnect sequence.
|
||||
*/
|
||||
export async function ensureHealthyPooledRemoteBackendForDispatch<
|
||||
TConnection extends RemoteConnectionDescriptor
|
||||
>({
|
||||
export async function ensureHealthyPooledRemoteBackendForDispatch<TConnection extends RemoteConnectionDescriptor>({
|
||||
connectionPromise,
|
||||
currentConnectionPromise,
|
||||
probe,
|
||||
|
||||
@@ -98,6 +98,7 @@ export function listTileSessionRow(deps: {
|
||||
|
||||
const knownOwner =
|
||||
sessionTileOwnerRoute(deps.storedSessionId) ?? knownSessionOwner(deps.sessions, deps.storedSessionId)
|
||||
|
||||
const ownerRoute: SessionProfileRoute | undefined =
|
||||
knownOwner && typeof knownOwner === 'object' ? knownOwner : undefined
|
||||
|
||||
@@ -178,6 +179,7 @@ export function useSessionTileActions({ requestGateway, runtimeId, scope, stored
|
||||
<T>(method: string, params?: Record<string, unknown>, timeoutMs?: number, signal?: AbortSignal) => {
|
||||
const knownOwner: SessionOwnerScope =
|
||||
sessionTileOwnerRoute(storedIdRef.current) ?? knownSessionOwner($sessions.get(), storedIdRef.current)
|
||||
|
||||
// A bare profile is the legacy/unknown tile shape. Preserve its ambient
|
||||
// behavior; only a composite route is strong enough to retarget a tile
|
||||
// across same-named sources.
|
||||
|
||||
@@ -128,6 +128,7 @@ describe('resolvePinnedSessions', () => {
|
||||
row('foreign', { last_active: 1, pinned: true, profile: 'k9' }),
|
||||
row('local', { last_active: 50, pinned: true, profile: 'default' })
|
||||
]
|
||||
|
||||
const index = buildSessionByAnyId(sessions, [], [])
|
||||
|
||||
expect(resolvePinnedSessions(['foreign', 'local'], index, sessions, settled).map(s => s.id)).toEqual([
|
||||
|
||||
@@ -9,7 +9,13 @@ import {
|
||||
selectConnection,
|
||||
setConnectionsRegistry
|
||||
} from '@/store/connections'
|
||||
import { activeGateway, closeSecondaryGateways, ensureGatewayForAgent, isActivePrimary, requestGatewayForAgent } from '@/store/gateway'
|
||||
import {
|
||||
activeGateway,
|
||||
closeSecondaryGateways,
|
||||
ensureGatewayForAgent,
|
||||
isActivePrimary,
|
||||
requestGatewayForAgent
|
||||
} from '@/store/gateway'
|
||||
import { reconnectGateway } from '@/store/gateway-reconnect'
|
||||
import {
|
||||
$gatewaySwitching,
|
||||
|
||||
@@ -742,6 +742,7 @@ export function useGatewayBoot({
|
||||
|
||||
const offEvent = gateway.onEvent(event => {
|
||||
const connectionId = activeGatewayConnectionId()
|
||||
|
||||
const scopedEvent = {
|
||||
...event,
|
||||
profile: sourceProfile,
|
||||
|
||||
@@ -87,6 +87,7 @@ const remoteConnection = {
|
||||
|
||||
function installRemoteDesktop() {
|
||||
let mintCount = 0
|
||||
|
||||
const getConnection = vi.fn(async (profile?: null | string) => ({
|
||||
authMode: 'token' as const,
|
||||
baseUrl: 'http://127.0.0.1:5151',
|
||||
@@ -95,15 +96,18 @@ function installRemoteDesktop() {
|
||||
token: 'local-token',
|
||||
wsUrl: 'ws://127.0.0.1:5151/api/ws?token=local'
|
||||
}))
|
||||
|
||||
const getConnectionFor = vi.fn(async ({ connectionId, profile }: { connectionId: string; profile: string }) => ({
|
||||
...remoteConnection,
|
||||
connectionId,
|
||||
profile
|
||||
}))
|
||||
|
||||
const getGatewayWsUrl = vi.fn(async () => ({
|
||||
ok: true as const,
|
||||
wsUrl: 'ws://127.0.0.1:5151/api/ws?token=fresh-local'
|
||||
}))
|
||||
|
||||
const getGatewayWsUrlFor = vi.fn(
|
||||
async ({ connectionId, profile }: { connectionId: string; profile: string }): Promise<GatewayWsUrlResult> => {
|
||||
mintCount += 1
|
||||
@@ -132,6 +136,7 @@ function installPrimaryDesktop(authMode: 'oauth' | 'token') {
|
||||
token: 'primary-token',
|
||||
wsUrl: authMode === 'oauth' ? 'wss://gateway.example.test/api/ws?ticket=stale' : 'ws://127.0.0.1:5151/api/ws'
|
||||
}))
|
||||
|
||||
const getGatewayWsUrl = vi.fn(async (profile?: null | string) => ({
|
||||
ok: true as const,
|
||||
wsUrl:
|
||||
@@ -139,6 +144,7 @@ function installPrimaryDesktop(authMode: 'oauth' | 'token') {
|
||||
? `wss://gateway.example.test/api/ws?profile=${profile ?? 'default'}&ticket=fresh`
|
||||
: 'ws://127.0.0.1:5151/api/ws?token=fresh'
|
||||
}))
|
||||
|
||||
const getConnectionFor = vi.fn()
|
||||
const getGatewayWsUrlFor = vi.fn()
|
||||
|
||||
@@ -183,6 +189,7 @@ async function expectSecondaryRecoveryFailure(
|
||||
gateway.connectionState = 'closed'
|
||||
|
||||
vi.useFakeTimers()
|
||||
|
||||
const retry = request('session.resume').then(
|
||||
() => undefined,
|
||||
error => error
|
||||
|
||||
@@ -145,8 +145,7 @@ export function ModelCatalogMenu({
|
||||
// Gateway-first even with no session: a connected (possibly remote)
|
||||
// gateway owns the model catalog, including virtual providers the local
|
||||
// REST fallback can't know about (#53817).
|
||||
queryFn: (): Promise<ModelOptionsResponse> =>
|
||||
requestModelOptions({ gateway, profile, request, sessionId })
|
||||
queryFn: (): Promise<ModelOptionsResponse> => requestModelOptions({ gateway, profile, request, sessionId })
|
||||
})
|
||||
|
||||
const loading = modelOptions.isPending && !modelOptions.data
|
||||
|
||||
@@ -131,6 +131,7 @@ export function connectionScopedAtom<T>(
|
||||
options?: ConnectionScopeOptions
|
||||
): WritableAtom<T> {
|
||||
const includeProfile = options?.includeProfile !== false
|
||||
|
||||
const entry: ScopedEntry<T> = {
|
||||
$value: atom<T>(fallback),
|
||||
applying: false,
|
||||
@@ -140,6 +141,7 @@ export function connectionScopedAtom<T>(
|
||||
key,
|
||||
suffix: connectionScopeSuffix(activeConnection, includeProfile)
|
||||
}
|
||||
|
||||
entry.$value.set(loadEntry(entry))
|
||||
registry.push(entry)
|
||||
|
||||
|
||||
@@ -124,22 +124,25 @@ describe('requestModelOptions', () => {
|
||||
provider: 'nous',
|
||||
providers: [{ models: ['chrome-model'], name: 'Nous', slug: 'nous' }]
|
||||
}
|
||||
|
||||
const routedPayload = {
|
||||
model: 'berry-model',
|
||||
provider: 'openai',
|
||||
providers: [{ models: ['berry-model'], name: 'OpenAI', slug: 'openai' }]
|
||||
}
|
||||
|
||||
const gateway = {
|
||||
request: vi.fn(() => Promise.resolve(gatewayPayload))
|
||||
}
|
||||
|
||||
const request = vi.fn(() => Promise.resolve(routedPayload)) as unknown as <T>(
|
||||
method: string,
|
||||
params?: Record<string, unknown>
|
||||
) => Promise<T>
|
||||
|
||||
await expect(
|
||||
requestModelOptions({ gateway: gateway as never, request, sessionId: 'tile-1' })
|
||||
).resolves.toBe(routedPayload)
|
||||
await expect(requestModelOptions({ gateway: gateway as never, request, sessionId: 'tile-1' })).resolves.toBe(
|
||||
routedPayload
|
||||
)
|
||||
|
||||
expect(request).toHaveBeenCalledWith('model.options', { explicit_only: true, session_id: 'tile-1' })
|
||||
expect(gateway.request).not.toHaveBeenCalled()
|
||||
@@ -151,13 +154,12 @@ describe('requestModelOptions', () => {
|
||||
provider: 'hermes-local',
|
||||
providers: [{ models: ['berry-local'], name: 'Hermes Local', slug: 'hermes-local' }]
|
||||
}
|
||||
|
||||
const request = vi.fn(() => Promise.reject(new Error('gateway request unavailable')))
|
||||
|
||||
vi.mocked(getGlobalModelOptions).mockResolvedValueOnce(restPayload)
|
||||
|
||||
await expect(requestModelOptions({ profile: 'berry', request, sessionId: 'tile-1' })).resolves.toEqual(
|
||||
restPayload
|
||||
)
|
||||
await expect(requestModelOptions({ profile: 'berry', request, sessionId: 'tile-1' })).resolves.toEqual(restPayload)
|
||||
expect(getGlobalModelOptions).toHaveBeenCalledWith({ explicitOnly: true }, 'berry')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,14 +4,15 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const gatewayState = atom<'closed' | 'open'>('closed')
|
||||
|
||||
const listPersistedSessions = vi.fn(
|
||||
async (_route: unknown, options: { profile: string }) => ({
|
||||
sessions: [{ id: `${options.profile}-bot`, profile: options.profile, started_at: 1, title: 'Bot Chat' }]
|
||||
})
|
||||
)
|
||||
const listPersistedSessions = vi.fn(async (_route: unknown, options: { profile: string }) => ({
|
||||
sessions: [{ id: `${options.profile}-bot`, profile: options.profile, started_at: 1, title: 'Bot Chat' }]
|
||||
}))
|
||||
|
||||
const setPersistedSessionHidden = vi.fn(
|
||||
async (_route: unknown, _options: { hidden: boolean; profile: string; sessionId: string }) => ({ hidden: true, ok: true })
|
||||
async (_route: unknown, _options: { hidden: boolean; profile: string; sessionId: string }) => ({
|
||||
hidden: true,
|
||||
ok: true
|
||||
})
|
||||
)
|
||||
|
||||
const request = vi.fn(async (method: string) =>
|
||||
@@ -86,7 +87,9 @@ describe('Bot Mode hidden-session reconciliation lifecycle', () => {
|
||||
expect.objectContaining({ hidden: true, profile: 'beta', sessionId: 'beta-bot' })
|
||||
])
|
||||
)
|
||||
expect(request.mock.calls.some(([method]) => method === 'session.list' || method === 'session.set_hidden')).toBe(false)
|
||||
expect(request.mock.calls.some(([method]) => method === 'session.list' || method === 'session.set_hidden')).toBe(
|
||||
false
|
||||
)
|
||||
|
||||
disposers.forEach(dispose => dispose())
|
||||
const readsAtDispose = listPersistedSessions.mock.calls.length
|
||||
@@ -97,4 +100,4 @@ describe('Bot Mode hidden-session reconciliation lifecycle', () => {
|
||||
|
||||
expect(listPersistedSessions).toHaveBeenCalledTimes(readsAtDispose)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -50,6 +50,7 @@ const {
|
||||
setPrimaryGateway,
|
||||
setPrimaryGatewayConnectionId
|
||||
} = await import('./gateway')
|
||||
|
||||
const { setApiRequestConnection } = await import('@/hermes')
|
||||
|
||||
function installDesktop(): void {
|
||||
@@ -160,7 +161,7 @@ describe('pruneSecondaryGateways with registry-scoped entries', () => {
|
||||
expect(gatewayMocks.closed).toHaveLength(1)
|
||||
})
|
||||
|
||||
it("does not let a remote tile keep-set pin a local same-named secondary", async () => {
|
||||
it('does not let a remote tile keep-set pin a local same-named secondary', async () => {
|
||||
// Chrome is on another profile so 'default' is a real secondary, not the
|
||||
// spared active key. A homelab bot tile keep-set must keep only the
|
||||
// composite scope — the local 'default' socket still idles out.
|
||||
|
||||
@@ -37,13 +37,8 @@ vi.mock('@/store/session', () => ({
|
||||
}))
|
||||
vi.mock('@/store/notify-baseline', () => ({ markNativeNotifyBaseline: vi.fn() }))
|
||||
|
||||
const {
|
||||
$gateway,
|
||||
closeSecondaryGateways,
|
||||
configureGatewayRegistry,
|
||||
ensureGatewayForProfile,
|
||||
setPrimaryGateway
|
||||
} = await import('./gateway')
|
||||
const { $gateway, closeSecondaryGateways, configureGatewayRegistry, ensureGatewayForProfile, setPrimaryGateway } =
|
||||
await import('./gateway')
|
||||
|
||||
type DesktopStub = { getConnection: ReturnType<typeof vi.fn> }
|
||||
|
||||
|
||||
@@ -72,9 +72,7 @@ describe('foregroundSessionScopes', () => {
|
||||
}
|
||||
])
|
||||
|
||||
expect(foregroundSessionScopes()).toEqual(
|
||||
new Set(['conn:cloud-a::default', 'conn:cloud-b::default'])
|
||||
)
|
||||
expect(foregroundSessionScopes()).toEqual(new Set(['conn:cloud-a::default', 'conn:cloud-b::default']))
|
||||
})
|
||||
|
||||
it('releases an idle pane owner when the pane closes', () => {
|
||||
|
||||
Reference in New Issue
Block a user