feature: Ask User Question implementation for Claude Code & upgrade claude agent sdk to 0.1.71 to support the tool

This commit is contained in:
simosmik
2026-02-16 12:14:51 +00:00
parent 272eb00602
commit 42f13e151c
17 changed files with 851 additions and 90 deletions

View File

@@ -157,16 +157,23 @@ export default function ChatComposer({
bottom: textareaRect ? window.innerHeight - textareaRect.top + 8 : 90,
};
// Detect if the AskUserQuestion interactive panel is active
const hasQuestionPanel = pendingPermissionRequests.some(
(r) => r.toolName === 'AskUserQuestion'
);
return (
<div className="p-2 sm:p-4 md:p-4 flex-shrink-0 pb-2 sm:pb-4 md:pb-6">
<div className="flex-1">
<ClaudeStatus
status={claudeStatus}
isLoading={isLoading}
onAbort={onAbortSession}
provider={provider}
/>
</div>
{!hasQuestionPanel && (
<div className="flex-1">
<ClaudeStatus
status={claudeStatus}
isLoading={isLoading}
onAbort={onAbortSession}
provider={provider}
/>
</div>
)}
<div className="max-w-4xl mx-auto mb-3">
<PermissionRequestsBanner
@@ -175,7 +182,7 @@ export default function ChatComposer({
handleGrantToolPermission={handleGrantToolPermission}
/>
<ChatInputControls
{!hasQuestionPanel && <ChatInputControls
permissionMode={permissionMode}
onModeSwitch={onModeSwitch}
provider={provider}
@@ -189,10 +196,10 @@ export default function ChatComposer({
isUserScrolledUp={isUserScrolledUp}
hasMessages={hasMessages}
onScrollToBottom={onScrollToBottom}
/>
/>}
</div>
<form onSubmit={onSubmit as (event: FormEvent<HTMLFormElement>) => void} className="relative max-w-4xl mx-auto">
{!hasQuestionPanel && <form onSubmit={onSubmit as (event: FormEvent<HTMLFormElement>) => void} className="relative max-w-4xl mx-auto">
{isDragActive && (
<div className="absolute inset-0 bg-blue-500/20 border-2 border-dashed border-blue-500 rounded-lg flex items-center justify-center z-50">
<div className="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-lg">
@@ -340,7 +347,7 @@ export default function ChatComposer({
</div>
</div>
</div>
</form>
</form>}
</div>
);
}

View File

@@ -127,6 +127,14 @@ const MessageComponent = memo(({ message, index, prevMessage, createDiff, onFile
</div>
)}
</div>
) : message.isTaskNotification ? (
/* Compact task notification on the left */
<div className="w-full">
<div className="flex items-center gap-2 py-0.5">
<span className={`inline-block w-1.5 h-1.5 rounded-full flex-shrink-0 ${message.taskStatus === 'completed' ? 'bg-green-400 dark:bg-green-500' : 'bg-amber-400 dark:bg-amber-500'}`} />
<span className="text-xs text-gray-500 dark:text-gray-400">{message.content}</span>
</div>
</div>
) : (
/* Claude/Error/Tool messages on the left */
<div className="w-full">

View File

@@ -2,6 +2,10 @@ import React from 'react';
import type { PendingPermissionRequest } from '../../types/types';
import { buildClaudeToolPermissionEntry, formatToolInputForDisplay } from '../../utils/chatPermissions';
import { getClaudeSettings } from '../../utils/chatStorage';
import { getPermissionPanel, registerPermissionPanel } from '../../tools/configs/permissionPanelRegistry';
import { AskUserQuestionPanel } from '../../tools/components/InteractiveRenderers';
registerPermissionPanel('AskUserQuestion', AskUserQuestionPanel);
interface PermissionRequestsBannerProps {
pendingPermissionRequests: PendingPermissionRequest[];
@@ -24,6 +28,17 @@ export default function PermissionRequestsBanner({
return (
<div className="mb-3 space-y-2">
{pendingPermissionRequests.map((request) => {
const CustomPanel = getPermissionPanel(request.toolName);
if (CustomPanel) {
return (
<CustomPanel
key={request.requestId}
request={request}
onDecision={handlePermissionDecision}
/>
);
}
const rawInput = formatToolInputForDisplay(request.input);
const permissionEntry = buildClaudeToolPermissionEntry(request.toolName, rawInput);
const settings = getClaudeSettings();