story-kit: merge 199_story_web_ui_submits_all_queued_items_at_once

This commit is contained in:
Dave
2026-02-26 12:05:08 +00:00
parent 3c5b496432
commit 8d29956dea
3 changed files with 90 additions and 22 deletions

View File

@@ -192,8 +192,10 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
// Ref so stale WebSocket callbacks can read the current queued messages
const queuedMessagesRef = useRef<{ id: string; text: string }[]>([]);
const queueIdCounterRef = useRef(0);
// Trigger state: set to a message string to fire auto-send after loading ends
const [pendingAutoSend, setPendingAutoSend] = useState<string | null>(null);
// Trigger state: set to a batch of message strings to fire auto-send after loading ends
const [pendingAutoSendBatch, setPendingAutoSendBatch] = useState<
string[] | null
>(null);
const wsRef = useRef<ChatWebSocket | null>(null);
const messagesEndRef = useRef<HTMLDivElement>(null);
@@ -294,10 +296,11 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
if (last?.role === "assistant" && !last.tool_calls) {
setLoading(false);
setActivityStatus(null);
const nextQueued = queuedMessagesRef.current.shift();
if (nextQueued !== undefined) {
setQueuedMessages([...queuedMessagesRef.current]);
setPendingAutoSend(nextQueued.text);
if (queuedMessagesRef.current.length > 0) {
const batch = queuedMessagesRef.current.map((item) => item.text);
queuedMessagesRef.current = [];
setQueuedMessages([]);
setPendingAutoSendBatch(batch);
}
}
},
@@ -308,10 +311,11 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
console.error("WebSocket error:", message);
setLoading(false);
setActivityStatus(null);
const nextQueued = queuedMessagesRef.current.shift();
if (nextQueued !== undefined) {
setQueuedMessages([...queuedMessagesRef.current]);
setPendingAutoSend(nextQueued.text);
if (queuedMessagesRef.current.length > 0) {
const batch = queuedMessagesRef.current.map((item) => item.text);
queuedMessagesRef.current = [];
setQueuedMessages([]);
setPendingAutoSendBatch(batch);
}
},
onPipelineState: (state) => {
@@ -395,14 +399,14 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
}
}, [autoScrollKey, scrollToBottom]);
// Auto-send queued message when loading ends
// Auto-send all queued messages as a batch when loading ends
useEffect(() => {
if (pendingAutoSend) {
const msg = pendingAutoSend;
setPendingAutoSend(null);
sendMessage(msg);
if (pendingAutoSendBatch && pendingAutoSendBatch.length > 0) {
const batch = pendingAutoSendBatch;
setPendingAutoSendBatch(null);
sendMessageBatch(batch);
}
}, [pendingAutoSend]);
}, [pendingAutoSendBatch]);
useEffect(() => {
const handleResize = () =>
@@ -498,6 +502,51 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
}
};
const sendMessageBatch = async (messageTexts: string[]) => {
if (messageTexts.length === 0) return;
const userMsgs: Message[] = messageTexts.map((text) => ({
role: "user",
content: text,
}));
const newHistory = [...messages, ...userMsgs];
setMessages(newHistory);
setLoading(true);
setStreamingContent("");
setStreamingThinking("");
setActivityStatus(null);
try {
const isClaudeCode = model === "claude-code-pty";
const provider = isClaudeCode
? "claude-code"
: model.startsWith("claude-")
? "anthropic"
: "ollama";
const config: ProviderConfig = {
provider,
model,
base_url: "http://localhost:11434",
enable_tools: enableTools,
...(isClaudeCode && claudeSessionId
? { session_id: claudeSessionId }
: {}),
};
wsRef.current?.sendChat(newHistory, config);
} catch (e) {
console.error("Chat error:", e);
const errorMessage = String(e);
if (!errorMessage.includes("Chat cancelled by user")) {
setMessages((prev: Message[]) => [
...prev,
{ role: "assistant", content: `**Error:** ${e}` },
]);
}
setLoading(false);
}
};
const handleSaveApiKey = async () => {
if (!apiKeyInput.trim()) return;