Skip to content

Commit 3b19d7a

Browse files
authored
Await checkpoint saves (except the initial) (RooCodeInc#2665)
1 parent 75a6bc1 commit 3b19d7a

File tree

19 files changed

+653
-922
lines changed

19 files changed

+653
-922
lines changed

src/core/Cline.ts

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ import { TokenUsage } from "../schemas"
1616
import { ApiHandler, buildApiHandler } from "../api"
1717
import { ApiStream } from "../api/transform/stream"
1818
import { DIFF_VIEW_URI_SCHEME, DiffViewProvider } from "../integrations/editor/DiffViewProvider"
19-
import {
20-
CheckpointServiceOptions,
21-
RepoPerTaskCheckpointService,
22-
RepoPerWorkspaceCheckpointService,
23-
} from "../services/checkpoints"
19+
import { CheckpointServiceOptions, RepoPerTaskCheckpointService } from "../services/checkpoints"
2420
import { findToolName, formatContentBlockToMarkdown } from "../integrations/misc/export-markdown"
2521
import { fetchInstructionsTool } from "./tools/fetchInstructionsTool"
2622
import { listFilesTool } from "./tools/listFilesTool"
@@ -30,7 +26,6 @@ import { Terminal } from "../integrations/terminal/Terminal"
3026
import { TerminalRegistry } from "../integrations/terminal/TerminalRegistry"
3127
import { UrlContentFetcher } from "../services/browser/UrlContentFetcher"
3228
import { listFiles } from "../services/glob/list-files"
33-
import { CheckpointStorage } from "../shared/checkpoints"
3429
import { ApiConfiguration } from "../shared/api"
3530
import { findLastIndex } from "../shared/array"
3631
import { combineApiRequests } from "../shared/combineApiRequests"
@@ -104,7 +99,6 @@ export type ClineOptions = {
10499
customInstructions?: string
105100
enableDiff?: boolean
106101
enableCheckpoints?: boolean
107-
checkpointStorage?: CheckpointStorage
108102
fuzzyMatchThreshold?: number
109103
consecutiveMistakeLimit?: number
110104
task?: string
@@ -162,8 +156,8 @@ export class Cline extends EventEmitter<ClineEvents> {
162156

163157
// checkpoints
164158
private enableCheckpoints: boolean
165-
private checkpointStorage: CheckpointStorage
166-
private checkpointService?: RepoPerTaskCheckpointService | RepoPerWorkspaceCheckpointService
159+
private checkpointService?: RepoPerTaskCheckpointService
160+
private checkpointServiceInitializing = false
167161

168162
// streaming
169163
isWaitingForFirstChunk = false
@@ -184,7 +178,6 @@ export class Cline extends EventEmitter<ClineEvents> {
184178
customInstructions,
185179
enableDiff = false,
186180
enableCheckpoints = true,
187-
checkpointStorage = "task",
188181
fuzzyMatchThreshold = 1.0,
189182
consecutiveMistakeLimit = 3,
190183
task,
@@ -223,7 +216,6 @@ export class Cline extends EventEmitter<ClineEvents> {
223216
this.providerRef = new WeakRef(provider)
224217
this.diffViewProvider = new DiffViewProvider(this.cwd)
225218
this.enableCheckpoints = enableCheckpoints
226-
this.checkpointStorage = checkpointStorage
227219

228220
this.rootTask = rootTask
229221
this.parentTask = parentTask
@@ -1680,9 +1672,11 @@ export class Cline extends EventEmitter<ClineEvents> {
16801672
}
16811673

16821674
const recentlyModifiedFiles = this.fileContextTracker.getAndClearCheckpointPossibleFile()
1675+
16831676
if (recentlyModifiedFiles.length > 0) {
1684-
// TODO: we can track what file changes were made and only checkpoint those files, this will be save storage
1685-
this.checkpointSave()
1677+
// TODO: We can track what file changes were made and only
1678+
// checkpoint those files, this will be save storage.
1679+
await this.checkpointSave()
16861680
}
16871681

16881682
/*
@@ -2397,6 +2391,11 @@ export class Cline extends EventEmitter<ClineEvents> {
23972391
return this.checkpointService
23982392
}
23992393

2394+
if (this.checkpointServiceInitializing) {
2395+
console.log("[Cline#getCheckpointService] checkpoint service is still initializing")
2396+
return undefined
2397+
}
2398+
24002399
const log = (message: string) => {
24012400
console.log(message)
24022401

@@ -2407,19 +2406,21 @@ export class Cline extends EventEmitter<ClineEvents> {
24072406
}
24082407
}
24092408

2409+
console.log("[Cline#getCheckpointService] initializing checkpoints service")
2410+
24102411
try {
24112412
const workspaceDir = getWorkspacePath()
24122413

24132414
if (!workspaceDir) {
2414-
log("[Cline#initializeCheckpoints] workspace folder not found, disabling checkpoints")
2415+
log("[Cline#getCheckpointService] workspace folder not found, disabling checkpoints")
24152416
this.enableCheckpoints = false
24162417
return undefined
24172418
}
24182419

24192420
const globalStorageDir = this.providerRef.deref()?.context.globalStorageUri.fsPath
24202421

24212422
if (!globalStorageDir) {
2422-
log("[Cline#initializeCheckpoints] globalStorageDir not found, disabling checkpoints")
2423+
log("[Cline#getCheckpointService] globalStorageDir not found, disabling checkpoints")
24232424
this.enableCheckpoints = false
24242425
return undefined
24252426
}
@@ -2431,28 +2432,26 @@ export class Cline extends EventEmitter<ClineEvents> {
24312432
log,
24322433
}
24332434

2434-
// Only `task` is supported at the moment until we figure out how
2435-
// to fully isolate the `workspace` variant.
2436-
// const service =
2437-
// this.checkpointStorage === "task"
2438-
// ? RepoPerTaskCheckpointService.create(options)
2439-
// : RepoPerWorkspaceCheckpointService.create(options)
2440-
24412435
const service = RepoPerTaskCheckpointService.create(options)
24422436

2437+
this.checkpointServiceInitializing = true
2438+
24432439
service.on("initialize", () => {
2440+
log("[Cline#getCheckpointService] service initialized")
2441+
24442442
try {
24452443
const isCheckpointNeeded =
24462444
typeof this.clineMessages.find(({ say }) => say === "checkpoint_saved") === "undefined"
24472445

24482446
this.checkpointService = service
2447+
this.checkpointServiceInitializing = false
24492448

24502449
if (isCheckpointNeeded) {
2451-
log("[Cline#initializeCheckpoints] no checkpoints found, saving initial checkpoint")
2450+
log("[Cline#getCheckpointService] no checkpoints found, saving initial checkpoint")
24522451
this.checkpointSave()
24532452
}
24542453
} catch (err) {
2455-
log("[Cline#initializeCheckpoints] caught error in on('initialize'), disabling checkpoints")
2454+
log("[Cline#getCheckpointService] caught error in on('initialize'), disabling checkpoints")
24562455
this.enableCheckpoints = false
24572456
}
24582457
})
@@ -2462,29 +2461,31 @@ export class Cline extends EventEmitter<ClineEvents> {
24622461
this.providerRef.deref()?.postMessageToWebview({ type: "currentCheckpointUpdated", text: to })
24632462

24642463
this.say("checkpoint_saved", to, undefined, undefined, { isFirst, from, to }).catch((err) => {
2465-
log("[Cline#initializeCheckpoints] caught unexpected error in say('checkpoint_saved')")
2464+
log("[Cline#getCheckpointService] caught unexpected error in say('checkpoint_saved')")
24662465
console.error(err)
24672466
})
24682467
} catch (err) {
24692468
log(
2470-
"[Cline#initializeCheckpoints] caught unexpected error in on('checkpoint'), disabling checkpoints",
2469+
"[Cline#getCheckpointService] caught unexpected error in on('checkpoint'), disabling checkpoints",
24712470
)
24722471
console.error(err)
24732472
this.enableCheckpoints = false
24742473
}
24752474
})
24762475

2476+
log("[Cline#getCheckpointService] initializing shadow git")
2477+
24772478
service.initShadowGit().catch((err) => {
24782479
log(
2479-
`[Cline#initializeCheckpoints] caught unexpected error in initShadowGit, disabling checkpoints (${err.message})`,
2480+
`[Cline#getCheckpointService] caught unexpected error in initShadowGit, disabling checkpoints (${err.message})`,
24802481
)
24812482
console.error(err)
24822483
this.enableCheckpoints = false
24832484
})
24842485

24852486
return service
24862487
} catch (err) {
2487-
log("[Cline#initializeCheckpoints] caught unexpected error, disabling checkpoints")
2488+
log("[Cline#getCheckpointService] caught unexpected error, disabling checkpoints")
24882489
this.enableCheckpoints = false
24892490
return undefined
24902491
}
@@ -2508,6 +2509,7 @@ export class Cline extends EventEmitter<ClineEvents> {
25082509
},
25092510
{ interval, timeout },
25102511
)
2512+
25112513
return service
25122514
} catch (err) {
25132515
return undefined
@@ -2569,7 +2571,7 @@ export class Cline extends EventEmitter<ClineEvents> {
25692571
}
25702572
}
25712573

2572-
public checkpointSave() {
2574+
public async checkpointSave() {
25732575
const service = this.getCheckpointService()
25742576

25752577
if (!service) {
@@ -2580,14 +2582,15 @@ export class Cline extends EventEmitter<ClineEvents> {
25802582
this.providerRef
25812583
.deref()
25822584
?.log("[checkpointSave] checkpoints didn't initialize in time, disabling checkpoints for this task")
2585+
25832586
this.enableCheckpoints = false
25842587
return
25852588
}
25862589

25872590
telemetryService.captureCheckpointCreated(this.taskId)
25882591

25892592
// Start the checkpoint process in the background.
2590-
service.saveCheckpoint(`Task: ${this.taskId}, Time: ${Date.now()}`).catch((err) => {
2593+
return service.saveCheckpoint(`Task: ${this.taskId}, Time: ${Date.now()}`).catch((err) => {
25912594
console.error("[Cline#checkpointSave] caught unexpected error, disabling checkpoints", err)
25922595
this.enableCheckpoints = false
25932596
})

src/core/webview/ClineProvider.ts

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
483483
| "customInstructions"
484484
| "enableDiff"
485485
| "enableCheckpoints"
486-
| "checkpointStorage"
487486
| "fuzzyMatchThreshold"
488487
| "consecutiveMistakeLimit"
489488
| "experiments"
@@ -495,7 +494,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
495494
customModePrompts,
496495
diffEnabled: enableDiff,
497496
enableCheckpoints,
498-
checkpointStorage,
499497
fuzzyMatchThreshold,
500498
mode,
501499
customInstructions: globalInstructions,
@@ -511,7 +509,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
511509
customInstructions: effectiveInstructions,
512510
enableDiff,
513511
enableCheckpoints,
514-
checkpointStorage,
515512
fuzzyMatchThreshold,
516513
task,
517514
images,
@@ -540,7 +537,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
540537
customModePrompts,
541538
diffEnabled: enableDiff,
542539
enableCheckpoints,
543-
checkpointStorage,
544540
fuzzyMatchThreshold,
545541
mode,
546542
customInstructions: globalInstructions,
@@ -550,38 +546,12 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
550546
const modePrompt = customModePrompts?.[mode] as PromptComponent
551547
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
552548

553-
const taskId = historyItem.id
554-
const globalStorageDir = this.contextProxy.globalStorageUri.fsPath
555-
const workspaceDir = this.cwd
556-
557-
const checkpoints: Pick<ClineOptions, "enableCheckpoints" | "checkpointStorage"> = {
558-
enableCheckpoints,
559-
checkpointStorage,
560-
}
561-
562-
if (enableCheckpoints) {
563-
try {
564-
checkpoints.checkpointStorage = await ShadowCheckpointService.getTaskStorage({
565-
taskId,
566-
globalStorageDir,
567-
workspaceDir,
568-
})
569-
570-
this.log(
571-
`[ClineProvider#initClineWithHistoryItem] Using ${checkpoints.checkpointStorage} storage for ${taskId}`,
572-
)
573-
} catch (error) {
574-
checkpoints.enableCheckpoints = false
575-
this.log(`[ClineProvider#initClineWithHistoryItem] Error getting task storage: ${error.message}`)
576-
}
577-
}
578-
579549
const cline = new Cline({
580550
provider: this,
581551
apiConfiguration,
582552
customInstructions: effectiveInstructions,
583553
enableDiff,
584-
...checkpoints,
554+
enableCheckpoints,
585555
fuzzyMatchThreshold,
586556
historyItem,
587557
experiments,
@@ -1210,7 +1180,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
12101180
ttsSpeed,
12111181
diffEnabled,
12121182
enableCheckpoints,
1213-
checkpointStorage,
12141183
taskHistory,
12151184
soundVolume,
12161185
browserViewportSize,
@@ -1282,7 +1251,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
12821251
ttsSpeed: ttsSpeed ?? 1.0,
12831252
diffEnabled: diffEnabled ?? true,
12841253
enableCheckpoints: enableCheckpoints ?? true,
1285-
checkpointStorage: checkpointStorage ?? "task",
12861254
shouldShowAnnouncement:
12871255
telemetrySetting !== "unset" && lastShownAnnouncementId !== this.latestAnnouncementId,
12881256
allowedCommands,
@@ -1377,7 +1345,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
13771345
ttsSpeed: stateValues.ttsSpeed ?? 1.0,
13781346
diffEnabled: stateValues.diffEnabled ?? true,
13791347
enableCheckpoints: stateValues.enableCheckpoints ?? true,
1380-
checkpointStorage: stateValues.checkpointStorage ?? "task",
13811348
soundVolume: stateValues.soundVolume,
13821349
browserViewportSize: stateValues.browserViewportSize ?? "900x600",
13831350
screenshotQuality: stateValues.screenshotQuality ?? 75,

src/core/webview/__tests__/ClineProvider.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,6 @@ describe("ClineProvider", () => {
407407
ttsEnabled: false,
408408
diffEnabled: false,
409409
enableCheckpoints: false,
410-
checkpointStorage: "task",
411410
writeDelayMs: 1000,
412411
browserViewportSize: "900x600",
413412
fuzzyMatchThreshold: 1.0,
@@ -829,7 +828,6 @@ describe("ClineProvider", () => {
829828
mode: "code",
830829
diffEnabled: true,
831830
enableCheckpoints: false,
832-
checkpointStorage: "task",
833831
fuzzyMatchThreshold: 1.0,
834832
experiments: experimentDefault,
835833
} as any)
@@ -848,7 +846,6 @@ describe("ClineProvider", () => {
848846
customInstructions: modeCustomInstructions,
849847
enableDiff: true,
850848
enableCheckpoints: false,
851-
checkpointStorage: "task",
852849
fuzzyMatchThreshold: 1.0,
853850
task: "Test task",
854851
experiments: experimentDefault,

src/core/webview/webviewMessageHandler.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import pWaitFor from "p-wait-for"
44
import * as vscode from "vscode"
55

66
import { ClineProvider } from "./ClineProvider"
7-
import { CheckpointStorage, Language, ApiConfigMeta } from "../../schemas"
7+
import { Language, ApiConfigMeta } from "../../schemas"
88
import { changeLanguage, t } from "../../i18n"
99
import { ApiConfiguration } from "../../shared/api"
1010
import { supportPrompt } from "../../shared/support-prompt"
@@ -655,12 +655,6 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
655655
await updateGlobalState("enableCheckpoints", enableCheckpoints)
656656
await provider.postStateToWebview()
657657
break
658-
case "checkpointStorage":
659-
console.log(`[ClineProvider] checkpointStorage: ${message.text}`)
660-
const checkpointStorage = message.text ?? "task"
661-
await updateGlobalState("checkpointStorage", checkpointStorage as CheckpointStorage)
662-
await provider.postStateToWebview()
663-
break
664658
case "browserViewportSize":
665659
const browserViewportSize = message.text ?? "900x600"
666660
await updateGlobalState("browserViewportSize", browserViewportSize)

src/exports/roo-code.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ type GlobalSettings = {
259259
remoteBrowserHost?: string | undefined
260260
cachedChromeHostUrl?: string | undefined
261261
enableCheckpoints?: boolean | undefined
262-
checkpointStorage?: ("task" | "workspace") | undefined
263262
showGreeting?: boolean | undefined
264263
ttsEnabled?: boolean | undefined
265264
ttsSpeed?: number | undefined

src/exports/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,6 @@ type GlobalSettings = {
262262
remoteBrowserHost?: string | undefined
263263
cachedChromeHostUrl?: string | undefined
264264
enableCheckpoints?: boolean | undefined
265-
checkpointStorage?: ("task" | "workspace") | undefined
266265
showGreeting?: boolean | undefined
267266
ttsEnabled?: boolean | undefined
268267
ttsSpeed?: number | undefined

0 commit comments

Comments
 (0)