Skip to content

Commit 42f7465

Browse files
authored
Add a mode switched event, better mode switch e2e test (#2237)
1 parent c4af8ca commit 42f7465

File tree

8 files changed

+30
-32
lines changed

8 files changed

+30
-32
lines changed

e2e/src/suite/modes.test.ts

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,33 @@ suite("Roo Code Modes", () => {
1313
*/
1414

1515
const switchModesPrompt =
16-
"For each mode (Code, Architect, Ask) respond with the mode name and what it specializes in after switching to that mode. " +
17-
"Do not start with the current mode."
16+
"For each mode (Architect, Ask, Debug) respond with the mode name and what it specializes in after switching to that mode."
1817

1918
let messages: ClineMessage[] = []
2019

20+
const modeSwitches: string[] = []
21+
22+
api.on("taskModeSwitched", (_taskId, mode) => {
23+
console.log("taskModeSwitched", mode)
24+
modeSwitches.push(mode)
25+
})
26+
2127
api.on("message", ({ message }) => {
2228
if (message.type === "say" && message.partial === false) {
2329
messages.push(message)
2430
}
2531
})
2632

2733
const switchModesTaskId = await api.startNewTask({
28-
configuration: { mode: "Code", alwaysAllowModeSwitch: true, autoApprovalEnabled: true },
34+
configuration: { mode: "code", alwaysAllowModeSwitch: true, autoApprovalEnabled: true },
2935
text: switchModesPrompt,
3036
})
3137

32-
await waitUntilCompleted({ api, taskId: switchModesTaskId, timeout: 60_000 })
33-
34-
/**
35-
* Grade the response.
36-
*/
37-
38-
const response = messages
39-
.filter(({ type, say, partial }) => say === "text")
40-
.map(({ text }) => text ?? "")
41-
.join("\n")
42-
43-
const gradePrompt = `Given this prompt: ${switchModesPrompt} grade the response from 1 to 10 in the format of "Grade: (1-10)". For example: Grade 7\n\nResponse: ${response}`
44-
45-
messages = []
46-
47-
const gradeTaskId = await api.startNewTask({ configuration: { mode: "Ask" }, text: gradePrompt })
48-
await waitUntilCompleted({ api, taskId: gradeTaskId })
49-
50-
const completion = messages.find(({ type, say, partial }) => say === "completion_result")
51-
const match = completion?.text?.match(/Grade: (\d+)/)
52-
const score = parseInt(match?.[1] ?? "0")
53-
assert.ok(
54-
score >= 7 && score <= 10,
55-
`Grade must be between 7 and 10. DEBUG: score = ${score}, completion = ${completion?.text}`,
56-
)
57-
38+
await waitUntilCompleted({ api, taskId: switchModesTaskId })
5839
await api.cancelCurrentTask()
40+
41+
assert.ok(modeSwitches.includes("architect"))
42+
assert.ok(modeSwitches.includes("ask"))
43+
assert.ok(modeSwitches.includes("debug"))
5944
})
6045
})

src/core/Cline.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ type UserContent = Array<Anthropic.Messages.ContentBlockParam>
8787
export type ClineEvents = {
8888
message: [{ action: "created" | "updated"; message: ClineMessage }]
8989
taskStarted: []
90+
taskModeSwitched: [taskId: string, mode: string]
9091
taskPaused: []
9192
taskUnpaused: []
9293
taskAskResponded: []

src/core/webview/ClineProvider.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,10 +740,11 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
740740
*/
741741
public async handleModeSwitch(newMode: Mode) {
742742
// Capture mode switch telemetry event
743-
const currentTaskId = this.getCurrentCline()?.taskId
743+
const cline = this.getCurrentCline()
744744

745-
if (currentTaskId) {
746-
telemetryService.captureModeSwitch(currentTaskId, newMode)
745+
if (cline) {
746+
telemetryService.captureModeSwitch(cline.taskId, newMode)
747+
cline.emit("taskModeSwitched", cline.taskId, newMode)
747748
}
748749

749750
await this.updateGlobalState("mode", newMode)

src/exports/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
176176

177177
cline.on("message", (message) => this.emit(RooCodeEventName.Message, { taskId: cline.taskId, ...message }))
178178

179+
cline.on("taskModeSwitched", (taskId, mode) => this.emit(RooCodeEventName.TaskModeSwitched, taskId, mode))
180+
179181
cline.on("taskTokenUsageUpdated", (_, usage) =>
180182
this.emit(RooCodeEventName.TaskTokenUsageUpdated, cline.taskId, usage),
181183
)

src/exports/roo-code.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ type RooCodeEvents = {
470470
]
471471
taskCreated: [string]
472472
taskStarted: [string]
473+
taskModeSwitched: [string, string]
473474
taskPaused: [string]
474475
taskUnpaused: [string]
475476
taskAskResponded: [string]
@@ -506,6 +507,7 @@ declare enum RooCodeEventName {
506507
Message = "message",
507508
TaskCreated = "taskCreated",
508509
TaskStarted = "taskStarted",
510+
TaskModeSwitched = "taskModeSwitched",
509511
TaskPaused = "taskPaused",
510512
TaskUnpaused = "taskUnpaused",
511513
TaskAskResponded = "taskAskResponded",

src/exports/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ type RooCodeEvents = {
479479
]
480480
taskCreated: [string]
481481
taskStarted: [string]
482+
taskModeSwitched: [string, string]
482483
taskPaused: [string]
483484
taskUnpaused: [string]
484485
taskAskResponded: [string]

src/schemas/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ export enum RooCodeEventName {
797797
Message = "message",
798798
TaskCreated = "taskCreated",
799799
TaskStarted = "taskStarted",
800+
TaskModeSwitched = "taskModeSwitched",
800801
TaskPaused = "taskPaused",
801802
TaskUnpaused = "taskUnpaused",
802803
TaskAskResponded = "taskAskResponded",
@@ -816,6 +817,7 @@ export const rooCodeEventsSchema = z.object({
816817
]),
817818
[RooCodeEventName.TaskCreated]: z.tuple([z.string()]),
818819
[RooCodeEventName.TaskStarted]: z.tuple([z.string()]),
820+
[RooCodeEventName.TaskModeSwitched]: z.tuple([z.string(), z.string()]),
819821
[RooCodeEventName.TaskPaused]: z.tuple([z.string()]),
820822
[RooCodeEventName.TaskUnpaused]: z.tuple([z.string()]),
821823
[RooCodeEventName.TaskAskResponded]: z.tuple([z.string()]),

src/schemas/ipc.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export const taskEventSchema = z.discriminatedUnion("eventName", [
6363
eventName: z.literal(RooCodeEventName.TaskStarted),
6464
payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskStarted],
6565
}),
66+
z.object({
67+
eventName: z.literal(RooCodeEventName.TaskModeSwitched),
68+
payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskModeSwitched],
69+
}),
6670
z.object({
6771
eventName: z.literal(RooCodeEventName.TaskPaused),
6872
payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskPaused],

0 commit comments

Comments
 (0)