Identify cloud tasks in the extension bridge (#8539)

This commit is contained in:
Chris Estreich 2025-10-08 20:54:08 -07:00 • committed by GitHub
parent eeaafef786
commit b011b63c93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 31 additions and 8 deletions

View file

@ -83,6 +83,12 @@ export class CloudService extends EventEmitter<CloudServiceEvents> implements Di
return this._retryQueue
}
private _isCloudAgent = false
public get isCloudAgent() {
return this._isCloudAgent
}
private constructor(context: ExtensionContext, log?: (...args: unknown[]) => void) {
super()
@ -117,6 +123,7 @@ export class CloudService extends EventEmitter<CloudServiceEvents> implements Di
if (cloudToken && cloudToken.length > 0) {
this._authService = new StaticTokenAuthService(this.context, cloudToken, this.log)
this._isCloudAgent = true
} else {
this._authService = new WebAuthService(this.context, this.log)
}
@ -141,19 +148,19 @@ export class CloudService extends EventEmitter<CloudServiceEvents> implements Di
this._cloudAPI = new CloudAPI(this._authService, this.log)
// Initialize retry queue with auth header provider
// Initialize retry queue with auth header provider.
this._retryQueue = new RetryQueue(
this.context,
undefined, // Use default config
undefined, // Use default config.
this.log,
() => {
// Provide fresh auth headers for retries
// Provide fresh auth headers for retries.
const sessionToken = this._authService?.getSessionToken()
if (sessionToken) {
return {
Authorization: `Bearer ${sessionToken}`,
}
return { Authorization: `Bearer ${sessionToken}` }
}
return undefined
},
)

View file

@ -7,6 +7,7 @@ export interface BaseChannelOptions {
instanceId: string
appProperties: StaticAppProperties
gitProperties?: GitProperties
isCloudAgent: boolean
}
/**
@ -22,11 +23,13 @@ export abstract class BaseChannel<TCommand = unknown, TEventName extends string
protected readonly instanceId: string
protected readonly appProperties: StaticAppProperties
protected readonly gitProperties?: GitProperties
protected readonly isCloudAgent: boolean
constructor(options: BaseChannelOptions) {
this.instanceId = options.instanceId
this.appProperties = options.appProperties
this.gitProperties = options.gitProperties
this.isCloudAgent = options.isCloudAgent
}
/**

View file

@ -23,7 +23,8 @@ export interface BridgeOrchestratorOptions {
socketBridgeUrl: string
token: string
provider: TaskProviderLike
sessionId?: string
sessionId: string
isCloudAgent: boolean
}
/**
@ -44,6 +45,7 @@ export class BridgeOrchestrator {
private readonly instanceId: string
private readonly appProperties: StaticAppProperties
private readonly gitProperties?: GitProperties
private readonly isCloudAgent?: boolean
// Components
private socketTransport: SocketTransport
@ -96,6 +98,7 @@ export class BridgeOrchestrator {
if (!instance) {
try {
console.log(`[BridgeOrchestrator#connectOrDisconnect] Connecting...`)
// Populate telemetry properties before registering the instance.
await options.provider.getTelemetryProperties()
@ -174,6 +177,7 @@ export class BridgeOrchestrator {
this.instanceId = options.sessionId || crypto.randomUUID()
this.appProperties = { ...options.provider.appProperties, hostname: os.hostname() }
this.gitProperties = options.provider.gitProperties
this.isCloudAgent = options.isCloudAgent
this.socketTransport = new SocketTransport({
url: this.socketBridgeUrl,
@ -200,12 +204,14 @@ export class BridgeOrchestrator {
gitProperties: this.gitProperties,
userId: this.userId,
provider: this.provider,
isCloudAgent: this.isCloudAgent,
})
this.taskChannel = new TaskChannel({
instanceId: this.instanceId,
appProperties: this.appProperties,
gitProperties: this.gitProperties,
isCloudAgent: this.isCloudAgent,
})
}

View file

@ -41,6 +41,7 @@ export class ExtensionChannel extends BaseChannel<
instanceId: options.instanceId,
appProperties: options.appProperties,
gitProperties: options.gitProperties,
isCloudAgent: options.isCloudAgent,
})
this.userId = options.userId
@ -55,6 +56,7 @@ export class ExtensionChannel extends BaseChannel<
lastHeartbeat: Date.now(),
task: { taskId: "", taskStatus: TaskStatus.None },
taskHistory: [],
isCloudAgent: this.isCloudAgent,
}
this.setupListeners()

View file

@ -95,6 +95,7 @@ describe("ExtensionChannel", () => {
appProperties,
userId,
provider: mockProvider,
isCloudAgent: false,
})
})
@ -176,6 +177,7 @@ describe("ExtensionChannel", () => {
appProperties,
userId,
provider: mockProvider,
isCloudAgent: false,
})
// Each event should have exactly 2 listeners (one from each channel)

View file

@ -88,6 +88,7 @@ describe("TaskChannel", () => {
taskChannel = new TaskChannel({
instanceId,
appProperties,
isCloudAgent: false,
})
})

View file

@ -1,6 +1,6 @@
{
"name": "@roo-code/types",
"version": "1.82.0",
"version": "1.83.0",
"description": "TypeScript type definitions for Roo Code.",
"publishConfig": {
"access": "public",

View file

@ -411,6 +411,7 @@ export const extensionInstanceSchema = z.object({
modes: z.array(z.object({ slug: z.string(), name: z.string() })).optional(),
providerProfile: z.string().optional(),
providerProfiles: z.array(z.object({ name: z.string(), provider: z.string().optional() })).optional(),
isCloudAgent: z.boolean().optional(),
})
export type ExtensionInstance = z.infer<typeof extensionInstanceSchema>

View file

@ -2343,6 +2343,7 @@ export class ClineProvider
...config,
provider: this,
sessionId: vscode.env.sessionId,
isCloudAgent: CloudService.instance.isCloudAgent,
})
const bridge = BridgeOrchestrator.getInstance()