Skip to content

Commit 7eb469f

Browse files
authored
Re-enable ClineProvider tests (#2047)
1 parent 0fd399d commit 7eb469f

File tree

4 files changed

+155
-284
lines changed

4 files changed

+155
-284
lines changed

src/__mocks__/p-wait-for.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
function pWaitFor(condition, options = {}) {
22
return new Promise((resolve, reject) => {
3+
let timeout
4+
35
const interval = setInterval(() => {
46
if (condition()) {
7+
if (timeout) {
8+
clearTimeout(timeout)
9+
}
10+
511
clearInterval(interval)
612
resolve()
713
}
814
}, options.interval || 20)
915

1016
if (options.timeout) {
11-
setTimeout(() => {
17+
timeout = setTimeout(() => {
1218
clearInterval(interval)
1319
reject(new Error("Timed out"))
1420
}, options.timeout)

src/core/Cline.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,7 @@ export type ClineOptions = {
123123
export class Cline extends EventEmitter<ClineEvents> {
124124
readonly taskId: string
125125
readonly instanceId: string
126-
get cwd() {
127-
return getWorkspacePath(path.join(os.homedir(), "Desktop"))
128-
}
129-
// Subtasks
126+
130127
readonly rootTask: Cline | undefined = undefined
131128
readonly parentTask: Cline | undefined = undefined
132129
readonly taskNumber: number
@@ -268,6 +265,10 @@ export class Cline extends EventEmitter<ClineEvents> {
268265
return [instance, promise]
269266
}
270267

268+
get cwd() {
269+
return getWorkspacePath(path.join(os.homedir(), "Desktop"))
270+
}
271+
271272
// Add method to update diffStrategy
272273
async updateDiffStrategy(experimentalDiffStrategy?: boolean, multiSearchReplaceDiffStrategy?: boolean) {
273274
// If not provided, get from current state
@@ -334,6 +335,7 @@ export class Cline extends EventEmitter<ClineEvents> {
334335

335336
private async getSavedClineMessages(): Promise<ClineMessage[]> {
336337
const filePath = path.join(await this.ensureTaskDirectoryExists(), GlobalFileNames.uiMessages)
338+
337339
if (await fileExistsAtPath(filePath)) {
338340
return JSON.parse(await fs.readFile(filePath, "utf8"))
339341
} else {
@@ -1222,11 +1224,12 @@ export class Cline extends EventEmitter<ClineEvents> {
12221224
}
12231225
return { role, content }
12241226
})
1227+
12251228
const stream = this.api.createMessage(systemPrompt, cleanConversationHistory)
12261229
const iterator = stream[Symbol.asyncIterator]()
12271230

12281231
try {
1229-
// awaiting first chunk to see if it will throw an error
1232+
// Awaiting first chunk to see if it will throw an error.
12301233
this.isWaitingForFirstChunk = true
12311234
const firstChunk = await iterator.next()
12321235
yield firstChunk.value
@@ -3392,6 +3395,7 @@ export class Cline extends EventEmitter<ClineEvents> {
33923395
? `This may indicate a failure in his thought process or inability to use a tool properly, which can be mitigated with some user guidance (e.g. "Try breaking down the task into smaller steps").`
33933396
: "Roo Code uses complex prompts and iterative task execution that may be challenging for less capable models. For best results, it's recommended to use Claude 3.7 Sonnet for its advanced agentic coding capabilities.",
33943397
)
3398+
33953399
if (response === "messageResponse") {
33963400
userContent.push(
33973401
...[
@@ -3455,9 +3459,11 @@ export class Cline extends EventEmitter<ClineEvents> {
34553459

34563460
// since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message
34573461
const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started")
3462+
34583463
this.clineMessages[lastApiReqIndex].text = JSON.stringify({
34593464
request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"),
34603465
} satisfies ClineApiReqInfo)
3466+
34613467
await this.saveClineMessages()
34623468
await this.providerRef.deref()?.postStateToWebview()
34633469

@@ -3499,6 +3505,7 @@ export class Cline extends EventEmitter<ClineEvents> {
34993505

35003506
// if last message is a partial we need to update and save it
35013507
const lastMessage = this.clineMessages.at(-1)
3508+
35023509
if (lastMessage && lastMessage.partial) {
35033510
// lastMessage.ts = Date.now() DO NOT update ts since it is used as a key for virtuoso list
35043511
lastMessage.partial = false
@@ -3544,17 +3551,21 @@ export class Cline extends EventEmitter<ClineEvents> {
35443551
this.presentAssistantMessageHasPendingUpdates = false
35453552
await this.diffViewProvider.reset()
35463553

3547-
const stream = this.attemptApiRequest(previousApiReqIndex) // yields only if the first chunk is successful, otherwise will allow the user to retry the request (most likely due to rate limit error, which gets thrown on the first chunk)
3554+
// Yields only if the first chunk is successful, otherwise will
3555+
// allow the user to retry the request (most likely due to rate
3556+
// limit error, which gets thrown on the first chunk).
3557+
const stream = this.attemptApiRequest(previousApiReqIndex)
35483558
let assistantMessage = ""
35493559
let reasoningMessage = ""
35503560
this.isStreaming = true
35513561

35523562
try {
35533563
for await (const chunk of stream) {
35543564
if (!chunk) {
3555-
// Sometimes chunk is undefined, no idea that can cause it, but this workaround seems to fix it
3565+
// Sometimes chunk is undefined, no idea that can cause it, but this workaround seems to fix it.
35563566
continue
35573567
}
3568+
35583569
switch (chunk.type) {
35593570
case "reasoning":
35603571
reasoningMessage += chunk.text
@@ -3610,11 +3621,14 @@ export class Cline extends EventEmitter<ClineEvents> {
36103621
// abandoned happens when extension is no longer waiting for the cline instance to finish aborting (error is thrown here when any function in the for loop throws due to this.abort)
36113622
if (!this.abandoned) {
36123623
this.abortTask() // if the stream failed, there's various states the task could be in (i.e. could have streamed some tools the user may have executed), so we just resort to replicating a cancel task
3624+
36133625
await abortStream(
36143626
"streaming_failed",
36153627
error.message ?? JSON.stringify(serializeError(error), null, 2),
36163628
)
3629+
36173630
const history = await this.providerRef.deref()?.getTaskWithId(this.taskId)
3631+
36183632
if (history) {
36193633
await this.providerRef.deref()?.initClineWithHistoryItem(history.historyItem)
36203634
// await this.providerRef.deref()?.postStateToWebview()
@@ -4092,7 +4106,9 @@ export class Cline extends EventEmitter<ClineEvents> {
40924106
})
40934107

40944108
service.initShadowGit().catch((err) => {
4095-
log("[Cline#initializeCheckpoints] caught unexpected error in initShadowGit, disabling checkpoints")
4109+
log(
4110+
`[Cline#initializeCheckpoints] caught unexpected error in initShadowGit, disabling checkpoints (${err.message})`,
4111+
)
40964112
console.error(err)
40974113
this.enableCheckpoints = false
40984114
})

0 commit comments

Comments
 (0)