mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 02:17:31 +00:00
Remove Fork Agent Session from the Chat UI menu (#38646)
* Remove whole-session fork action from chat menus * test: drop a terminal menu test this change can't fail
This commit is contained in:
+34
-1
@@ -45,12 +45,14 @@ function Chat({
|
||||
acceptsText = true,
|
||||
rewind,
|
||||
onFind,
|
||||
actions
|
||||
actions,
|
||||
standalone = false
|
||||
}: {
|
||||
acceptsText?: boolean
|
||||
rewind?: NativeChatRewindSurface
|
||||
onFind?: () => void
|
||||
actions?: Partial<NativeChatContextMenuActions>
|
||||
standalone?: boolean
|
||||
}): React.JSX.Element {
|
||||
const rootRef = useRef<HTMLDivElement>(null)
|
||||
const composerRef = useRef<NativeChatComposerHandle | null>({
|
||||
@@ -68,6 +70,20 @@ function Chat({
|
||||
composerRef,
|
||||
actions: { ...emptyNativeChatContextMenuActions, ...actions, onPaste: vi.fn() },
|
||||
showTerminalPaneActions: actions !== undefined,
|
||||
chatPane: standalone
|
||||
? { tabId: 'chat-tab', worktreeId: 'wt-1', groupId: 'group-1', sessionId: 'session-1' }
|
||||
: undefined,
|
||||
chatSession: standalone
|
||||
? {
|
||||
target: { kind: 'local' },
|
||||
sessionId: 'session-1',
|
||||
worktreeId: 'wt-1',
|
||||
epoch: 'epoch-1',
|
||||
agent: 'claude',
|
||||
messages: [],
|
||||
focusSource: vi.fn()
|
||||
}
|
||||
: undefined,
|
||||
fileLinkContext: linkContext,
|
||||
rewind,
|
||||
onFind
|
||||
@@ -108,6 +124,23 @@ afterEach(() => {
|
||||
vi.resetAllMocks()
|
||||
})
|
||||
|
||||
it.each(['terminal-backed', 'standalone'] as const)(
|
||||
'omits the whole-session fork action from the %s chat menu',
|
||||
async (surface) => {
|
||||
render(
|
||||
<Chat
|
||||
actions={surface === 'terminal-backed' ? {} : undefined}
|
||||
standalone={surface === 'standalone'}
|
||||
/>
|
||||
)
|
||||
|
||||
await rightClick('Empty area')
|
||||
|
||||
expect(screen.getByRole('menuitem', { name: 'Copy Context' })).toBeInTheDocument()
|
||||
expect(screen.queryByRole('menuitem', { name: 'Fork Agent Session…' })).not.toBeInTheDocument()
|
||||
}
|
||||
)
|
||||
|
||||
it.each([
|
||||
{
|
||||
firstText: 'docs link',
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from 'react'
|
||||
import { flushSync } from 'react-dom'
|
||||
import { chatMathSelectionText } from '../sidebar/chat-markdown-math-selection'
|
||||
import { Clipboard, Copy, GitFork, Image as ImageIcon, SquareTerminal } from 'lucide-react'
|
||||
import { Clipboard, Copy, Image as ImageIcon, SquareTerminal } from 'lucide-react'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -101,7 +101,6 @@ export type NativeChatContextMenuActions = {
|
||||
onToggleExpand: () => void
|
||||
canContinueAgentSessionInNewSession: boolean
|
||||
onContinueAgentSessionInNewSession: () => void
|
||||
onForkAgentSession: () => void
|
||||
onCopyAgentSessionContext: () => void
|
||||
onSetTitle: () => void
|
||||
canClearPaneTitle: boolean
|
||||
@@ -124,7 +123,6 @@ export const emptyNativeChatContextMenuActions: Omit<NativeChatContextMenuAction
|
||||
onToggleExpand: () => {},
|
||||
canContinueAgentSessionInNewSession: false,
|
||||
onContinueAgentSessionInNewSession: () => {},
|
||||
onForkAgentSession: () => {},
|
||||
onCopyAgentSessionContext: () => {},
|
||||
onSetTitle: () => {},
|
||||
canClearPaneTitle: false,
|
||||
@@ -337,13 +335,6 @@ export function useNativeChatContextMenu({
|
||||
onSelect={actions.onContinueAgentSessionInNewSession}
|
||||
/>
|
||||
) : null}
|
||||
<DropdownMenuItem onSelect={actions.onForkAgentSession}>
|
||||
<GitFork />
|
||||
{translate(
|
||||
'auto.components.terminal.pane.TerminalContextMenu.8a7ddb8b8a',
|
||||
'Fork Agent Session…'
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
<AgentSessionContextCopyMenuItem onSelect={actions.onCopyAgentSessionContext} />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
+3
-37
@@ -1,13 +1,8 @@
|
||||
import { useCallback, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { executionHostIdForStructuredTarget } from '@/runtime/structured-agent-session-owner'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { buildAgentSessionForkPrompt } from '@/lib/agent-session-fork-context'
|
||||
import { isTuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent-config'
|
||||
import type { AgentType } from '../../../../shared/agent-status/contracts/agent-status-types'
|
||||
import type { PreparedAgentSessionFork } from '../terminal-pane/terminal-agent-session-fork'
|
||||
import { copyAgentSessionContext } from '@/lib/copy-agent-session-context'
|
||||
import { TerminalAgentSessionForkDialog } from '../terminal-pane/TerminalAgentSessionForkDialog'
|
||||
import {
|
||||
resolveNativeChatSessionContext,
|
||||
type NativeChatSessionContextSource
|
||||
@@ -22,7 +17,6 @@ export type NativeChatSessionMenuSource = Omit<NativeChatSessionContextSource, '
|
||||
export function useNativeChatSessionContextActions(
|
||||
source: NativeChatSessionMenuSource | undefined
|
||||
) {
|
||||
const [fork, setFork] = useState<PreparedAgentSessionFork | null>(null)
|
||||
const [pending, setPending] = useState(false)
|
||||
const operation = useRef(0)
|
||||
const busy = useRef(false)
|
||||
@@ -34,11 +28,10 @@ export function useNativeChatSessionContextActions(
|
||||
retire()
|
||||
busy.current = false
|
||||
setPending(false)
|
||||
setFork(null)
|
||||
return retire
|
||||
}, [source?.sessionId, hostId, source?.epoch, source?.worktreeId, retire])
|
||||
|
||||
const prepare = async (action: 'fork' | 'copy'): Promise<void> => {
|
||||
const copy = async (): Promise<void> => {
|
||||
if (!source?.epoch || busy.current) {
|
||||
return
|
||||
}
|
||||
@@ -54,26 +47,7 @@ export function useNativeChatSessionContextActions(
|
||||
'components.native-chat.contextMenu.noSessionContext',
|
||||
'No chat context is available.'
|
||||
)
|
||||
if (action === 'copy') {
|
||||
await copyAgentSessionContext(context.capturedText, source.focusSource, noContext)
|
||||
return
|
||||
}
|
||||
const prompt = buildAgentSessionForkPrompt({
|
||||
capturedText: context.capturedText,
|
||||
sourceLabel: source.sessionId,
|
||||
agentLabel: source.agent
|
||||
})
|
||||
if (!prompt) {
|
||||
toast.error(noContext)
|
||||
source.focusSource()
|
||||
return
|
||||
}
|
||||
setFork({
|
||||
prompt,
|
||||
agent: isTuiAgent(source.agent) ? source.agent : null,
|
||||
worktreeId: source.worktreeId,
|
||||
focusSource: source.focusSource
|
||||
})
|
||||
await copyAgentSessionContext(context.capturedText, source.focusSource, noContext)
|
||||
} finally {
|
||||
if (operation.current === current) {
|
||||
busy.current = false
|
||||
@@ -84,14 +58,6 @@ export function useNativeChatSessionContextActions(
|
||||
return {
|
||||
available: Boolean(source?.epoch),
|
||||
pending,
|
||||
onFork: () => void prepare('fork'),
|
||||
onCopy: () => void prepare('copy'),
|
||||
dialog: fork ? (
|
||||
<TerminalAgentSessionForkDialog
|
||||
open={fork !== null}
|
||||
fork={fork}
|
||||
onOpenChange={(open) => !open && setFork(null)}
|
||||
/>
|
||||
) : null
|
||||
onCopy: () => void copy()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { GitFork } from 'lucide-react'
|
||||
import { DropdownMenuItem } from '@/components/ui/dropdown-menu'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { NativeChatCliForkMenuItems } from '../tab-bar/NativeChatCliForkMenuItems'
|
||||
import { AgentSessionContextCopyMenuItem } from '../terminal-pane/AgentSessionContextCopyMenuItem'
|
||||
import { useNativeChatQuickCommandsMenu } from './use-native-chat-quick-commands-menu'
|
||||
@@ -26,19 +23,7 @@ export function useNativeChatStandaloneMenu({
|
||||
pane && source ? (
|
||||
<>
|
||||
{context.available ? (
|
||||
<>
|
||||
<DropdownMenuItem disabled={context.pending} onSelect={context.onFork}>
|
||||
<GitFork />
|
||||
{translate(
|
||||
'auto.components.terminal.pane.TerminalContextMenu.8a7ddb8b8a',
|
||||
'Fork Agent Session…'
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
<AgentSessionContextCopyMenuItem
|
||||
disabled={context.pending}
|
||||
onSelect={context.onCopy}
|
||||
/>
|
||||
</>
|
||||
<AgentSessionContextCopyMenuItem disabled={context.pending} onSelect={context.onCopy} />
|
||||
) : null}
|
||||
<NativeChatCliForkMenuItems
|
||||
tab={{ id: pane.tabId, worktreeId: pane.worktreeId }}
|
||||
@@ -49,11 +34,6 @@ export function useNativeChatStandaloneMenu({
|
||||
/>
|
||||
</>
|
||||
) : null,
|
||||
dialogs: (
|
||||
<>
|
||||
{quickCommands.dialog}
|
||||
{context.dialog}
|
||||
</>
|
||||
)
|
||||
dialogs: quickCommands.dialog
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,6 @@ export function TerminalPaneNativeChatPortal({
|
||||
),
|
||||
onContinueAgentSessionInNewSession: () =>
|
||||
contextMenu.runForPane(chatPane.id, contextMenu.onContinueAgentSessionInNewSession),
|
||||
onForkAgentSession: () =>
|
||||
void contextMenu.runForPane(chatPane.id, contextMenu.onForkAgentSession),
|
||||
onCopyAgentSessionContext: () =>
|
||||
void contextMenu.runForPane(chatPane.id, contextMenu.onCopyAgentSessionContext),
|
||||
onSetTitle: () => contextMenu.runForPane(chatPane.id, contextMenu.onSetTitle),
|
||||
|
||||
Reference in New Issue
Block a user