Skip to content

Commit e2d78c8

Browse files
authored
Implement when clause for remoteCodingAgents (#252366)
implement when clause for remoteCodingAgents
1 parent cf75ff5 commit e2d78c8

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ export class CreateRemoteAgentJobAction extends Action2 {
513513

514514
const chatModel = widget.viewModel?.model;
515515
const chatRequests = chatModel.getRequests();
516-
const agents = remoteCodingAgent.getRegisteredAgents();
516+
const agents = remoteCodingAgent.getAvailableAgents();
517517
const defaultAgent = chatAgentService.getDefaultAgent(ChatAgentLocation.Panel);
518518

519519
const agent = agents[0]; // TODO: We just pick the first one for testing

src/vs/workbench/contrib/remoteCodingAgents/browser/remoteCodingAgents.contribution.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,12 @@ export class RemoteCodingAgentsContribution extends Disposable implements IWorkb
7676
continue;
7777
}
7878

79-
// TODO: Handle 'when' clause
80-
8179
const agent: IRemoteCodingAgent = {
8280
id: contribution.id,
8381
command: contribution.command,
8482
displayName: contribution.displayName,
85-
description: contribution.description
83+
description: contribution.description,
84+
when: contribution.when
8685
};
8786
this.logService.info(`Registering remote coding agent: ${agent.displayName} (${agent.command})`);
8887
this.remoteCodingAgentsService.registerAgent(agent);

src/vs/workbench/contrib/remoteCodingAgents/common/remoteCodingAgentsService.ts

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
6+
import { Disposable } from '../../../../base/common/lifecycle.js';
7+
import { Event } from '../../../../base/common/event.js';
8+
import { ContextKeyExpr, IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
79
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
810
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
911
import { ChatContextKeys } from '../../chat/common/chatContextKeys.js';
@@ -13,37 +15,80 @@ export interface IRemoteCodingAgent {
1315
command: string;
1416
displayName: string;
1517
description?: string;
18+
when?: string;
1619
}
1720

1821
export interface IRemoteCodingAgentsService {
1922
readonly _serviceBrand: undefined;
2023
getRegisteredAgents(): IRemoteCodingAgent[];
24+
getAvailableAgents(): IRemoteCodingAgent[];
2125
registerAgent(agent: IRemoteCodingAgent): void;
2226
}
2327

2428
export const IRemoteCodingAgentsService = createDecorator<IRemoteCodingAgentsService>('remoteCodingAgentsService');
2529

26-
export class RemoteCodingAgentsService implements IRemoteCodingAgentsService {
30+
export class RemoteCodingAgentsService extends Disposable implements IRemoteCodingAgentsService {
2731
readonly _serviceBrand: undefined;
2832
private readonly _ctxHasRemoteCodingAgent: IContextKey<boolean>;
33+
private readonly agents: IRemoteCodingAgent[] = [];
34+
private readonly contextKeys = new Set<string>();
2935

3036
constructor(
3137
@IContextKeyService private readonly contextKeyService: IContextKeyService
3238
) {
39+
super();
3340
this._ctxHasRemoteCodingAgent = ChatContextKeys.hasRemoteCodingAgent.bindTo(this.contextKeyService);
34-
}
3541

36-
private agents: IRemoteCodingAgent[] = [];
42+
// Listen for context changes and re-evaluate agent availability
43+
this._register(Event.filter(contextKeyService.onDidChangeContext, e => e.affectsSome(this.contextKeys))(() => {
44+
this.updateContextKeys();
45+
}));
46+
}
3747

3848
getRegisteredAgents(): IRemoteCodingAgent[] {
39-
return this.agents;
49+
return [...this.agents];
50+
}
51+
52+
getAvailableAgents(): IRemoteCodingAgent[] {
53+
return this.agents.filter(agent => this.isAgentAvailable(agent));
4054
}
4155

4256
registerAgent(agent: IRemoteCodingAgent): void {
43-
if (!this.agents.includes(agent)) {
57+
// Check if agent already exists
58+
const existingIndex = this.agents.findIndex(a => a.id === agent.id);
59+
if (existingIndex >= 0) {
60+
// Update existing agent
61+
this.agents[existingIndex] = agent;
62+
} else {
63+
// Add new agent
4464
this.agents.push(agent);
45-
this._ctxHasRemoteCodingAgent.set(true);
4665
}
66+
67+
// Track context keys from the when condition
68+
if (agent.when) {
69+
const whenExpr = ContextKeyExpr.deserialize(agent.when);
70+
if (whenExpr) {
71+
for (const key of whenExpr.keys()) {
72+
this.contextKeys.add(key);
73+
}
74+
}
75+
}
76+
77+
this.updateContextKeys();
78+
}
79+
80+
private isAgentAvailable(agent: IRemoteCodingAgent): boolean {
81+
if (!agent.when) {
82+
return true;
83+
}
84+
85+
const whenExpr = ContextKeyExpr.deserialize(agent.when);
86+
return !whenExpr || this.contextKeyService.contextMatchesRules(whenExpr);
87+
}
88+
89+
private updateContextKeys(): void {
90+
const hasAvailableAgent = this.getAvailableAgents().length > 0;
91+
this._ctxHasRemoteCodingAgent.set(hasAvailableAgent);
4792
}
4893
}
4994

0 commit comments

Comments
 (0)