Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/types/src/followup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { z } from "zod"

/**
* Interface for follow-up data structure used in follow-up questions
* This represents the data structure for follow-up questions that the LLM can ask
* to gather more information needed to complete a task.
*/
export interface FollowUpData {
/** The question being asked by the LLM */
question?: string
/** Array of suggested answers that the user can select */
suggest?: Array<SuggestionItem>
}

/**
* Interface for a suggestion item with optional mode switching
*/
export interface SuggestionItem {
/** The text of the suggestion */
answer: string
/** Optional mode to switch to when selecting this suggestion */
mode?: string
}

/**
* Zod schema for SuggestionItem
*/
export const suggestionItemSchema = z.object({
answer: z.string(),
mode: z.string().optional(),
})

/**
* Zod schema for FollowUpData
*/
export const followUpDataSchema = z.object({
question: z.string().optional(),
suggest: z.array(suggestionItemSchema).optional(),
})

export type FollowUpDataType = z.infer<typeof followUpDataSchema>
4 changes: 4 additions & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const globalSettingsSchema = z.object({
alwaysAllowModeSwitch: z.boolean().optional(),
alwaysAllowSubtasks: z.boolean().optional(),
alwaysAllowExecute: z.boolean().optional(),
alwaysAllowFollowupQuestions: z.boolean().optional(),
followupAutoApproveTimeoutMs: z.number().optional(),
allowedCommands: z.array(z.string()).optional(),
allowedMaxRequests: z.number().nullish(),
autoCondenseContext: z.boolean().optional(),
Expand Down Expand Up @@ -189,6 +191,8 @@ export const EVALS_SETTINGS: RooCodeSettings = {
alwaysAllowModeSwitch: true,
alwaysAllowSubtasks: true,
alwaysAllowExecute: true,
alwaysAllowFollowupQuestions: true,
followupAutoApproveTimeoutMs: 0,
allowedCommands: ["*"],

browserToolEnabled: false,
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./api.js"
export * from "./codebase-index.js"
export * from "./cloud.js"
export * from "./experiment.js"
export * from "./followup.js"
export * from "./global-settings.js"
export * from "./history.js"
export * from "./ipc.js"
Expand Down
6 changes: 6 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,8 @@ export class ClineProvider
codebaseIndexConfig,
codebaseIndexModels,
profileThresholds,
alwaysAllowFollowupQuestions,
followupAutoApproveTimeoutMs,
} = await this.getState()

const telemetryKey = process.env.POSTHOG_API_KEY
Expand Down Expand Up @@ -1521,6 +1523,8 @@ export class ClineProvider
profileThresholds: profileThresholds ?? {},
cloudApiUrl: getRooCodeApiUrl(),
hasOpenedModeSelector: this.getGlobalState("hasOpenedModeSelector") ?? false,
alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions ?? false,
followupAutoApproveTimeoutMs: followupAutoApproveTimeoutMs ?? 60000,
}
}

