Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add api client support for a4d #137

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@salesforce/vscode-service-provider",
"version": "1.2.1",
"version": "1.3.0-rc.3",
"description": "Library that provides access to Salesforce VSCode Service Provider",
"main": "lib/src/index.js",
"author": "Peter Hale <[email protected]>",
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './types';

export const telemetryCommand = 'sf.vscode.core.get.telemetry';
export const loggerCommand = 'sf.vscode.core.logger.get.instance';
export const aiApiCommand = 'salesforcedx-einstein-gpt.getAiClient';
4 changes: 3 additions & 1 deletion src/services/serviceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
ServiceValidators
} from '../types';
import * as vscode from 'vscode';
import { loggerCommand, telemetryCommand } from '../index';
import { aiApiCommand, loggerCommand, telemetryCommand } from '../index';

/**
* The ServiceProvider class is a utility class that provides services of different types.
Expand Down Expand Up @@ -195,6 +195,8 @@ export class ServiceProvider {
return loggerCommand;
case ServiceType.Telemetry:
return telemetryCommand;
case ServiceType.AiApiClient:
return aiApiCommand;
default:
throw new Error(`Unsupported service type: ${type}`);
}
Expand Down
40 changes: 40 additions & 0 deletions src/types/aiApiClient/Completions/AiCompletion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
export type GenericCompletionType =
| { completion: string }
| { id: string; text: string };

/**
* Represents a Salesforce API completion type.
* @property {string} id - The unique identifier for the completion.
* @property {string} text - The text of the completion.
*/
export type SFApiCompletion = Extract<GenericCompletionType, { id: string }>;

/**
* Represents a code generation completion type.
* @property {string} completion - The completion text.
*/
export type CodeGenCompletion = Extract<
GenericCompletionType,
{ completion: string }
>;

// There are two different APIs we are currently supporting for the GPT response.
// A new conditional type should be created to include future additions.

/**
* Represents a completion type based on the provided generic type.
* @template T
*/
export type CompletionType<T extends SFApiCompletion | CodeGenCompletion> =
T extends SFApiCompletion ? SFApiCompletion : CodeGenCompletion;

/**
* Represents an AI completion type.
*/
export type AiCompletion = CompletionType<SFApiCompletion | CodeGenCompletion>;
36 changes: 36 additions & 0 deletions src/types/aiApiClient/Completions/InlineCompletions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

export type JaccardSnippet = {
file_path: string;
text: string;
similarity: number;
};

/**
* Represents the context for an inline completion request.
* @property {string} current_file_path - The current file path.
* @property {JaccardSnippet[]} windows - The array of Jaccard snippets.
*/
export type InlineCompletionRequestContext = {
current_file_path: string;
windows: JaccardSnippet[];
};

/**
* Represents the inputs for an inline completion request.
* @property {string} prefix - The prefix text for the completion.
* @property {string} suffix - The suffix text for the completion.
* @property {InlineCompletionRequestContext | string} context - The context for the completion request.
* @property {string} promptId - The prompt identifier.
*/
export type InlineCompletionRequestInputs = {
prefix: string;
suffix: string;
context: InlineCompletionRequestContext | string;
promptId: string;
};
27 changes: 27 additions & 0 deletions src/types/aiApiClient/enums/commandSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
export enum CommandSource {
/**
* Command source for natural language to code generation.
*/
NLtoCodeGen = 'NLtoCodeGen',

/**
* Command source for test generation.
*/
TestGen = 'TestGen',

/**
* Command source for inline autocomplete.
*/
InlineAutocomplete = 'InlineAutocomplete',

/**
* Command source for chat.
*/
Chat = 'Chat'
}
14 changes: 14 additions & 0 deletions src/types/aiApiClient/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

export * from './types/PromptStoreEntry';
export * from './types/TelemetryData';
export * from './types/ApiClient';
export * from './enums/commandSource';
export * from './utils/Completion/Completion';
export * from './Completions/AiCompletion';
export * from './Completions/InlineCompletions';
84 changes: 84 additions & 0 deletions src/types/aiApiClient/types/ApiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import {
Actions,
FeedbackCustomContextValues,
Reactions
} from './TelemetryData';
import { CommandSource } from '../enums/commandSource';
import { Completion } from '../utils/Completion/Completion';
import { AiCompletion } from '../index';
import { InlineCompletionRequestInputs } from '../Completions/InlineCompletions';
import { CancellationToken } from 'vscode';

export type LLMRequestBody = {
id: string;
generation_id: string;
feedback: Reactions | null;
feedback_text: string | null;
source: string;
previous_generation_ids?: string[];
app_feedback: {
feedback_detail: {
action: Actions | null;
};
custom_context: Record<string, FeedbackCustomContextValues>;
};
};

