Skip to content

Commit

Permalink
fix(agent&vscode): fix dynamic features registration. (#3359)
Browse files Browse the repository at this point in the history
  • Loading branch information
icycodes authored Nov 1, 2024
1 parent fe9748b commit 6ce2bb9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 86 deletions.
28 changes: 8 additions & 20 deletions clients/tabby-agent/src/chat/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { Connection } from "vscode-languageserver";
import type { Connection, Disposable } from "vscode-languageserver";
import type { ServerCapabilities } from "../protocol";
import type { Feature } from "../feature";
import type { TabbyApiClient } from "../http/tabbyApiClient";
import { RegistrationRequest, UnregistrationRequest } from "vscode-languageserver";
import { ChatFeatureRegistration } from "../protocol";
import { ChatFeatures } from "../protocol";

export class ChatFeature implements Feature {
private featureRegistration: Disposable | undefined = undefined;

constructor(private readonly tabbyApiClient: TabbyApiClient) {}

initialize(): ServerCapabilities {
Expand All @@ -20,24 +21,11 @@ export class ChatFeature implements Feature {
}

private async syncFeatureRegistration(connection: Connection) {
if (this.tabbyApiClient.isChatApiAvailable()) {
connection.sendRequest(RegistrationRequest.type, {
registrations: [
{
id: ChatFeatureRegistration.type.method,
method: ChatFeatureRegistration.type.method,
},
],
});
if (this.tabbyApiClient.isChatApiAvailable() && !this.featureRegistration) {
this.featureRegistration = await connection.client.register(ChatFeatures.type);
} else {
connection.sendRequest(UnregistrationRequest.type, {
unregisterations: [
{
id: ChatFeatureRegistration.type.method,
method: ChatFeatureRegistration.type.method,
},
],
});
this.featureRegistration?.dispose();
this.featureRegistration = undefined;
}
}
}
90 changes: 41 additions & 49 deletions clients/tabby-agent/src/codeCompletion/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import type {
Connection,
CancellationToken,
Disposable,
Position,
Range,
Location,
NotebookDocuments,
NotebookDocument,
NotebookCell,
CompletionParams,
CompletionOptions,
InlineCompletionParams,
TextDocumentPositionParams,
} from "vscode-languageserver";
Expand All @@ -20,17 +22,14 @@ import type { TabbyApiClient } from "../http/tabbyApiClient";
import type { GitContextProvider } from "../git";
import type { RecentlyChangedCodeSearch } from "../codeSearch/recentlyChanged";
import {
RegistrationRequest,
UnregistrationRequest,
CompletionRequest as LspCompletionRequest,
CompletionTriggerKind,
InlineCompletionTriggerKind,
CompletionItemKind,
} from "vscode-languageserver";
import {
ClientCapabilities,
ServerCapabilities,
TextDocumentCompletionFeatureRegistration,
TextDocumentInlineCompletionFeatureRegistration,
CompletionList,
CompletionItem as LspCompletionItem,
InlineCompletionRequest,
Expand Down Expand Up @@ -71,6 +70,10 @@ export class CompletionProvider implements Feature {
private lspConnection: Connection | undefined = undefined;
private clientCapabilities: ClientCapabilities | undefined = undefined;

private completionFeatureOptions: CompletionOptions | undefined = undefined;
private completionFeatureRegistration: Disposable | undefined = undefined;
private inlineCompletionFeatureRegistration: Disposable | undefined = undefined;

private mutexAbortController: AbortController | undefined = undefined;

constructor(
Expand All @@ -93,19 +96,29 @@ export class CompletionProvider implements Feature {
connection.onCompletion(async (params, token) => {
return this.provideCompletion(params, token);
});
serverCapabilities = {
...serverCapabilities,
completionProvider: {},
this.completionFeatureOptions = {
resolveProvider: false,
completionItem: {
labelDetailsSupport: true,
},
};
if (!clientCapabilities.textDocument?.completion.dynamicRegistration) {
serverCapabilities = {
...serverCapabilities,
completionProvider: this.completionFeatureOptions,
};
}
}
if (clientCapabilities.textDocument?.inlineCompletion) {
connection.onRequest(InlineCompletionRequest.type, async (params, token) => {
return this.provideInlineCompletion(params, token);
});
serverCapabilities = {
...serverCapabilities,
inlineCompletionProvider: true,
};
if (!clientCapabilities.textDocument?.inlineCompletion.dynamicRegistration) {
serverCapabilities = {
...serverCapabilities,
inlineCompletionProvider: true,
};
}
}
connection.onNotification(TelemetryEventNotification.type, async (param) => {
return this.postEvent(param);
Expand All @@ -128,47 +141,26 @@ export class CompletionProvider implements Feature {

private async syncFeatureRegistration(connection: Connection) {
if (this.tabbyApiClient.isCodeCompletionApiAvailable()) {
if (this.clientCapabilities?.textDocument?.completion) {
connection.sendRequest(RegistrationRequest.type, {
registrations: [
{
id: TextDocumentCompletionFeatureRegistration.type.method,
method: TextDocumentCompletionFeatureRegistration.type.method,
},
],
});
if (
this.clientCapabilities?.textDocument?.completion?.dynamicRegistration &&
!this.completionFeatureRegistration
) {
this.completionFeatureRegistration = await connection.client.register(
LspCompletionRequest.type,
this.completionFeatureOptions,
);
}
if (this.clientCapabilities?.textDocument?.inlineCompletion) {
connection.sendRequest(RegistrationRequest.type, {
registrations: [
{
id: TextDocumentInlineCompletionFeatureRegistration.type.method,
method: TextDocumentInlineCompletionFeatureRegistration.type.method,
},
],
});
if (
this.clientCapabilities?.textDocument?.inlineCompletion?.dynamicRegistration &&
!this.inlineCompletionFeatureRegistration
) {
this.inlineCompletionFeatureRegistration = await connection.client.register(InlineCompletionRequest.type);
}
} else {
if (this.clientCapabilities?.textDocument?.completion) {
connection.sendRequest(UnregistrationRequest.type, {
unregisterations: [
{
id: TextDocumentCompletionFeatureRegistration.type.method,
method: TextDocumentCompletionFeatureRegistration.type.method,
},
],
});
}
if (this.clientCapabilities?.textDocument?.inlineCompletion) {
connection.sendRequest(UnregistrationRequest.type, {
unregisterations: [
{
id: TextDocumentInlineCompletionFeatureRegistration.type.method,
method: TextDocumentInlineCompletionFeatureRegistration.type.method,
},
],
});
}
this.completionFeatureRegistration?.dispose();
this.completionFeatureRegistration = undefined;
this.inlineCompletionFeatureRegistration?.dispose();
this.inlineCompletionFeatureRegistration = undefined;
}
}

Expand Down
12 changes: 2 additions & 10 deletions clients/tabby-agent/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,8 @@ export type ServerCapabilities = LspServerCapabilities & {
};
};

export namespace TextDocumentCompletionFeatureRegistration {
export const type = new RegistrationType("textDocument/completion");
}

export namespace TextDocumentInlineCompletionFeatureRegistration {
export const type = new RegistrationType("textDocument/inlineCompletion");
}

export namespace ChatFeatureRegistration {
export const type = new RegistrationType("tabby/chat");
export namespace ChatFeatures {
export const type = new RegistrationType<void>("tabby/chat");
}

/**
Expand Down
11 changes: 4 additions & 7 deletions clients/vscode/src/lsp/ChatFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { EventEmitter } from "events";
import { Disposable, CancellationToken } from "vscode";
import { BaseLanguageClient, DynamicFeature, FeatureState, RegistrationData } from "vscode-languageclient";
import {
ServerCapabilities,
ChatFeatureRegistration,
ChatFeatures,
GenerateCommitMessageRequest,
GenerateCommitMessageParams,
GenerateCommitMessageResult,
Expand All @@ -27,7 +26,7 @@ export class ChatFeature extends EventEmitter implements DynamicFeature<unknown>
super();
}

readonly registrationType = ChatFeatureRegistration.type;
readonly registrationType = ChatFeatures.type;

getState(): FeatureState {
return { kind: "workspace", id: this.registrationType.method, registrations: this.isAvailable };
Expand All @@ -45,10 +44,8 @@ export class ChatFeature extends EventEmitter implements DynamicFeature<unknown>
// nothing
}

initialize(capabilities: ServerCapabilities): void {
if (capabilities.tabby?.chat) {
this.register({ id: this.registrationType.method, registerOptions: {} });
}
initialize(): void {
// nothing
}

register(data: RegistrationData<unknown>): void {
Expand Down

0 comments on commit 6ce2bb9

Please sign in to comment.