mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-07-18 22:42:54 +00:00
fix: title web slash command sessions (#1599)
* fix web slash command session titles * docs update slash command title pr fragment --------- Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
date: 2026-06-16
|
||||
pr: 1599
|
||||
feature: Web slash command session titles
|
||||
impact: New Web UI slash-command sessions now use the command text for their initial title instead of the generic Bridge command title.
|
||||
---
|
||||
@@ -88,7 +88,7 @@ export async function handleSessionCommand(
|
||||
): Promise<void> {
|
||||
const state = getOrCreateSession(ctx.sessionMap, sessionId)
|
||||
ctx.socket.join(`session:${sessionId}`)
|
||||
ensureCommandSession(sessionId, ctx)
|
||||
ensureCommandSession(sessionId, command, ctx)
|
||||
const isKnownCommand = Boolean(COMMAND_ALIASES[command.rawName])
|
||||
if (command.name !== 'plan' && command.name !== 'skill' && isKnownCommand) {
|
||||
persistCommandMessage(sessionId, state, `/${command.rawName}${command.args ? ` ${command.args}` : ''}`)
|
||||
@@ -827,17 +827,23 @@ function formatReloadSkillItem(item: unknown): string {
|
||||
return description ? `${name}: ${description}` : name
|
||||
}
|
||||
|
||||
function ensureCommandSession(sessionId: string, ctx: SessionCommandContext) {
|
||||
function ensureCommandSession(sessionId: string, command: ParsedSessionCommand, ctx: SessionCommandContext) {
|
||||
if (getSession(sessionId)) return
|
||||
createSession({
|
||||
id: sessionId,
|
||||
profile: ctx.profile,
|
||||
source: 'cli',
|
||||
model: ctx.model,
|
||||
title: 'Bridge command',
|
||||
title: buildCommandSessionTitle(command),
|
||||
})
|
||||
}
|
||||
|
||||
function buildCommandSessionTitle(command: ParsedSessionCommand): string {
|
||||
const prefix = `[${command.rawName}]`
|
||||
const args = command.args.replace(/\s+/g, ' ').trim()
|
||||
return args ? `${prefix} ${args}`.slice(0, 120) : prefix
|
||||
}
|
||||
|
||||
function persistCommandMessage(sessionId: string, state: SessionState, content: string) {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const id = addMessage({
|
||||
|
||||
@@ -122,6 +122,36 @@ describe('plan session command', () => {
|
||||
expect(namespaceEmit).not.toHaveBeenCalledWith('session.command', expect.anything())
|
||||
})
|
||||
|
||||
it('creates a new slash-command session with a command-derived title', async () => {
|
||||
getSessionMock.mockReturnValueOnce(null)
|
||||
const state = { messages: [], isWorking: false, events: [], queue: [] }
|
||||
const { bridge, nsp, runQueuedItem, sessionMap, socket } = makeContext(state, {
|
||||
handled: true,
|
||||
type: 'goal',
|
||||
action: 'set',
|
||||
message: 'Goal set.',
|
||||
kickoff_prompt: 'build a todo app',
|
||||
})
|
||||
const { handleSessionCommand, parseSessionCommand } = await import('../../packages/server/src/services/hermes/run-chat/session-command')
|
||||
const command = parseSessionCommand('/goal build a todo app')!
|
||||
|
||||
await handleSessionCommand('session-1', command, {
|
||||
nsp: nsp as any,
|
||||
socket: socket as any,
|
||||
sessionMap,
|
||||
bridge: bridge as any,
|
||||
profile: 'default',
|
||||
runQueuedItem,
|
||||
})
|
||||
|
||||
expect(createSessionMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
id: 'session-1',
|
||||
profile: 'default',
|
||||
source: 'cli',
|
||||
title: '[goal] build a todo app',
|
||||
}))
|
||||
})
|
||||
|
||||
it('starts an idle /skill command with expanded storage and visible command display', async () => {
|
||||
const state = { messages: [], isWorking: false, events: [], queue: [] }
|
||||
const { bridge, namespaceEmit, nsp, runQueuedItem, sessionMap, socket } = makeContext(state, {
|
||||
|
||||
Reference in New Issue
Block a user