Merge pull request #211300 from microsoft/roblou/corporate-mammal

Fix broken chat layout after reloading window
This commit is contained in:
Rob Lourens 2024-04-25 08:39:52 -07:00 committed by GitHub
commit 91588fbb30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 59 additions and 29 deletions

View file

@ -138,7 +138,8 @@ export class MainThreadChatAgents2 extends Disposable implements MainThreadChatA
description: dynamicProps.description,
extensionId: extension,
extensionDisplayName: extensionDescription?.displayName ?? extension.value,
extensionPublisher: extensionDescription?.publisherDisplayName ?? extension.value,
extensionPublisherId: extensionDescription?.publisher ?? '', // extensionDescription _should_ be present at this point, since this extension is active and registering agents
extensionPublisherDisplayName: extensionDescription?.publisherDisplayName,
metadata: revive(metadata),
slashCommands: [],
locations: [ChatAgentLocation.Panel] // TODO all dynamic participants are panel only?

View file

@ -108,7 +108,7 @@ export class ChatAgentHover extends Disposable {
this.name.textContent = `@${agent.name}`;
this.extensionName.textContent = agent.extensionDisplayName;
this.publisherName.textContent = agent.extensionPublisher;
this.publisherName.textContent = agent.extensionPublisherDisplayName ?? agent.extensionPublisherId;
const description = agent.description && !agent.description.endsWith('.') ?
`${agent.description}. ` :

View file

@ -42,7 +42,7 @@ export class ChatMarkdownDecorationsRenderer {
let text = part.text;
const isDupe = this.chatAgentService.getAgentsByName(part.agent.name).length > 1;
if (isDupe) {
text += ` (${part.agent.extensionPublisher})`;
text += ` (${part.agent.extensionPublisherDisplayName})`;
}
result += `[${text}](${agentRefUrl}?${encodeURIComponent(part.agent.id)})`;

View file

@ -202,7 +202,8 @@ export class ChatExtensionPointHandler implements IWorkbenchContribution {
providerDescriptor.id,
{
extensionId: extension.description.identifier,
extensionPublisher: extension.description.publisherDisplayName ?? extension.description.publisher, // May not be present in OSS
extensionPublisherDisplayName: extension.description.publisherDisplayName ?? extension.description.publisher, // May not be present in OSS
extensionPublisherId: extension.description.publisher,
extensionDisplayName: extension.description.displayName ?? extension.description.name,
id: providerDescriptor.id,
description: providerDescriptor.description,

View file

@ -213,7 +213,7 @@ class InputEditorDecorations extends Disposable {
const textDecorations: IDecorationOptions[] | undefined = [];
if (agentPart) {
const isDupe = !!this.chatAgentService.getAgents().find(other => other.name === agentPart.agent.name && other.id !== agentPart.agent.id);
const publisher = isDupe ? `(${agentPart.agent.extensionPublisher}) ` : '';
const publisher = isDupe ? `(${agentPart.agent.extensionPublisherDisplayName}) ` : '';
const agentHover = `${publisher}${agentPart.agent.description}`;
textDecorations.push({ range: agentPart.editorRange, hoverMessage: new MarkdownString(agentHover) });
if (agentSubcommandPart) {
@ -361,7 +361,7 @@ class AgentCompletions extends Disposable {
return <CompletionItem>{
// Leading space is important because detail has no space at the start by design
label: isDupe ?
{ label: withAt, description: a.description, detail: ` (${a.extensionPublisher})` } :
{ label: withAt, description: a.description, detail: ` (${a.extensionPublisherDisplayName})` } :
withAt,
insertText: `${withAt} `,
detail: a.description,
@ -452,7 +452,7 @@ class AgentCompletions extends Disposable {
return {
label: isDupe ?
{ label: agentLabel, description: agent.description, detail: ` (${agent.extensionPublisher})` } :
{ label: agentLabel, description: agent.description, detail: ` (${agent.extensionPublisherDisplayName})` } :
agentLabel,
detail,
filterText: `${chatSubcommandLeader}${agent.name}`,

View file

@ -59,7 +59,8 @@ export interface IChatAgentData {
name: string;
description?: string;
extensionId: ExtensionIdentifier;
extensionPublisher: string;
extensionPublisherId: string;
extensionPublisherDisplayName?: string;
extensionDisplayName: string;
/** The agent invoked when no agent is specified */
isDefault?: boolean;
@ -325,7 +326,8 @@ export class MergedChatAgent implements IChatAgent {
get name(): string { return this.data.name ?? ''; }
get description(): string { return this.data.description ?? ''; }
get extensionId(): ExtensionIdentifier { return this.data.extensionId; }
get extensionPublisher(): string { return this.data.extensionPublisher; }
get extensionPublisherId(): string { return this.data.extensionPublisherId; }
get extensionPublisherDisplayName() { return this.data.extensionPublisherDisplayName; }
get extensionDisplayName(): string { return this.data.extensionDisplayName; }
get isDefault(): boolean | undefined { return this.data.isDefault; }
get metadata(): IChatAgentMetadata { return this.data.metadata; }
@ -445,7 +447,7 @@ export class ChatAgentNameService implements IChatAgentNameService {
return true;
}
return allowList.some(id => equalsIgnoreCase(id, id.includes('.') ? chatAgentData.extensionId.value : chatAgentData.extensionPublisher));
return allowList.some(id => equalsIgnoreCase(id, id.includes('.') ? chatAgentData.extensionId.value : chatAgentData.extensionPublisherId));
});
}

View file

@ -672,6 +672,16 @@ export class ChatModel extends Disposable implements IChatModel {
...(raw as any),
name: (raw as any).id,
};
// Fill in required fields that may be missing from old data
if (!('extensionPublisherId' in agent)) {
agent.extensionPublisherId = agent.extensionPublisher ?? '';
}
if (!('extensionDisplayName' in agent)) {
agent.extensionDisplayName = '';
}
return revive(agent);
}
@ -847,7 +857,7 @@ export class ChatModel extends Disposable implements IChatModel {
followups: r.response?.followups,
isCanceled: r.response?.isCanceled,
vote: r.response?.vote,
agent: r.response?.agent,
agent: r.response?.agent ? { ...r.response.agent } : undefined,
slashCommand: r.response?.slashCommand,
usedContext: r.response?.usedContext,
contentReferences: r.response?.contentReferences

View file

@ -32,8 +32,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -32,8 +32,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -18,8 +18,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -18,8 +18,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -18,8 +18,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -18,8 +18,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -18,8 +18,9 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
metadata: { },
slashCommands: [

View file

@ -28,7 +28,8 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherId: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
metadata: { },
@ -65,7 +66,8 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherId: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
metadata: { },

View file

@ -27,7 +27,8 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherId: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
metadata: {
@ -68,7 +69,8 @@
value: "nullExtensionDescription",
_lower: "nullextensiondescription"
},
extensionPublisher: "",
extensionPublisherId: "",
extensionPublisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
metadata: {

View file

@ -115,7 +115,7 @@ suite('ChatRequestParser', () => {
});
const getAgentWithSlashCommands = (slashCommands: IChatAgentCommand[]) => {
return { id: 'agent', name: 'agent', extensionId: nullExtensionDescription.identifier, extensionPublisher: '', extensionDisplayName: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands } satisfies IChatAgentData;
return { id: 'agent', name: 'agent', extensionId: nullExtensionDescription.identifier, extensionPublisherDisplayName: '', extensionDisplayName: '', extensionPublisherId: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands } satisfies IChatAgentData;
};
test('agent with subcommand after text', async () => {

View file

@ -35,7 +35,8 @@ const chatAgentWithUsedContext: IChatAgent = {
id: chatAgentWithUsedContextId,
name: chatAgentWithUsedContextId,
extensionId: nullExtensionDescription.identifier,
extensionPublisher: '',
extensionPublisherDisplayName: '',
extensionPublisherId: '',
extensionDisplayName: '',
locations: [ChatAgentLocation.Panel],
metadata: {},
@ -91,8 +92,8 @@ suite('ChatService', () => {
return {};
},
} satisfies IChatAgentImplementation;
testDisposables.add(chatAgentService.registerAgent('testAgent', { name: 'testAgent', id: 'testAgent', isDefault: true, extensionId: nullExtensionDescription.identifier, extensionPublisher: '', extensionDisplayName: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands: [] }));
testDisposables.add(chatAgentService.registerAgent(chatAgentWithUsedContextId, { name: chatAgentWithUsedContextId, id: chatAgentWithUsedContextId, extensionId: nullExtensionDescription.identifier, extensionPublisher: '', extensionDisplayName: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands: [] }));
testDisposables.add(chatAgentService.registerAgent('testAgent', { name: 'testAgent', id: 'testAgent', isDefault: true, extensionId: nullExtensionDescription.identifier, extensionPublisherId: '', extensionPublisherDisplayName: '', extensionDisplayName: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands: [] }));
testDisposables.add(chatAgentService.registerAgent(chatAgentWithUsedContextId, { name: chatAgentWithUsedContextId, id: chatAgentWithUsedContextId, extensionId: nullExtensionDescription.identifier, extensionPublisherId: '', extensionPublisherDisplayName: '', extensionDisplayName: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands: [] }));
testDisposables.add(chatAgentService.registerAgentImplementation('testAgent', agent));
chatAgentService.updateAgent('testAgent', { requester: { name: 'test' }, fullName: 'test' });
});

View file

@ -29,6 +29,7 @@ suite('VoiceChat', () => {
extensionId: ExtensionIdentifier = nullExtensionDescription.identifier;
extensionPublisher = '';
extensionDisplayName = '';
extensionPublisherId = '';
locations: ChatAgentLocation[] = [ChatAgentLocation.Panel];
public readonly name: string;
constructor(readonly id: string, readonly slashCommands: IChatAgentCommand[]) {

View file

@ -318,8 +318,9 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService {
id: _bridgeAgentId,
name: 'editor',
extensionId: nullExtensionDescription.identifier,
extensionPublisher: '',
extensionPublisherDisplayName: '',
extensionDisplayName: '',
extensionPublisherId: '',
isDefault: true,
locations: [ChatAgentLocation.Editor],
get slashCommands(): IChatAgentCommand[] {

View file

@ -180,8 +180,9 @@ suite('InteractiveChatController', function () {
store.add(chatAgentService.registerDynamicAgent({
extensionId: nullExtensionDescription.identifier,
extensionPublisher: '',
extensionPublisherDisplayName: '',
extensionDisplayName: '',
extensionPublisherId: '',
id: 'testAgent',
name: 'testAgent',
isDefault: true,

View file

@ -127,8 +127,9 @@ suite('InlineChatSession', function () {
instaService.get(IChatAgentService).registerDynamicAgent({
extensionId: nullExtensionDescription.identifier,
extensionPublisher: '',
extensionPublisherDisplayName: '',
extensionDisplayName: '',
extensionPublisherId: '',
id: 'testAgent',
name: 'testAgent',
isDefault: true,