mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 08:02:21 +00:00
fix(native-chat): a chat whose draft holds text is never reused or claimed as empty
The empty-chat check read the pane's old draft key, while the composer and every hand-back write the conversation's. A chat with typed or given-back text read as empty, so a bare new chat reused it and a text request claimed it. It reads the conversation's draft now.
This commit is contained in:
@@ -113,10 +113,8 @@ import {
|
||||
clearNativeChatDraftCacheForTests,
|
||||
writeNativeChatDraftCache
|
||||
} from '@/components/native-chat/native-chat-draft-cache'
|
||||
import {
|
||||
structuredAgentSessionPaneKey,
|
||||
structuredAgentSessionTabId
|
||||
} from '../../../shared/structured-agent-session-projection'
|
||||
import { structuredAgentSessionTabId } from '../../../shared/structured-agent-session-projection'
|
||||
import { structuredAgentSessionDraftScopeKey } from '@/components/native-chat/native-chat-composer-draft-store'
|
||||
import { adoptAgentSessionLaunchVerdict } from './agent-session-launch-plan'
|
||||
import {
|
||||
beginStructuredAgentSessionProvisionalLaunch,
|
||||
@@ -279,8 +277,8 @@ describe('a second "new chat" with no text', () => {
|
||||
it('opens a new chat when the idle chat has a typed draft', async () => {
|
||||
pick('plus-pick-1')
|
||||
await publishIdle(first.sessionId)
|
||||
const tabId = structuredAgentSessionTabId(first.sessionId)
|
||||
writeNativeChatDraftCache(structuredAgentSessionPaneKey(tabId, first.sessionId), 'half a q')
|
||||
// Under the conversation's key, which the composer and every hand-back write.
|
||||
writeNativeChatDraftCache(structuredAgentSessionDraftScopeKey(first.sessionId), 'half a q')
|
||||
|
||||
expect(pick('plus-pick-2').sessionId).toBe(second.sessionId)
|
||||
})
|
||||
@@ -288,8 +286,7 @@ describe('a second "new chat" with no text', () => {
|
||||
it('opens a new chat when the idle chat has an image in its composer', async () => {
|
||||
pick('plus-pick-1')
|
||||
await publishIdle(first.sessionId)
|
||||
const tabId = structuredAgentSessionTabId(first.sessionId)
|
||||
appendNativeChatAttachmentCache(structuredAgentSessionPaneKey(tabId, first.sessionId), [
|
||||
appendNativeChatAttachmentCache(structuredAgentSessionDraftScopeKey(first.sessionId), [
|
||||
{ id: 'shot', path: '/tmp/shot.png' }
|
||||
])
|
||||
|
||||
@@ -484,6 +481,15 @@ describe('a "new chat" with text', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('leaves a starting chat whose draft holds text, given back or typed, to its user', () => {
|
||||
mocks.launch.mockImplementation(() => new Promise(() => undefined))
|
||||
const blank = pick('plus-pick-1')
|
||||
writeNativeChatDraftCache(structuredAgentSessionDraftScopeKey(blank.sessionId), 'my words')
|
||||
|
||||
expect(pick('notes-send', { prompt: 'review notes' }).sessionId).toBe(second.sessionId)
|
||||
expect(readOutbox(blank.sessionId)).toEqual([])
|
||||
})
|
||||
|
||||
it('takes an empty chat still starting, as before', () => {
|
||||
mocks.launch.mockImplementation(() => new Promise(() => undefined))
|
||||
const blank = pick('plus-pick-1')
|
||||
|
||||
@@ -67,10 +67,7 @@ import {
|
||||
readNativeChatDraftCache,
|
||||
writeNativeChatDraftCache
|
||||
} from '@/components/native-chat/native-chat-draft-cache'
|
||||
import {
|
||||
structuredAgentSessionPaneKey,
|
||||
structuredAgentSessionTabId
|
||||
} from '../../../shared/structured-agent-session-projection'
|
||||
import { structuredAgentSessionDraftScopeKey } from '@/components/native-chat/native-chat-composer-draft-store'
|
||||
import { StructuredAgentSessionCreateRefusalError } from '@/lib/launch-structured-agent-session'
|
||||
import {
|
||||
getStructuredAgentSessionLaunchLifecycle,
|
||||
@@ -520,10 +517,8 @@ describe('an empty chat still starting', () => {
|
||||
|
||||
it('leaves a chat its user is typing into to them, and opens a new chat for the notes', async () => {
|
||||
const blank = startStructuredAgentLaunch(WORKTREE_ID, 'codex', { requestId: 'plus-pick' })
|
||||
const paneKey = structuredAgentSessionPaneKey(
|
||||
structuredAgentSessionTabId(blank.sessionId),
|
||||
blank.sessionId
|
||||
)
|
||||
// The conversation's draft, which its composer writes.
|
||||
const paneKey = structuredAgentSessionDraftScopeKey(blank.sessionId)
|
||||
writeNativeChatDraftCache(paneKey, 'half a question')
|
||||
|
||||
const notes = startStructuredAgentLaunch(WORKTREE_ID, 'codex', notesSend)
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import {
|
||||
structuredAgentSessionPaneKey,
|
||||
structuredAgentSessionTabId
|
||||
} from '../../../shared/structured-agent-session-projection'
|
||||
import { getStructuredAgentSessionOutbox } from '@/components/native-chat/structured-agent-session-outbox-storage'
|
||||
import { readNativeChatDraftCache } from '@/components/native-chat/native-chat-draft-cache'
|
||||
// The draft store, not the composer hook: the launch must not load the composer (a store cycle).
|
||||
import { readNativeChatComposerDraft } from '@/components/native-chat/native-chat-composer-draft-store'
|
||||
import {
|
||||
readNativeChatComposerDraft,
|
||||
structuredAgentSessionDraftScopeKey
|
||||
} from '@/components/native-chat/native-chat-composer-draft-store'
|
||||
|
||||
/** A starting chat is empty until its user sends into it or puts text or images in its composer;
|
||||
* after that it is theirs, and another request never goes into it. */
|
||||
/** A starting chat is empty until its user sends into it or puts text or images in its draft (typed,
|
||||
* or given back); after that it is theirs, and another request never goes into it. Read by the
|
||||
* conversation's key, which the composer and every hand-back write. */
|
||||
export function isStructuredLaunchChatEmpty(sessionId: string): boolean {
|
||||
const paneKey = structuredAgentSessionPaneKey(structuredAgentSessionTabId(sessionId), sessionId)
|
||||
const scopeKey = structuredAgentSessionDraftScopeKey(sessionId)
|
||||
return (
|
||||
getStructuredAgentSessionOutbox(sessionId).length === 0 &&
|
||||
readNativeChatDraftCache(paneKey).trim() === '' &&
|
||||
readNativeChatComposerDraft(paneKey).images.length === 0
|
||||
readNativeChatDraftCache(scopeKey).trim() === '' &&
|
||||
readNativeChatComposerDraft(scopeKey).images.length === 0
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user