Skip to content

Commit cace4df

Browse files
authored
VSCODE-640: Adapt message content access to latest vscode API (#857)
* Adapt message content access to latest vscode API * Address CR comments
1 parent 92a2c0b commit cace4df

File tree

5 files changed

+169
-57
lines changed

5 files changed

+169
-57
lines changed

.vscode/launch.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@
4040
"outFiles": [
4141
"${workspaceFolder}/dist/**/*.js"
4242
]
43+
},
44+
{
45+
"name": "Run Tests",
46+
"type": "extensionHost",
47+
"request": "launch",
48+
"runtimeExecutable": "${execPath}",
49+
"args": [
50+
"${workspaceFolder}/out/test/suite", // TODO: VSCODE-641 - remove suite
51+
"--disable-extensions",
52+
"--extensionDevelopmentPath=${workspaceFolder}",
53+
"--extensionTestsPath=${workspaceFolder}/out/test/suite"
54+
],
55+
"outFiles": ["${workspaceFolder}/out/**/*.js"],
56+
"preLaunchTask": "npm: compile:extension",
4357
}
4458
],
4559
"compounds": [

src/participant/participant.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { LoadedConnection } from '../storage/connectionStorage';
1010
import EXTENSION_COMMANDS from '../commands';
1111
import type { StorageController } from '../storage';
1212
import { StorageVariables } from '../storage';
13-
import { Prompts } from './prompts';
13+
import { getContentLength, Prompts } from './prompts';
1414
import type { ChatResult } from './constants';
1515
import {
1616
askToConnectChatResult,
@@ -189,7 +189,7 @@ export default class ParticipantController {
189189
(message: vscode.LanguageModelChatMessage) =>
190190
util.inspect({
191191
role: message.role,
192-
contentLength: message.content.length,
192+
contentLength: getContentLength(message),
193193
})
194194
),
195195
});
@@ -790,15 +790,18 @@ export default class ParticipantController {
790790
// it currently errors (not on insiders, only main VSCode).
791791
// Here we're defaulting to have some content as a workaround.
792792
// TODO: Remove this when the issue is fixed.
793-
messagesWithNamespace.messages[
794-
messagesWithNamespace.messages.length - 1
795-
// eslint-disable-next-line new-cap
796-
] = vscode.LanguageModelChatMessage.User(
793+
if (
794+
!Prompts.doMessagesContainUserInput([
795+
messagesWithNamespace.messages[
796+
messagesWithNamespace.messages.length - 1
797+
],
798+
])
799+
) {
797800
messagesWithNamespace.messages[
798801
messagesWithNamespace.messages.length - 1
799-
].content.trim() || 'see previous messages'
800-
);
801-
802+
// eslint-disable-next-line new-cap
803+
] = vscode.LanguageModelChatMessage.User('see previous messages');
804+
}
802805
const responseContentWithNamespace = await this.getChatResponseContent({
803806
modelInput: messagesWithNamespace,
804807
token,

src/participant/prompts/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { IntentPrompt } from './intent';
55
import { NamespacePrompt } from './namespace';
66
import { QueryPrompt } from './query';
77
import { SchemaPrompt } from './schema';
8+
import { isContentEmpty } from './promptBase';
9+
10+
export { getContentLength } from './promptBase';
811

912
export class Prompts {
1013
public static generic = new GenericPrompt();
@@ -26,7 +29,7 @@ export class Prompts {
2629
for (const message of messages) {
2730
if (
2831
message.role === vscode.LanguageModelChatMessageRole.User &&
29-
message.content.trim().length > 0
32+
!isContentEmpty(message)
3033
) {
3134
return true;
3235
}

src/participant/prompts/promptBase.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,52 @@ export interface ModelInput {
2424
stats: ParticipantPromptProperties;
2525
}
2626

27+
export function getContentLength(
28+
message: vscode.LanguageModelChatMessage
29+
): number {
30+
const content = message.content as any;
31+
if (typeof content === 'string') {
32+
return content.trim().length;
33+
}
34+
35+
// TODO: https://github.com/microsoft/vscode/pull/231788 made it so message.content is no longer a string,
36+
// but an array of things that a message can contain. This will eventually be reflected in the type definitions
37+
// but until then, we're manually checking the array contents to ensure we don't break when this PR gets released
38+
// in the stable channel.
39+
if (Array.isArray(content)) {
40+
return content.reduce((acc: number, element) => {
41+
const value = element?.value ?? element?.content?.value;
42+
if (typeof value === 'string') {
43+
return acc + value.length;
44+
}
45+
46+
return acc;
47+
}, 0);
48+
}
49+
50+
return 0;
51+
}
52+
53+
export function isContentEmpty(
54+
message: vscode.LanguageModelChatMessage
55+
): boolean {
56+
const content = message.content as any;
57+
if (typeof content === 'string') {
58+
return content.trim().length === 0;
59+
}
60+
61+
if (Array.isArray(content)) {
62+
for (const element of content) {
63+
const value = element?.value ?? element?.content?.value;
64+
if (typeof value === 'string' && value.trim().length > 0) {
65+
return false;
66+
}
67+
}
68+
}
69+
70+
return true;
71+
}
72+
2773
export abstract class PromptBase<TArgs extends PromptArgsBase> {
2874
protected abstract getAssistantPrompt(args: TArgs): string;
2975

@@ -92,7 +138,7 @@ export abstract class PromptBase<TArgs extends PromptArgsBase> {
92138
): ParticipantPromptProperties {
93139
return {
94140
total_message_length: messages.reduce(
95-
(acc, message) => acc + message.content.length,
141+
(acc, message) => acc + getContentLength(message),
96142
0
97143
),
98144
user_input_length: request.prompt.length,

0 commit comments

Comments
 (0)