Skip to content

Commit 9321cef

Browse files
authored
Switch from Redis to a Socket.IO bridge (#6930)
1 parent fbe7756 commit 9321cef

File tree

3 files changed

+82
-34
lines changed

3 files changed

+82
-34
lines changed

src/core/task/Task.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export type TaskOptions = {
107107
apiConfiguration: ProviderSettings
108108
enableDiff?: boolean
109109
enableCheckpoints?: boolean
110+
enableTaskBridge?: boolean
110111
fuzzyMatchThreshold?: number
111112
consecutiveMistakeLimit?: number
112113
task?: string
@@ -118,7 +119,6 @@ export type TaskOptions = {
118119
parentTask?: Task
119120
taskNumber?: number
120121
onCreated?: (task: Task) => void
121-
enableTaskBridge?: boolean
122122
}
123123

124124
export class Task extends EventEmitter<TaskEvents> implements TaskLike {
@@ -239,7 +239,8 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
239239
checkpointServiceInitializing = false
240240

241241
// Task Bridge
242-
taskBridgeService?: TaskBridgeService
242+
enableTaskBridge: boolean
243+
taskBridgeService: TaskBridgeService | null = null
243244

244245
// Streaming
245246
isWaitingForFirstChunk = false
@@ -264,6 +265,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
264265
apiConfiguration,
265266
enableDiff = false,
266267
enableCheckpoints = true,
268+
enableTaskBridge = false,
267269
fuzzyMatchThreshold = 1.0,
268270
consecutiveMistakeLimit = DEFAULT_CONSECUTIVE_MISTAKE_LIMIT,
269271
task,
@@ -274,7 +276,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
274276
parentTask,
275277
taskNumber = -1,
276278
onCreated,
277-
enableTaskBridge = false,
278279
}: TaskOptions) {
279280
super()
280281

@@ -313,6 +314,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
313314
this.globalStoragePath = provider.context.globalStorageUri.fsPath
314315
this.diffViewProvider = new DiffViewProvider(this.cwd, this)
315316
this.enableCheckpoints = enableCheckpoints
317+
this.enableTaskBridge = enableTaskBridge
316318

317319
this.rootTask = rootTask
318320
this.parentTask = parentTask
@@ -352,11 +354,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
352354

353355
this.toolRepetitionDetector = new ToolRepetitionDetector(this.consecutiveMistakeLimit)
354356

355-
// Initialize TaskBridgeService only if enabled
356-
if (enableTaskBridge) {
357-
this.taskBridgeService = TaskBridgeService.getInstance()
358-
}
359-
360357
onCreated?.(this)
361358

362359
if (startTask) {
@@ -982,9 +979,20 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
982979
// Start / Abort / Resume
983980

984981
private async startTask(task?: string, images?: string[]): Promise<void> {
985-
if (this.taskBridgeService) {
986-
await this.taskBridgeService.initialize()
987-
await this.taskBridgeService.subscribeToTask(this)
982+
if (this.enableTaskBridge && CloudService.hasInstance()) {
983+
if (!this.taskBridgeService) {
984+
const bridgeConfig = await CloudService.instance.cloudAPI?.bridgeConfig()
985+
986+
if (bridgeConfig) {
987+
this.taskBridgeService = await TaskBridgeService.createInstance({
988+
...bridgeConfig,
989+
})
990+
}
991+
}
992+
993+
if (this.taskBridgeService) {
994+
await this.taskBridgeService.subscribeToTask(this)
995+
}
988996
}
989997

990998
// `conversationHistory` (for API) and `clineMessages` (for webview)
@@ -1038,9 +1046,20 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
10381046
}
10391047

10401048
private async resumeTaskFromHistory() {
1041-
if (this.taskBridgeService) {
1042-
await this.taskBridgeService.initialize()
1043-
await this.taskBridgeService.subscribeToTask(this)
1049+
if (this.enableTaskBridge && CloudService.hasInstance()) {
1050+
if (!this.taskBridgeService) {
1051+
const bridgeConfig = await CloudService.instance.cloudAPI?.bridgeConfig()
1052+
1053+
if (bridgeConfig) {
1054+
this.taskBridgeService = await TaskBridgeService.createInstance({
1055+
...bridgeConfig,
1056+
})
1057+
}
1058+
}
1059+
1060+
if (this.taskBridgeService) {
1061+
await this.taskBridgeService.subscribeToTask(this)
1062+
}
10441063
}
10451064

10461065
const modifiedClineMessages = await this.getSavedClineMessages()
@@ -1293,6 +1312,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
12931312
this.taskBridgeService
12941313
.unsubscribeFromTask(this.taskId)
12951314
.catch((error) => console.error("Error unsubscribing from task bridge:", error))
1315+
this.taskBridgeService = null
12961316
}
12971317

12981318
// Release any terminals associated with this task.

src/core/webview/ClineProvider.ts

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -724,9 +724,6 @@ export class ClineProvider
724724
throw new OrganizationAllowListViolationError(t("common:errors.violated_organization_allowlist"))
725725
}
726726

727-
// Determine if TaskBridge should be enabled
728-
const enableTaskBridge = isRemoteControlEnabled(cloudUserInfo, remoteControlEnabled)
729-
730727
const task = new Task({
731728
provider: this,
732729
apiConfiguration,
@@ -741,7 +738,7 @@ export class ClineProvider
741738
parentTask,
742739
taskNumber: this.clineStack.length + 1,
743740
onCreated: this.taskCreationCallback,
744-
enableTaskBridge,
741+
enableTaskBridge: isRemoteControlEnabled(cloudUserInfo, remoteControlEnabled),
745742
...options,
746743
})
747744

@@ -2139,26 +2136,49 @@ export class ClineProvider
21392136
* Handle remote control enabled/disabled state changes
21402137
* Manages ExtensionBridgeService and TaskBridgeService lifecycle
21412138
*/
2142-
public async handleRemoteControlToggle(enabled: boolean): Promise<void> {
2139+
public async handleRemoteControlToggle(enabled: boolean) {
21432140
const {
21442141
CloudService: CloudServiceImport,
21452142
ExtensionBridgeService,
21462143
TaskBridgeService,
21472144
} = await import("@roo-code/cloud")
2145+
21482146
const userInfo = CloudServiceImport.instance.getUserInfo()
21492147

2150-
// Handle ExtensionBridgeService using static method
2151-
await ExtensionBridgeService.handleRemoteControlState(userInfo, enabled, this, (message: string) =>
2152-
this.log(message),
2148+
const bridgeConfig = await CloudServiceImport.instance.cloudAPI?.bridgeConfig()
2149+
2150+
if (!bridgeConfig) {
2151+
this.log("[CloudService] Failed to get bridge config")
2152+
return
2153+
}
2154+
2155+
ExtensionBridgeService.handleRemoteControlState(
2156+
userInfo,
2157+
enabled,
2158+
{ ...bridgeConfig, provider: this },
2159+
(message: string) => this.log(message),
21532160
)
21542161

21552162
if (isRemoteControlEnabled(userInfo, enabled)) {
2156-
// Set up TaskBridgeService for the currently active task if one exists
2163+
// Set up TaskBridgeService for the currently active task if one exists.
21572164
const currentTask = this.getCurrentCline()
2158-
if (currentTask && !currentTask.taskBridgeService) {
2165+
2166+
if (currentTask && !currentTask.taskBridgeService && CloudService.hasInstance()) {
21592167
try {
2160-
currentTask.taskBridgeService = TaskBridgeService.getInstance()
2161-
await currentTask.taskBridgeService.subscribeToTask(currentTask)
2168+
if (!currentTask.taskBridgeService) {
2169+
const bridgeConfig = await CloudService.instance.cloudAPI?.bridgeConfig()
2170+
2171+
if (bridgeConfig) {
2172+
currentTask.taskBridgeService = await TaskBridgeService.createInstance({
2173+
...bridgeConfig,
2174+
})
2175+
}
2176+
}
2177+
2178+
if (currentTask.taskBridgeService) {
2179+
await currentTask.taskBridgeService.subscribeToTask(currentTask)
2180+
}
2181+
21622182
this.log(`[TaskBridgeService] Subscribed current task ${currentTask.taskId} to TaskBridge`)
21632183
} catch (error) {
21642184
const message = `[TaskBridgeService#subscribeToTask] ${error instanceof Error ? error.message : String(error)}`
@@ -2167,12 +2187,12 @@ export class ClineProvider
21672187
}
21682188
}
21692189
} else {
2170-
// Disconnect TaskBridgeService for all tasks in the stack
2190+
// Disconnect TaskBridgeService for all tasks in the stack.
21712191
for (const task of this.clineStack) {
21722192
if (task.taskBridgeService) {
21732193
try {
21742194
await task.taskBridgeService.unsubscribeFromTask(task.taskId)
2175-
task.taskBridgeService = undefined
2195+
task.taskBridgeService = null
21762196
this.log(`[TaskBridgeService] Unsubscribed task ${task.taskId} from TaskBridge`)
21772197
} catch (error) {
21782198
const message = `[TaskBridgeService#unsubscribeFromTask] for task ${task.taskId}: ${error instanceof Error ? error.message : String(error)}`
@@ -2181,6 +2201,8 @@ export class ClineProvider
21812201
}
21822202
}
21832203
}
2204+
2205+
TaskBridgeService.resetInstance()
21842206
}
21852207
}
21862208

src/extension.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,21 @@ export async function activate(context: vscode.ExtensionContext) {
131131
cloudService.on("auth-state-changed", postStateListener)
132132
cloudService.on("settings-updated", postStateListener)
133133

134-
cloudService.on("user-info", ({ userInfo }) => {
134+
cloudService.on("user-info", async ({ userInfo }) => {
135135
postStateListener()
136136

137-
// Check if remote control is enabled in user settings
138-
const remoteControlEnabled = contextProxy.getValue("remoteControlEnabled")
137+
const bridgeConfig = await cloudService.cloudAPI?.bridgeConfig()
139138

140-
// Handle ExtensionBridgeService state using static method
141-
ExtensionBridgeService.handleRemoteControlState(userInfo, remoteControlEnabled, provider, (message: string) =>
142-
outputChannel.appendLine(message),
139+
if (!bridgeConfig) {
140+
outputChannel.appendLine("[CloudService] Failed to get bridge config")
141+
return
142+
}
143+
144+
ExtensionBridgeService.handleRemoteControlState(
145+
userInfo,
146+
contextProxy.getValue("remoteControlEnabled"),
147+
{ ...bridgeConfig, provider },
148+
(message: string) => outputChannel.appendLine(message),
143149
)
144150
})
145151

0 commit comments

Comments
 (0)