Skip to content

Commit 1f2bae6

Browse files
authored
Adopt new tool audience and lm data model part (#7399)
* Adopt new tool audience and lm data model part Part of microsoft/vscode#255383 * Reduce version
1 parent 32d37d5 commit 1f2bae6

File tree

5 files changed

+212
-5
lines changed

5 files changed

+212
-5
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929
"contribEditorContentMenu",
3030
"contribShareMenu",
3131
"diffCommand",
32+
"languageModelDataPart",
33+
"languageModelToolResultAudience",
3234
"quickDiffProvider",
3335
"remoteCodingAgents",
3436
"shareProvider",
3537
"tokenInformation",
3638
"treeViewMarkdownMessage"
3739
],
38-
"version": "0.114.0",
40+
"version": "0.116.0",
3941
"publisher": "GitHub",
4042
"engines": {
4143
"vscode": "^1.103.0"
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
// version: 3
7+
8+
declare module 'vscode' {
9+
10+
export interface LanguageModelChat {
11+
sendRequest(messages: Array<LanguageModelChatMessage | LanguageModelChatMessage2>, options?: LanguageModelChatRequestOptions, token?: CancellationToken): Thenable<LanguageModelChatResponse>;
12+
countTokens(text: string | LanguageModelChatMessage | LanguageModelChatMessage2, token?: CancellationToken): Thenable<number>;
13+
}
14+
15+
/**
16+
* Represents a message in a chat. Can assume different roles, like user or assistant.
17+
*/
18+
export class LanguageModelChatMessage2 {
19+
20+
/**
21+
* Utility to create a new user message.
22+
*
23+
* @param content The content of the message.
24+
* @param name The optional name of a user for the message.
25+
*/
26+
static User(content: string | Array<LanguageModelTextPart | LanguageModelToolResultPart2 | LanguageModelDataPart>, name?: string): LanguageModelChatMessage2;
27+
28+
/**
29+
* Utility to create a new assistant message.
30+
*
31+
* @param content The content of the message.
32+
* @param name The optional name of a user for the message.
33+
*/
34+
static Assistant(content: string | Array<LanguageModelTextPart | LanguageModelToolCallPart | LanguageModelDataPart>, name?: string): LanguageModelChatMessage2;
35+
36+
/**
37+
* The role of this message.
38+
*/
39+
role: LanguageModelChatMessageRole;
40+
41+
/**
42+
* A string or heterogeneous array of things that a message can contain as content. Some parts may be message-type
43+
* specific for some models.
44+
*/
45+
content: Array<LanguageModelTextPart | LanguageModelToolResultPart2 | LanguageModelToolCallPart | LanguageModelDataPart>;
46+
47+
/**
48+
* The optional name of a user for this message.
49+
*/
50+
name: string | undefined;
51+
52+
/**
53+
* Create a new user message.
54+
*
55+
* @param role The role of the message.
56+
* @param content The content of the message.
57+
* @param name The optional name of a user for the message.
58+
*/
59+
constructor(role: LanguageModelChatMessageRole, content: string | Array<LanguageModelTextPart | LanguageModelToolResultPart2 | LanguageModelToolCallPart | LanguageModelDataPart>, name?: string);
60+
}
61+
62+
/**
63+
* A language model response part containing arbitrary data, returned from a {@link LanguageModelChatResponse}.
64+
*/
65+
export class LanguageModelDataPart {
66+
/**
67+
* Factory function to create a `LanguageModelDataPart` for an image.
68+
* @param data Binary image data
69+
* @param mimeType The MIME type of the image
70+
*/
71+
// TODO@API just use string, no enum required
72+
static image(data: Uint8Array, mimeType: ChatImageMimeType): LanguageModelDataPart;
73+
74+
static json(value: any, mime?: string): LanguageModelDataPart;
75+
76+
static text(value: string, mime?: string): LanguageModelDataPart;
77+
78+
/**
79+
* The mime type which determines how the data property is interpreted.
80+
*/
81+
mimeType: string;
82+
83+
/**
84+
* The data of the part.
85+
*/
86+
data: Uint8Array;
87+
88+
/**
89+
* Construct a generic data part with the given content.
90+
* @param value The data of the part.
91+
*/
92+
constructor(data: Uint8Array, mimeType: string);
93+
}
94+
95+
/**
96+
* Enum for supported image MIME types.
97+
*/
98+
export enum ChatImageMimeType {
99+
PNG = 'image/png',
100+
JPEG = 'image/jpeg',
101+
GIF = 'image/gif',
102+
WEBP = 'image/webp',
103+
BMP = 'image/bmp',
104+
}
105+
106+
/**
107+
* The result of a tool call. This is the counterpart of a {@link LanguageModelToolCallPart tool call} and
108+
* it can only be included in the content of a User message
109+
*/
110+
export class LanguageModelToolResultPart2 {
111+
/**
112+
* The ID of the tool call.
113+
*
114+
* *Note* that this should match the {@link LanguageModelToolCallPart.callId callId} of a tool call part.
115+
*/
116+
callId: string;
117+
118+
/**
119+
* The value of the tool result.
120+
*/
121+
content: Array<LanguageModelTextPart | LanguageModelPromptTsxPart | LanguageModelDataPart | unknown>;
122+
123+
/**
124+
* @param callId The ID of the tool call.
125+
* @param content The content of the tool result.
126+
*/
127+
constructor(callId: string, content: Array<LanguageModelTextPart | LanguageModelPromptTsxPart | LanguageModelDataPart | unknown>);
128+
}
129+
130+
131+
/**
132+
* A tool that can be invoked by a call to a {@link LanguageModelChat}.
133+
*/
134+
export interface LanguageModelTool<T> {
135+
/**
136+
* Invoke the tool with the given input and return a result.
137+
*
138+
* The provided {@link LanguageModelToolInvocationOptions.input} has been validated against the declared schema.
139+
*/
140+
invoke(options: LanguageModelToolInvocationOptions<T>, token: CancellationToken): ProviderResult<LanguageModelToolResult2>;
141+
}
142+
143+
/**
144+
* A result returned from a tool invocation. If using `@vscode/prompt-tsx`, this result may be rendered using a `ToolResult`.
145+
*/
146+
export class LanguageModelToolResult2 {
147+
/**
148+
* A list of tool result content parts. Includes `unknown` becauses this list may be extended with new content types in
149+
* the future.
150+
* @see {@link lm.invokeTool}.
151+
*/
152+
content: Array<LanguageModelTextPart | LanguageModelPromptTsxPart | LanguageModelDataPart | unknown>;
153+
154+
/**
155+
* Create a LanguageModelToolResult
156+
* @param content A list of tool result content parts
157+
*/
158+
constructor(content: Array<LanguageModelTextPart | LanguageModelPromptTsxPart | LanguageModelDataPart | unknown>);
159+
}
160+
161+
export namespace lm {
162+
export function invokeTool(name: string, options: LanguageModelToolInvocationOptions<object>, token?: CancellationToken): Thenable<LanguageModelToolResult2>;
163+
}
164+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
declare module 'vscode' {
7+
8+
export enum ToolResultAudience {
9+
Assistant = 0,
10+
User = 1,
11+
}
12+
13+
/**
14+
* A language model response part containing a piece of text, returned from a {@link LanguageModelChatResponse}.
15+
*/
16+
export class LanguageModelTextPart2 extends LanguageModelTextPart {
17+
audience: ToolResultAudience[] | undefined;
18+
constructor(value: string, audience?: ToolResultAudience[]);
19+
}
20+
21+
export class LanguageModelDataPart2 extends LanguageModelDataPart {
22+
audience: ToolResultAudience[] | undefined;
23+
constructor(data: Uint8Array, mimeType: string, audience?: ToolResultAudience[]);
24+
}
25+
}

src/github/copilotRemoteAgent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ export class CopilotRemoteAgentManager extends Disposable {
618618
const { pull_request } = await capiClient.postRemoteAgentJob(owner, repo, payload);
619619
this._onDidCreatePullRequest.fire(pull_request.number);
620620
const webviewUri = await toOpenPullRequestWebviewUri({ owner, repo, pullRequestNumber: pull_request.number });
621-
const prLlmString = `The remote agent has begun work. The user can track progress on GitHub.com by visiting ${pull_request.html_url} and within VS Code by visiting ${webviewUri.toString()}. Format all links as markdown (eg: [link text](url)).`;
621+
const prLlmString = `The remote agent has begun work and has created a pull request. Details about the pull request are being shown to the user. If the user wants to track progress or iterate on the agent's work, they should use the pull request.`;
622622
return {
623623
state: 'success',
624624
number: pull_request.number,

src/lm/tools/copilotRemoteAgentTool.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66

77
import * as vscode from 'vscode';
8+
import { COPILOT_ACCOUNTS } from '../../common/comment';
89
import { ITelemetry } from '../../common/telemetry';
10+
import { toOpenPullRequestWebviewUri } from '../../common/uri';
911
import { CopilotRemoteAgentManager } from '../../github/copilotRemoteAgent';
1012
import { FolderRepositoryManager } from '../../github/folderRepositoryManager';
1113

@@ -112,9 +114,23 @@ export class CopilotRemoteAgentTool implements vscode.LanguageModelTool<CopilotR
112114
this.telemetry.sendTelemetryErrorEvent('copilot.remoteAgent.tool.error', { reason: 'invocationError' });
113115
throw new Error(result.error);
114116
}
115-
return new vscode.LanguageModelToolResult([
116-
new vscode.LanguageModelTextPart(result.llmDetails)
117-
]);
117+
118+
let lmResult: (vscode.LanguageModelTextPart | vscode.LanguageModelDataPart)[] = [new vscode.LanguageModelTextPart(result.llmDetails)];
119+
const pr = await targetRepo.fm.resolvePullRequest(targetRepo.owner, targetRepo.repo, result.number);
120+
if (pr) {
121+
const preferredRendering = {
122+
uri: (await toOpenPullRequestWebviewUri({ owner: pr.githubRepository.remote.owner, repo: pr.githubRepository.remote.repositoryName, pullRequestNumber: pr.number })).toString(),
123+
title: pr.title,
124+
description: pr.body,
125+
author: COPILOT_ACCOUNTS[pr.author.login].name,
126+
linkTag: `#${pr.number}`
127+
};
128+
const buffer: Buffer = Buffer.from(JSON.stringify(preferredRendering));
129+
const data: Uint8Array = Uint8Array.from(buffer);
130+
lmResult.push(new vscode.LanguageModelDataPart2(data, 'application/pull-request+json', [vscode.ToolResultAudience.User]));
131+
}
132+
133+
return new vscode.LanguageModelToolResult2(lmResult);
118134
}
119135

120136
private async getActivePullRequestWithSession(repoInfo: { repo: string; owner: string; fm: FolderRepositoryManager } | undefined): Promise<number | undefined> {

0 commit comments

Comments
 (0)