Enable two participants with the same name from the same extension, in different locations (#214535)

For #214479
This commit is contained in:
Rob Lourens 2024-06-06 18:19:33 -07:00 committed by GitHub
parent bf11c6cd52
commit f89375854f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 23 additions and 12 deletions

View file

@ -42,7 +42,7 @@ export function agentToMarkdown(agent: IChatAgentData, isClickable: boolean, acc
const isAllowed = chatAgentNameService.getAgentNameRestriction(agent);
let name = `${isAllowed ? agent.name : getFullyQualifiedId(agent)}`;
const isDupe = isAllowed && chatAgentService.getAgentsByName(agent.name).length > 1;
const isDupe = isAllowed && chatAgentService.agentHasDupeName(agent.id);
if (isDupe) {
name += ` (${agent.publisherDisplayName})`;
}

View file

@ -117,7 +117,7 @@ class AgentCompletions extends Disposable {
return {
suggestions: agents.map((agent, i): CompletionItem => {
const { label: agentLabel, isDupe } = getAgentCompletionDetails(agent, agents, this.chatAgentNameService);
const { label: agentLabel, isDupe } = this.getAgentCompletionDetails(agent);
return {
// Leading space is important because detail has no space at the start by design
label: isDupe ?
@ -216,7 +216,7 @@ class AgentCompletions extends Disposable {
const justAgents: CompletionItem[] = agents
.filter(a => !a.isDefault)
.map(agent => {
const { label: agentLabel, isDupe } = getAgentCompletionDetails(agent, agents, this.chatAgentNameService);
const { label: agentLabel, isDupe } = this.getAgentCompletionDetails(agent);
const detail = agent.description;
return {
@ -236,7 +236,7 @@ class AgentCompletions extends Disposable {
return {
suggestions: justAgents.concat(
agents.flatMap(agent => agent.slashCommands.map((c, i) => {
const { label: agentLabel, isDupe } = getAgentCompletionDetails(agent, agents, this.chatAgentNameService);
const { label: agentLabel, isDupe } = this.getAgentCompletionDetails(agent);
const withSlash = `${chatSubcommandLeader}${c.name}`;
return {
label: { label: withSlash, description: agentLabel, detail: isDupe ? ` (${agent.publisherDisplayName})` : undefined },
@ -254,6 +254,13 @@ class AgentCompletions extends Disposable {
}
}));
}
private getAgentCompletionDetails(agent: IChatAgentData): { label: string; isDupe: boolean } {
const isAllowed = this.chatAgentNameService.getAgentNameRestriction(agent);
const agentLabel = `${chatAgentLeader}${isAllowed ? agent.name : getFullyQualifiedId(agent)}`;
const isDupe = isAllowed && this.chatAgentService.agentHasDupeName(agent.id);
return { label: agentLabel, isDupe };
}
}
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(AgentCompletions, LifecyclePhase.Eventually);
@ -401,11 +408,3 @@ class VariableCompletions extends Disposable {
}
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(VariableCompletions, LifecyclePhase.Eventually);
function getAgentCompletionDetails(agent: IChatAgentData, otherAgents: IChatAgentData[], chatAgentNameService: IChatAgentNameService): { label: string; isDupe: boolean } {
const isAllowed = chatAgentNameService.getAgentNameRestriction(agent);
const agentLabel = `${chatAgentLeader}${isAllowed ? agent.name : getFullyQualifiedId(agent)}`;
const isDupe = isAllowed && !!otherAgents.find(other => other.name === agent.name && other.id !== agent.id);
return { label: agentLabel, isDupe };
}

View file

@ -174,6 +174,7 @@ export interface IChatAgentService {
getAgents(): IChatAgentData[];
getActivatedAgents(): Array<IChatAgent>;
getAgentsByName(name: string): IChatAgentData[];
agentHasDupeName(id: string): boolean;
/**
* Get the default agent (only if activated)
@ -345,6 +346,16 @@ export class ChatAgentService implements IChatAgentService {
return this.getAgents().filter(a => a.name === name);
}
agentHasDupeName(id: string): boolean {
const agent = this.getAgent(id);
if (!agent) {
return false;
}
return this.getAgentsByName(agent.name)
.filter(a => a.extensionId.value !== agent.extensionId.value).length > 0;
}
async invokeAgent(id: string, request: IChatAgentRequest, progress: (part: IChatProgress) => void, history: IChatAgentHistoryEntry[], token: CancellationToken): Promise<IChatAgentResult> {
const data = this._agents.get(id);
if (!data?.impl) {

View file

@ -70,6 +70,7 @@ suite('VoiceChat', () => {
getAgentByFullyQualifiedId(id: string): IChatAgentData | undefined { throw new Error('Method not implemented.'); }
registerAgentCompletionProvider(id: string, provider: (query: string, token: CancellationToken) => Promise<IChatAgentCompletionItem[]>): IDisposable { throw new Error('Method not implemented.'); }
getAgentCompletionItems(id: string, query: string, token: CancellationToken): Promise<IChatAgentCompletionItem[]> { throw new Error('Method not implemented.'); }
agentHasDupeName(id: string): boolean { throw new Error('Method not implemented.'); }
}
class TestSpeechService implements ISpeechService {