mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(desktop): reuse global remote backend across profiles
Keep non-primary profiles that inherit the app-global remote on the primary connection descriptor instead of creating processless pool entries that the idle reaper repeatedly removes. Preserve per-profile remote overrides and local pooled backends, and cover the routing policy with behavioral tests. Co-authored-by: Rodrigo Fernandez <rodrigo@nxtlevelsaas.com>
This commit is contained in:
parent
704a321870
commit
3884e0eea0
3 changed files with 83 additions and 6 deletions
|
|
@ -35,6 +35,7 @@ import {
|
|||
profileHasRemoteConnection,
|
||||
profileRemoteOverride,
|
||||
profileSshOverride,
|
||||
profileUsesPrimaryBackend,
|
||||
resolveAuthMode,
|
||||
resolveTestWsUrl,
|
||||
RT_COOKIE_VARIANTS,
|
||||
|
|
@ -187,6 +188,44 @@ test('saved SSH drafts are inactive and explicit overrides take precedence', ()
|
|||
assert.equal(profileHasRemoteConnection(config, 'coder'), true)
|
||||
})
|
||||
|
||||
// --- profileUsesPrimaryBackend ---
|
||||
|
||||
test('profileUsesPrimaryBackend keeps primary and empty scopes on the window backend', () => {
|
||||
assert.equal(profileUsesPrimaryBackend('default', { primaryProfile: 'default' }), true)
|
||||
assert.equal(profileUsesPrimaryBackend(' coder ', { primaryProfile: 'coder' }), true)
|
||||
assert.equal(profileUsesPrimaryBackend('', { primaryProfile: 'default' }), true)
|
||||
})
|
||||
|
||||
test('profileUsesPrimaryBackend shares one app-global remote across profiles', () => {
|
||||
assert.equal(
|
||||
profileUsesPrimaryBackend('coder', {
|
||||
primaryProfile: 'default',
|
||||
globalRemote: true,
|
||||
profileRemoteOverride: false
|
||||
}),
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
test('profileUsesPrimaryBackend preserves profile overrides and local profile backends', () => {
|
||||
assert.equal(
|
||||
profileUsesPrimaryBackend('coder', {
|
||||
primaryProfile: 'default',
|
||||
globalRemote: true,
|
||||
profileRemoteOverride: true
|
||||
}),
|
||||
false
|
||||
)
|
||||
assert.equal(
|
||||
profileUsesPrimaryBackend('coder', {
|
||||
primaryProfile: 'default',
|
||||
globalRemote: false,
|
||||
profileRemoteOverride: false
|
||||
}),
|
||||
false
|
||||
)
|
||||
})
|
||||
|
||||
// --- pathWithGlobalRemoteProfile ---
|
||||
|
||||
test('pathWithGlobalRemoteProfile appends profile in global remote mode', () => {
|
||||
|
|
|
|||
|
|
@ -350,6 +350,24 @@ function profileRemoteOverride(config, profile) {
|
|||
return { url, authMode: normAuthMode(entry.authMode), token: entry.token }
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide whether a profile should reuse the primary backend connection.
|
||||
*
|
||||
* The primary profile always owns the window backend. In app-global remote
|
||||
* mode, that same backend serves every profile through request-level profile
|
||||
* scoping, unless a profile has its own remote connection override.
|
||||
*/
|
||||
function profileUsesPrimaryBackend(profile, opts: any = {}) {
|
||||
const scopedProfile = connectionScopeKey(profile)
|
||||
const primaryProfile = connectionScopeKey(opts.primaryProfile) || 'default'
|
||||
|
||||
if (!scopedProfile || scopedProfile === primaryProfile) {
|
||||
return true
|
||||
}
|
||||
|
||||
return Boolean(opts.globalRemote) && !opts.profileRemoteOverride
|
||||
}
|
||||
|
||||
/**
|
||||
* In global-remote mode one backend serves every Desktop profile, so REST calls
|
||||
* that are scoped by renderer-side `request.profile` must carry that scope as a
|
||||
|
|
@ -505,6 +523,7 @@ export {
|
|||
profileHasRemoteConnection,
|
||||
profileRemoteOverride,
|
||||
profileSshOverride,
|
||||
profileUsesPrimaryBackend,
|
||||
resolveAuthMode,
|
||||
resolveTestWsUrl,
|
||||
RT_COOKIE_VARIANTS,
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import {
|
|||
profileHasRemoteConnection,
|
||||
profileRemoteOverride,
|
||||
profileSshOverride,
|
||||
profileUsesPrimaryBackend,
|
||||
resolveAuthMode,
|
||||
resolveTestWsUrl,
|
||||
savedProfileSsh,
|
||||
|
|
@ -7727,17 +7728,35 @@ function primaryProfileKey() {
|
|||
return readActiveDesktopProfile() || 'default'
|
||||
}
|
||||
|
||||
// Resolve a backend connection for the given profile. Routes the primary
|
||||
// profile to startHermes() (the window backend: boot UI, bootstrap, remote
|
||||
// mode), and any OTHER profile to a lazily-spawned pool backend. An empty /
|
||||
// unknown profile resolves to the primary, so all legacy callers are unchanged.
|
||||
// Resolve a backend connection for the given profile. The primary profile uses
|
||||
// startHermes() (the window backend: boot UI, bootstrap, remote mode). Profiles
|
||||
// inheriting an app-global remote share that same connection because the remote
|
||||
// backend scopes their requests by profile. Other profiles use lazily-spawned
|
||||
// pool backends. An empty / unknown profile resolves to the primary.
|
||||
async function ensureBackend(profile) {
|
||||
const key = profile && String(profile).trim() ? String(profile).trim() : primaryProfileKey()
|
||||
const primaryProfile = primaryProfileKey()
|
||||
const key = profile && String(profile).trim() ? String(profile).trim() : primaryProfile
|
||||
|
||||
if (key === primaryProfileKey()) {
|
||||
if (key === primaryProfile) {
|
||||
return startHermes()
|
||||
}
|
||||
|
||||
if (
|
||||
globalRemoteActive() &&
|
||||
profileUsesPrimaryBackend(key, {
|
||||
primaryProfile,
|
||||
globalRemote: true,
|
||||
profileRemoteOverride: profileHasRemoteOverride(key)
|
||||
})
|
||||
) {
|
||||
const connection = await startHermes()
|
||||
|
||||
// Non-primary global-remote profiles still need their scope on the
|
||||
// descriptor so renderer-side WebSocket, filesystem, and cache routing use
|
||||
// the selected profile while sharing the one underlying backend.
|
||||
return { ...connection, profile: key }
|
||||
}
|
||||
|
||||
const existing = backendPool.get(key)
|
||||
|
||||
if (existing) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue