Skip to content

Commit 434e7fa

Browse files
authored
Merge pull request #3378 from Kilo-Org/kevinvandijk/yolo-mode
Introduce full yolo mode
2 parents 34b04ae + 0e71cea commit 434e7fa

File tree

15 files changed

+471
-3
lines changed

15 files changed

+471
-3
lines changed

packages/types/src/global-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const globalSettingsSchema = z.object({
5353
customCondensingPrompt: z.string().optional(),
5454

5555
autoApprovalEnabled: z.boolean().optional(),
56+
yoloMode: z.boolean().optional(), // kilocode_change
5657
alwaysAllowReadOnly: z.boolean().optional(),
5758
alwaysAllowReadOnlyOutsideWorkspace: z.boolean().optional(),
5859
alwaysAllowWrite: z.boolean().optional(),

src/core/assistant-message/presentAssistantMessage.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,14 @@ export async function presentAssistantMessage(cline: Task) {
311311
progressStatus?: ToolProgressStatus,
312312
isProtected?: boolean,
313313
) => {
314+
// kilocode_change start: yolo mode
315+
316+
const state = await cline.providerRef.deref()?.getState()
317+
if (state?.yoloMode) {
318+
return true
319+
}
320+
// kilocode_change end
321+
314322
const { response, text, images } = await cline.ask(
315323
type,
316324
partialMessage,

src/core/task/AutoApprovalHandler.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ export class AutoApprovalHandler {
2525
data: string,
2626
) => Promise<{ response: ClineAskResponse; text?: string; images?: string[] }>,
2727
): Promise<AutoApprovalResult> {
28+
// kilocode_change start: yolo mode
29+
if (state?.yoloMode) {
30+
return {
31+
shouldProceed: true,
32+
requiresApproval: false,
33+
}
34+
}
35+
// kilocode_change end
36+
2837
// Check request count limit
2938
const requestResult = await this.checkRequestLimit(state, messages, askForApproval)
3039
if (!requestResult.shouldProceed || requestResult.requiresApproval) {

src/core/task/Task.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,41 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
841841
await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text, isProtected })
842842
}
843843

844+
// kilocode_change start: YOLO mode auto-answer for follow-up questions
845+
// Check if this is a follow-up question with suggestions in YOLO mode
846+
if (type === "followup" && text && !partial) {
847+
try {
848+
const state = await this.providerRef.deref()?.getState()
849+
if (state?.yoloMode) {
850+
// Parse the follow-up JSON to extract suggestions
851+
const followUpData = JSON.parse(text)
852+
if (
853+
followUpData.suggest &&
854+
Array.isArray(followUpData.suggest) &&
855+
followUpData.suggest.length > 0
856+
) {
857+
// Auto-select the first suggestion
858+
const firstSuggestion = followUpData.suggest[0]
859+
const autoAnswer = firstSuggestion.answer || firstSuggestion
860+
861+
// Immediately set the response as if the user clicked the first suggestion
862+
this.handleWebviewAskResponse("messageResponse", autoAnswer, undefined)
863+
864+
// Return immediately with the auto-selected answer
865+
const result = { response: this.askResponse!, text: autoAnswer, images: undefined }
866+
this.askResponse = undefined
867+
this.askResponseText = undefined
868+
this.askResponseImages = undefined
869+
return result
870+
}
871+
}
872+
} catch (error) {
873+
// If parsing fails or YOLO check fails, continue with normal flow
874+
console.warn("Failed to auto-answer follow-up question in YOLO mode:", error)
875+
}
876+
}
877+
// kilocode_change end
878+
844879
// The state is mutable if the message is complete and the task will
845880
// block (via the `pWaitFor`).
846881
const isBlocking = !(this.askResponse !== undefined || this.lastMessageTs !== askTs)

src/core/task/__tests__/AutoApprovalHandler.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,56 @@ describe("AutoApprovalHandler", () => {
3535
expect(mockAskForApproval).not.toHaveBeenCalled()
3636
})
3737

38+
// kilocode_change start: yolo mode
39+
it("should bypass all checks when YOLO mode is enabled", async () => {
40+
mockState.yoloMode = true
41+
mockState.allowedMaxRequests = 1
42+
mockState.allowedMaxCost = 0.01
43+
44+
const messages: ClineMessage[] = []
45+
// Add messages that would normally exceed limits
46+
for (let i = 0; i < 10; i++) {
47+
messages.push({ type: "say", say: "api_req_started", text: "{}", ts: 1000 + i })
48+
}
49+
50+
mockGetApiMetrics.mockReturnValue({ totalCost: 100.0 })
51+
52+
const result = await handler.checkAutoApprovalLimits(mockState, messages, mockAskForApproval)
53+
54+
expect(result.shouldProceed).toBe(true)
55+
expect(result.requiresApproval).toBe(false)
56+
expect(mockAskForApproval).not.toHaveBeenCalled()
57+
expect(mockGetApiMetrics).not.toHaveBeenCalled()
58+
})
59+
60+
it("should bypass request limits when YOLO mode is enabled", async () => {
61+
mockState.yoloMode = true
62+
mockState.allowedMaxRequests = 0
63+
64+
const messages: ClineMessage[] = []
65+
const result = await handler.checkAutoApprovalLimits(mockState, messages, mockAskForApproval)
66+
67+
expect(result.shouldProceed).toBe(true)
68+
expect(result.requiresApproval).toBe(false)
69+
expect(mockAskForApproval).not.toHaveBeenCalled()
70+
})
71+
72+
it("should bypass cost limits when YOLO mode is enabled", async () => {
73+
mockState.yoloMode = true
74+
mockState.allowedMaxCost = 0
75+
76+
const messages: ClineMessage[] = []
77+
mockGetApiMetrics.mockReturnValue({ totalCost: 1000.0 })
78+
79+
const result = await handler.checkAutoApprovalLimits(mockState, messages, mockAskForApproval)
80+
81+
expect(result.shouldProceed).toBe(true)
82+
expect(result.requiresApproval).toBe(false)
83+
expect(mockAskForApproval).not.toHaveBeenCalled()
84+
expect(mockGetApiMetrics).not.toHaveBeenCalled()
85+
})
86+
// kilocode_change end
87+
3888
it("should check request limit before cost limit", async () => {
3989
mockState.allowedMaxRequests = 1
4090
mockState.allowedMaxCost = 10

0 commit comments

Comments
 (0)