Expand Down Expand Up @@ -1601,6 +1605,8 @@ export class ClineProvider
alwaysAllowMcp: stateValues.alwaysAllowMcp ?? false,
alwaysAllowModeSwitch: stateValues.alwaysAllowModeSwitch ?? false,
alwaysAllowSubtasks: stateValues.alwaysAllowSubtasks ?? false,
alwaysAllowFollowupQuestions: stateValues.alwaysAllowFollowupQuestions ?? false,
followupAutoApproveTimeoutMs: stateValues.followupAutoApproveTimeoutMs ?? 60000,
allowedMaxRequests: stateValues.allowedMaxRequests,
autoCondenseContext: stateValues.autoCondenseContext ?? true,
autoCondenseContextPercent: stateValues.autoCondenseContextPercent ?? 100,
Expand Down
8 changes: 8 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,14 @@ export const webviewMessageHandler = async (
await updateGlobalState("maxWorkspaceFiles", fileCount)
await provider.postStateToWebview()
break
case "alwaysAllowFollowupQuestions":
await updateGlobalState("alwaysAllowFollowupQuestions", message.bool ?? false)
await provider.postStateToWebview()
break
case "followupAutoApproveTimeoutMs":
await updateGlobalState("followupAutoApproveTimeoutMs", message.value)
await provider.postStateToWebview()
break
case "browserToolEnabled":
await updateGlobalState("browserToolEnabled", message.bool ?? true)
await provider.postStateToWebview()
Expand Down
2 changes: 2 additions & 0 deletions src/shared/WebviewMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface WebviewMessage {
| "alwaysAllowWriteOutsideWorkspace"
| "alwaysAllowWriteProtected"
| "alwaysAllowExecute"
| "alwaysAllowFollowupQuestions"
| "followupAutoApproveTimeoutMs"
| "webviewDidLaunch"
| "newTask"
| "askResponse"
Expand Down
8 changes: 8 additions & 0 deletions webview-ui/src/components/chat/AutoApproveMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
alwaysAllowModeSwitch,
alwaysAllowSubtasks,
alwaysApproveResubmit,
alwaysAllowFollowupQuestions,
allowedMaxRequests,
setAlwaysAllowReadOnly,
setAlwaysAllowWrite,
Expand All @@ -34,6 +35,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
setAlwaysAllowModeSwitch,
setAlwaysAllowSubtasks,
setAlwaysApproveResubmit,
setAlwaysAllowFollowupQuestions,
setAllowedMaxRequests,
} = useExtensionState()

Expand Down Expand Up @@ -68,6 +70,9 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
case "alwaysApproveResubmit":
setAlwaysApproveResubmit(value)
break
case "alwaysAllowFollowupQuestions":
setAlwaysAllowFollowupQuestions(value)
break
}
},
[
Expand All @@ -79,6 +84,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
setAlwaysAllowModeSwitch,
setAlwaysAllowSubtasks,
setAlwaysApproveResubmit,
setAlwaysAllowFollowupQuestions,
],
)

Expand All @@ -94,6 +100,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
alwaysAllowModeSwitch: alwaysAllowModeSwitch,
alwaysAllowSubtasks: alwaysAllowSubtasks,
alwaysApproveResubmit: alwaysApproveResubmit,
alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions,
}),
[
alwaysAllowReadOnly,
Expand All @@ -104,6 +111,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
alwaysAllowModeSwitch,
alwaysAllowSubtasks,
alwaysApproveResubmit,
alwaysAllowFollowupQuestions,
],
)

Expand Down
8 changes: 6 additions & 2 deletions webview-ui/src/components/chat/ChatRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { ClineMessage } from "@roo-code/types"
import { ClineApiReqInfo, ClineAskUseMcpServer, ClineSayTool } from "@roo/ExtensionMessage"
import { COMMAND_OUTPUT_STRING } from "@roo/combineCommandSequences"
import { safeJsonParse } from "@roo/safeJsonParse"
import { FollowUpData, SuggestionItem } from "@roo-code/types"

import { useCopyToClipboard } from "@src/utils/clipboard"
import { useExtensionState } from "@src/context/ExtensionStateContext"
Expand Down Expand Up @@ -48,8 +49,9 @@ interface ChatRowProps {
isStreaming: boolean
onToggleExpand: (ts: number) => void
onHeightChange: (isTaller: boolean) => void
onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void
onSuggestionClick?: (suggestion: SuggestionItem, event?: React.MouseEvent) => void
onBatchFileResponse?: (response: { [key: string]: boolean }) => void
onFollowUpUnmount?: () => void
}

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
Expand Down Expand Up @@ -98,6 +100,7 @@ export const ChatRowContent = ({
isStreaming,
onToggleExpand,
onSuggestionClick,
onFollowUpUnmount,
onBatchFileResponse,
}: ChatRowContentProps) => {
const { t } = useTranslation()
Expand Down Expand Up @@ -279,7 +282,7 @@ export const ChatRowContent = ({

const followUpData = useMemo(() => {
if (message.type === "ask" && message.ask === "followup" && !message.partial) {
return safeJsonParse<any>(message.text)
return safeJsonParse<FollowUpData>(message.text)
}
return null
}, [message.type, message.ask, message.partial, message.text])
Expand Down Expand Up @@ -1215,6 +1218,7 @@ export const ChatRowContent = ({
suggestions={followUpData?.suggest}
onSuggestionClick={onSuggestionClick}
ts={message?.ts}
onUnmount={onFollowUpUnmount}
/>
</>
)
Expand Down
Loading
Loading