mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 20:50:34 +00:00
feat(arena): improve cancellation handling and simplify to in-process mode
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> - Track user-initiated cancellation separately from failures - Cancel round immediately when user denies a tool call - Add message queue to handle input during streaming - Add info messages during Arena operations (apply, stop, cleanup) - Disable tmux/iTerm2 backends (only in-process mode supported) - Polish UI: green tool count, updated warning prefix This improves the Arena UX by providing clearer feedback and properly handling user cancellations without treating them as failures.
This commit is contained in:
parent
3233d16b5c
commit
4ee94715df
13 changed files with 153 additions and 65 deletions
|
|
@ -18,9 +18,10 @@
|
|||
*/
|
||||
|
||||
import { Box, Text, useStdin } from 'ink';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
AgentStatus,
|
||||
isTerminalStatus,
|
||||
ApprovalMode,
|
||||
APPROVAL_MODES,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
|
|
@ -38,6 +39,7 @@ import { useTextBuffer } from '../shared/text-buffer.js';
|
|||
import { calculatePromptWidths } from '../../utils/layoutUtils.js';
|
||||
import { BaseTextInput } from '../BaseTextInput.js';
|
||||
import { LoadingIndicator } from '../LoadingIndicator.js';
|
||||
import { QueuedMessageDisplay } from '../QueuedMessageDisplay.js';
|
||||
import { AgentFooter } from './AgentFooter.js';
|
||||
import { keyMatchers, Command } from '../../keyMatchers.js';
|
||||
import { theme } from '../../semantic-colors.js';
|
||||
|
|
@ -182,13 +184,35 @@ export const AgentComposer: React.FC<AgentComposerProps> = ({ agentId }) => {
|
|||
[buffer, agentTabBarFocused, setAgentTabBarFocused],
|
||||
);
|
||||
|
||||
// ── Message queue (accumulate while streaming, flush as one prompt on idle) ──
|
||||
|
||||
const [messageQueue, setMessageQueue] = useState<string[]>([]);
|
||||
|
||||
// When agent becomes idle (and not terminal), flush queued messages.
|
||||
useEffect(() => {
|
||||
if (
|
||||
streamingState === StreamingState.Idle &&
|
||||
messageQueue.length > 0 &&
|
||||
status !== undefined &&
|
||||
!isTerminalStatus(status)
|
||||
) {
|
||||
const combined = messageQueue.join('\n');
|
||||
setMessageQueue([]);
|
||||
interactiveAgent?.enqueueMessage(combined);
|
||||
}
|
||||
}, [streamingState, messageQueue, interactiveAgent, status]);
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(text: string) => {
|
||||
const trimmed = text.trim();
|
||||
if (!trimmed || !interactiveAgent) return;
|
||||
interactiveAgent.enqueueMessage(trimmed);
|
||||
if (streamingState === StreamingState.Idle) {
|
||||
interactiveAgent.enqueueMessage(trimmed);
|
||||
} else {
|
||||
setMessageQueue((prev) => [...prev, trimmed]);
|
||||
}
|
||||
},
|
||||
[interactiveAgent],
|
||||
[interactiveAgent, streamingState],
|
||||
);
|
||||
|
||||
// ── Render ──
|
||||
|
|
@ -255,6 +279,8 @@ export const AgentComposer: React.FC<AgentComposerProps> = ({ agentId }) => {
|
|||
</Box>
|
||||
)}
|
||||
|
||||
<QueuedMessageDisplay messageQueue={messageQueue} />
|
||||
|
||||
{/* Input prompt — always visible, like the main Composer */}
|
||||
<BaseTextInput
|
||||
buffer={buffer}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue