mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-26 17:38:36 +00:00
Merge pull request #71891 from NousResearch/bb/slash-tab-target
fix(desktop): send a skill's kickoff into the tab that invoked it
This commit is contained in:
commit
080ee077a8
2 changed files with 60 additions and 1 deletions
|
|
@ -1167,6 +1167,56 @@ describe('usePromptActions slash.exec dispatch payloads', () => {
|
|||
$queuedPromptsBySession.set({})
|
||||
})
|
||||
|
||||
it("sends a skill's kickoff into the TAB that invoked it, not the foreground chat", async () => {
|
||||
// `/work` in a fresh ⌘T tab: slash.exec returns a skill dispatch whose
|
||||
// `message` is the kickoff prompt. The dispatcher resolved the tab as its
|
||||
// target, printed "⚡ loading skill" there — then submitted the kickoff
|
||||
// with no target at all, so submit re-resolved from activeSessionIdRef and
|
||||
// fired it as a user message into whatever conversation was on screen.
|
||||
const tabRuntimeId = 'tab-runtime'
|
||||
const tabStoredId = 'tab-stored'
|
||||
|
||||
$queuedPromptsBySession.set({})
|
||||
publishSessionState(tabRuntimeId, createClientSessionState(tabStoredId))
|
||||
|
||||
const submitted: (Record<string, unknown> | undefined)[] = []
|
||||
|
||||
const requestGateway = vi.fn(async (method: string, params?: Record<string, unknown>) => {
|
||||
if (method === 'prompt.submit') {
|
||||
submitted.push(params)
|
||||
}
|
||||
|
||||
return (
|
||||
method === 'slash.exec'
|
||||
? { type: 'skill', name: 'work', message: 'Load the work skill, then: fix the tab bug' }
|
||||
: {}
|
||||
) as never
|
||||
})
|
||||
|
||||
let handle: HarnessHandle | null = null
|
||||
await actRender(
|
||||
<Harness
|
||||
activeSessionId="foreground-runtime"
|
||||
onReady={h => (handle = h)}
|
||||
refreshSessions={async () => undefined}
|
||||
requestGateway={requestGateway}
|
||||
storedSessionId="foreground-stored"
|
||||
/>
|
||||
)
|
||||
|
||||
await handle!.submitText('/work fix the tab bug', { sessionId: tabRuntimeId })
|
||||
|
||||
expect(submitted).toEqual([
|
||||
expect.objectContaining({
|
||||
session_id: tabRuntimeId,
|
||||
text: 'Load the work skill, then: fix the tab bug'
|
||||
})
|
||||
])
|
||||
|
||||
dropSessionState(tabRuntimeId)
|
||||
$queuedPromptsBySession.set({})
|
||||
})
|
||||
|
||||
it('slash status header carries the command token, not the full invocation', async () => {
|
||||
// `/goal <long prose>` used to echo the entire invocation in the mono
|
||||
// header AND the goal text again in the backend notice right under it.
|
||||
|
|
|
|||
|
|
@ -285,7 +285,16 @@ export function useSlashCommand(deps: SlashCommandDeps) {
|
|||
return
|
||||
}
|
||||
|
||||
await submitPromptText(message)
|
||||
// Submit into the session this command was resolved against — the
|
||||
// same pair the output writer and the busy gate above already use.
|
||||
// Bare `submitPromptText(message)` let submit re-resolve from
|
||||
// `activeSessionIdRef`, which names the FOREGROUND chat: a `/work`
|
||||
// typed into a fresh ⌘T tab loaded the skill in that tab, printed
|
||||
// "⚡ loading skill" there, then fired its kickoff as a user message
|
||||
// into whatever conversation was on screen. Every other target the
|
||||
// dispatcher serves (tile, background queue drain, a session created
|
||||
// by this very call) had the same leak.
|
||||
await submitPromptText(message, { sessionId, storedSessionId })
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue