fix(bot-mode): persist canonical chat before opening
This commit is contained in:
@@ -4149,6 +4149,24 @@ function createCanonicalChat(name) {
|
||||
const sid = res?.stored_session_id
|
||||
const runtime = res?.session_id
|
||||
|
||||
// session.create is intentionally lazy: its stored row does not exist until
|
||||
// the first prompt. Mounting `sid` immediately therefore emits a noisy REST
|
||||
// 404 ("Session not found"), and the turn-start auto-titler can win the race
|
||||
// against the deferred `title: 'Bot Chat'` — under name-identity that is an
|
||||
// identity outage: until the row is titled, the registry has no "Bot Chat"
|
||||
// entry, so a second click during the intro turn mints a duplicate.
|
||||
// session.title materializes the row now and records a user-authority title
|
||||
// before either the open or kickoff, closing both the 404 race and the
|
||||
// untitled window. Older gateways may not support the eager write; retain
|
||||
// the kickoff-and-retry fallback below.
|
||||
if (runtime) {
|
||||
try {
|
||||
await host.request('session.title', { session_id: runtime, title: CANONICAL_CHAT_TITLE })
|
||||
} catch {
|
||||
/* compatibility fallback: prompt.submit will persist the lazy row */
|
||||
}
|
||||
}
|
||||
|
||||
// Mount the session view FIRST, then send the kickoff — submitting into
|
||||
// an unmounted session left the intro reply invisible until reopen.
|
||||
let opened = false
|
||||
|
||||
@@ -22,7 +22,31 @@ function loadCanonicalCreation({ openSession, request }) {
|
||||
return { ...context.__canonical }
|
||||
}
|
||||
|
||||
test('regression: navigation retries after the kickoff persists a new canonical chat', async () => {
|
||||
test('regression: creation materializes and titles the lazy row before opening it', async () => {
|
||||
const events = []
|
||||
const runtime = loadCanonicalCreation({
|
||||
openSession: async id => events.push(`open:${id}`),
|
||||
request: async (method, params) => {
|
||||
events.push(method)
|
||||
if (method === 'session.create') return { stored_session_id: 'stored-1', session_id: 'runtime-1' }
|
||||
if (method === 'session.title') {
|
||||
assert.deepEqual(params, { session_id: 'runtime-1', title: 'Bot Chat' })
|
||||
}
|
||||
return {}
|
||||
}
|
||||
})
|
||||
|
||||
assert.equal(await runtime.createCanonicalChat('ops'), 'stored-1')
|
||||
assert.deepEqual(events, [
|
||||
'session.list',
|
||||
'session.create',
|
||||
'session.title',
|
||||
'open:stored-1',
|
||||
'prompt.submit'
|
||||
])
|
||||
})
|
||||
|
||||
test('compatibility: navigation retries after kickoff when eager title persistence is unavailable', async () => {
|
||||
const events = []
|
||||
let attempts = 0
|
||||
const runtime = loadCanonicalCreation({
|
||||
@@ -33,6 +57,7 @@ test('regression: navigation retries after the kickoff persists a new canonical
|
||||
},
|
||||
request: async method => {
|
||||
if (method === 'session.create') return { stored_session_id: 'stored-1', session_id: 'runtime-1' }
|
||||
if (method === 'session.title') throw new Error('unknown method')
|
||||
if (method === 'prompt.submit') events.push('kickoff:persisted')
|
||||
return {}
|
||||
}
|
||||
|
||||
1
contributors/emails/switchstatement@gmail.com
Normal file
1
contributors/emails/switchstatement@gmail.com
Normal file
@@ -0,0 +1 @@
|
||||
krunkosaurus
|
||||
Reference in New Issue
Block a user