/**
* Represents the query parameters for natural language queries.
* @property {string} prefix - The prefix for the query.
* @property {string} suffix - The suffix for the query.
* @property {string} input - The input for the query.
* @property {string} promptId - The prompt identifier.
* @property {CommandSource} commandSource - The source of the command.
*/
export type QueryParams = {
prefix: string;
suffix: string;
input: string;
promptId: string;
commandSource: CommandSource;
};
/**
* Interface for AI API client.
* @interface AiApiClient
* @property {string} blockRestEndpoint - The endpoint for blocking REST requests.
* @property {string} inlineRestEndpoint - The endpoint for inline REST requests.
*/
export interface AiApiClient {
blockRestEndpoint: string;
inlineRestEndpoint: string;

/**
* Executes a natural language query.
* @param queryParams - The query parameters.
* @returns A promise that resolves to an array of completions.
*/
naturalLanguageQuery(
queryParams: QueryParams
): Promise<Completion<AiCompletion>[]>;

/**
* Executes an inline query.
* @param inputs - The inputs for the inline query.
* @param token - The cancellation token.
* @returns A promise that resolves to an array of completions.
*/
inlineQuery(
inputs: InlineCompletionRequestInputs,
token: CancellationToken
): Promise<Completion<AiCompletion>[]>;

/**
* Sends feedback for LLM.
* @param telemetryData - The telemetry data for feedback.
* @returns A promise that resolves when the feedback is sent.
*/
sendLLMFeedback?(telemetryData: LLMRequestBody): Promise<void>;
}
10 changes: 10 additions & 0 deletions src/types/aiApiClient/types/PromptStoreEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
export type SerializedRange = [
{ line: number; character: number },
{ line: number; character: number }
];
47 changes: 47 additions & 0 deletions src/types/aiApiClient/types/TelemetryData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { Uri } from 'vscode';
import { SerializedRange } from './PromptStoreEntry';

export const ReactionToActionMap = {
GOOD: 'thumbs-up',
BAD: 'thumbs-down'
} as const;

export type Reactions = keyof typeof ReactionToActionMap;

const EGPT_ACCEPT_COMMAND = 'accept';
const EGPT_ACCEPT_TEST_COMMAND = 'test';
const EGPT_CLEAR_COMMAND = 'clear';
const EGPT_CLEAR_TEST_COMMAND = 'clear-test';
const EGPT_TEST_COMMAND = 'command-test';
const EGPT_POST_COMPLETION = 'post-completion';
const EGPT_COMMAND = 'command-command';

export const CommandToActionMap = {
[EGPT_ACCEPT_COMMAND]: 'accept',
[EGPT_ACCEPT_TEST_COMMAND]: 'acceptTest',
[EGPT_CLEAR_COMMAND]: 'reject',
[EGPT_CLEAR_TEST_COMMAND]: 'rejectTest',
[EGPT_TEST_COMMAND]: 'test',
[EGPT_POST_COMPLETION]: 'generation-edit',
// command below only maps to a feedback action when it's a retry.
[EGPT_COMMAND]: 'regeneration'
} as const;

export type Commands = keyof typeof CommandToActionMap;
export type Actions =
| (typeof ReactionToActionMap)[Reactions]
| (typeof CommandToActionMap)[Commands];

export type FeedbackCustomContextValues =
| string
| string[]
| Uri
| Date
| SerializedRange
| boolean;
77 changes: 77 additions & 0 deletions src/types/aiApiClient/utils/Completion/Completion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { AiCompletion, CompletionType } from '../../index';

/**
* Interface representing a completion.
* @template T - The type of AI completion.
*/
export type Completion<T extends AiCompletion> = {
new (completion: CompletionType<T>, id?: string): Completion<T>;
/**
* The completion text.
* @type {string}
*/
completion: string;

/**
* The response identifier.
* @type {string | undefined}
*/
responseId?: string;

/**
* The generation identifier.
* @type {string | undefined}
*/
generationId?: string;

/**
* The number of lines in the completion.
* @type {number | undefined}
*/
lineCount: number | undefined;

/**
* The newline character.
* @type {string}
*/
newLineChar: string;

/**
* Adds a trailing newline character to the text.
* @param text - The text to which the newline character is added.
* @returns The text with the trailing newline character.
*/
addTrailingLine(text: string): string;

/**
* Gets the number of lines in the completion.
* @returns The number of lines in the completion.
*/
getLineCount(): number;

/**
* Checks if the text is multiline.
* @param text - The text to check.
* @returns True if the text is multiline, false otherwise.
*/
isMultiline(text: string): boolean;

/**
* Checks if the completion is empty.
* @returns True if the completion is empty, false otherwise.
*/
isEmpty(): boolean;

/**
* Checks if the text is a whitespace string.
* @param text - The text to check.
* @returns True if the text is a whitespace string, false otherwise.
*/
isWhiteSpaceString(text: string): boolean;
};
Loading