refactor(cli): make /btw non-blocking with fire-and-forget API call

Run the /btw API call as fire-and-forget in interactive mode so the
main conversation is not blocked while waiting for the answer. The
action now returns immediately after setting the pending item, and
the background promise updates the UI when the answer arrives.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Shaojin Wen 2026-03-14 17:41:09 +08:00
parent b1b5f72507
commit 1b651d5c4f
2 changed files with 60 additions and 29 deletions

View file

@ -175,36 +175,35 @@ export const btwCommand: SlashCommand = {
};
ui.setPendingItem(pendingItem);
try {
const answer = await askBtw(geminiClient, model, question, abortSignal);
// Fire-and-forget: run the API call in the background so the main
// conversation is not blocked while waiting for the btw answer.
void askBtw(geminiClient, model, question, abortSignal)
.then((answer) => {
if (abortSignal.aborted) return;
if (abortSignal.aborted) {
return;
}
const completedItem: HistoryItemBtw = {
type: MessageType.BTW,
btw: {
question,
answer,
isPending: false,
},
};
ui.addItem(completedItem, Date.now());
})
.catch((error) => {
if (abortSignal.aborted) return;
const completedItem: HistoryItemBtw = {
type: MessageType.BTW,
btw: {
question,
answer,
isPending: false,
},
};
ui.addItem(completedItem, Date.now());
} catch (error) {
if (abortSignal.aborted) {
return;
}
ui.addItem(
{
type: MessageType.ERROR,
text: formatBtwError(error),
},
Date.now(),
);
} finally {
ui.setPendingItem(null);
}
ui.addItem(
{
type: MessageType.ERROR,
text: formatBtwError(error),
},
Date.now(),
);
})
.finally(() => {
ui.setPendingItem(null);
});
},
};