Skip to content

Commit

Permalink
[vscode] Stub Chat and Language Model API (#13778)
Browse files Browse the repository at this point in the history
Stub Chat and Language Model API

fixes #13756

contributed on behalf of STMicroelectronics

Signed-off-by: Remi Schnekenburger <[email protected]>
  • Loading branch information
rschnekenbu authored Jun 25, 2024
1 parent 1a5d8d8 commit b16f49b
Show file tree
Hide file tree
Showing 5 changed files with 1,033 additions and 5 deletions.
49 changes: 46 additions & 3 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import type * as theia from '@theia/plugin';
import { CommandRegistryImpl } from './command-registry';
import { Emitter } from '@theia/core/lib/common/event';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { CancellationError, CancellationToken, CancellationTokenSource } from '@theia/core/lib/common/cancellation';
import { QuickOpenExtImpl } from './quick-open';
import {
Expand Down Expand Up @@ -211,7 +211,19 @@ import {
DeclarationCoverage,
FileCoverage,
StatementCoverage,
TestCoverageCount
TestCoverageCount,
ChatRequestTurn,
ChatResponseTurn,
ChatResponseAnchorPart,
ChatResponseCommandButtonPart,
ChatResponseFileTreePart,
ChatResponseMarkdownPart,
ChatResponseProgressPart,
ChatResponseReferencePart,
ChatResultFeedbackKind,
LanguageModelChatMessage,
LanguageModelChatMessageRole,
LanguageModelError
} from './types-impl';
import { AuthenticationExtImpl } from './authentication-ext';
import { SymbolKind } from '../common/plugin-api-rpc-model';
Expand Down Expand Up @@ -1223,9 +1235,27 @@ export function createAPIFactory(
/** @stubbed MappedEditsProvider */
registerMappedEditsProvider(documentSelector: theia.DocumentSelector, provider: theia.MappedEditsProvider): Disposable {
return Disposable.NULL;
},
/** @stubbed ChatRequestHandler */
createChatParticipant(id: string, handler: theia.ChatRequestHandler): theia.ChatParticipant {
return {
id,
requestHandler: handler,
dispose() {},
onDidReceiveFeedback: (listener, thisArgs?, disposables?) => Event.None(listener, thisArgs, disposables)
};
}
};

const lm: typeof theia.lm = {
/** @stubbed LanguageModelChat */
selectChatModels(selector?: theia.LanguageModelChatSelector): Thenable<theia.LanguageModelChat[]> {
return Promise.resolve([]);
},
/** @stubbed LanguageModelChat */
onDidChangeChatModels: (listener, thisArgs?, disposables?) => Event.None(listener, thisArgs, disposables)
};

return <typeof theia>{
version: require('../../package.json').version,
authentication,
Expand All @@ -1244,6 +1274,7 @@ export function createAPIFactory(
notebooks,
l10n,
tests,
lm,
// Types
StatusBarAlignment: StatusBarAlignment,
Disposable: Disposable,
Expand Down Expand Up @@ -1426,7 +1457,19 @@ export function createAPIFactory(
DeclarationCoverage,
FileCoverage,
StatementCoverage,
TestCoverageCount
TestCoverageCount,
ChatRequestTurn,
ChatResponseTurn,
ChatResponseAnchorPart,
ChatResponseCommandButtonPart,
ChatResponseFileTreePart,
ChatResponseMarkdownPart,
ChatResponseProgressPart,
ChatResponseReferencePart,
ChatResultFeedbackKind,
LanguageModelChatMessage,
LanguageModelChatMessageRole,
LanguageModelError
};
};
}
Expand Down
11 changes: 9 additions & 2 deletions packages/plugin-ext/src/plugin/plugin-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { PreferenceRegistryExtImpl } from './preference-registry';
import { InternalStorageExt, Memento, GlobalState } from './plugin-storage';
import { ExtPluginApi } from '../common/plugin-ext-api-contribution';
import { RPCProtocol } from '../common/rpc-protocol';
import { Emitter } from '@theia/core/lib/common/event';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { WebviewsExtImpl } from './webviews';
import { URI as Uri } from './types-impl';
import { InternalSecretsExt, SecretStorageExt } from '../plugin/secrets-ext';
Expand Down Expand Up @@ -391,7 +391,14 @@ export abstract class AbstractPluginManagerExtImpl<P extends Record<string, any>
environmentVariableCollection: this.terminalService.getEnvironmentVariableCollection(plugin.model.id),
extensionMode: extensionModeValue,
extension,
logUri: Uri.file(logPath)
logUri: Uri.file(logPath),
languageModelAccessInformation: {
/** @stubbed LanguageModelChat */
onDidChange: (listener, thisArgs?, disposables?) => Event.None(listener, thisArgs, disposables),
canSendRequest(chat: theia.LanguageModelChat): boolean | undefined {
return undefined;
}
}
};
this.pluginContextsMap.set(plugin.model.id, pluginContext);

Expand Down
112 changes: 112 additions & 0 deletions packages/plugin-ext/src/plugin/types-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3846,3 +3846,115 @@ export class TerminalQuickFixOpener {
constructor(uri: theia.Uri) { }
}

// #region Chat
export class ChatRequestTurn {
readonly prompt: string;
readonly participant: string;
readonly command?: string;
readonly references: theia.ChatPromptReference[];
private constructor(prompt: string, command: string | undefined, references: theia.ChatPromptReference[], participant: string) {
this.prompt = prompt;
this.command = command;
this.participant = participant;
this.references = references;
};
}

export class ChatResponseTurn {
readonly command?: string;

private constructor(readonly response: ReadonlyArray<theia.ChatResponseMarkdownPart | theia.ChatResponseFileTreePart | theia.ChatResponseAnchorPart
| theia.ChatResponseCommandButtonPart>, readonly result: theia.ChatResult, readonly participant: string) { }
}

export class ChatResponseAnchorPart {
value: URI | Location;
title?: string;

constructor(value: URI | Location, title?: string) { }
}

export class ChatResponseProgressPart {
value: string;

constructor(value: string) { }
}

export class ChatResponseReferencePart {
value: URI | Location;
iconPath?: URI | ThemeIcon | { light: URI; dark: URI; };

constructor(value: URI | theia.Location, iconPath?: URI | ThemeIcon | {
light: URI;
dark: URI;
}) { }
}
export class ChatResponseCommandButtonPart {
value: theia.Command;

constructor(value: theia.Command) { }
}

export class ChatResponseMarkdownPart {
value: theia.MarkdownString;

constructor(value: string | theia.MarkdownString) {
}
}

export class ChatResponseFileTreePart {
value: theia.ChatResponseFileTree[];
baseUri: URI;

constructor(value: theia.ChatResponseFileTree[], baseUri: URI) { }
}

export type ChatResponsePart = ChatResponseMarkdownPart | ChatResponseFileTreePart | ChatResponseAnchorPart
| ChatResponseProgressPart | ChatResponseReferencePart | ChatResponseCommandButtonPart;

export enum ChatResultFeedbackKind {
Unhelpful = 0,
Helpful = 1,
}

export enum LanguageModelChatMessageRole {
User = 1,
Assistant = 2
}

export class LanguageModelChatMessage {

static User(content: string, name?: string): LanguageModelChatMessage {
return new LanguageModelChatMessage(LanguageModelChatMessageRole.User, content, name);
}

static Assistant(content: string, name?: string): LanguageModelChatMessage {
return new LanguageModelChatMessage(LanguageModelChatMessageRole.Assistant, content, name);
}

constructor(public role: LanguageModelChatMessageRole, public content: string, public name?: string) { }
}

export class LanguageModelError extends Error {

static NoPermissions(message?: string): LanguageModelError {
return new LanguageModelError(message, LanguageModelError.NoPermissions.name);
}

static Blocked(message?: string): LanguageModelError {
return new LanguageModelError(message, LanguageModelError.Blocked.name);
}

static NotFound(message?: string): LanguageModelError {
return new LanguageModelError(message, LanguageModelError.NotFound.name);
}

readonly code: string;

constructor(message?: string, code?: string) {
super(message);
this.name = 'LanguageModelError';
this.code = code ?? '';
}
}
// #endregion
7 changes: 7 additions & 0 deletions packages/plugin/src/theia-extra.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@ export module '@theia/plugin' {
* see - workspace.fs for how to read and write files and folders from an uri.
*/
readonly logUri: Uri;

/**
* An object that keeps information about how this extension can use language models.
*
* @see {@link LanguageModelChat.sendRequest}
*/
readonly languageModelAccessInformation: LanguageModelAccessInformation;
}

export namespace commands {
Expand Down
Loading

0 comments on commit b16f49b

Please sign in to comment.