Skip to content
Merged
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
12 changes: 12 additions & 0 deletions extensions/ql-vscode/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,10 @@ const LLM_GENERATION_BATCH_SIZE = new Setting(
"llmGenerationBatchSize",
MODEL_SETTING,
);
const LLM_GENERATION_DEV_ENDPOINT = new Setting(
"llmGenerationDevEndpoint",
MODEL_SETTING,
);
const EXTENSIONS_DIRECTORY = new Setting("extensionsDirectory", MODEL_SETTING);
const ENABLE_RUBY = new Setting("enableRuby", MODEL_SETTING);

Expand Down Expand Up @@ -738,6 +742,14 @@ export class ModelConfigListener extends ConfigListener implements ModelConfig {
return LLM_GENERATION_BATCH_SIZE.getValue<number | null>() || 10;
}

/**
* The URL of the endpoint to use for LLM generation. This should only be set
* if you want to test against a dev server.
*/
public get llmGenerationDevEndpoint(): string | undefined {
return LLM_GENERATION_DEV_ENDPOINT.getValue<string | undefined>();
}

public getExtensionsDirectory(languageId: string): string | undefined {
return EXTENSIONS_DIRECTORY.getValue<string>({
languageId,
Expand Down
45 changes: 38 additions & 7 deletions extensions/ql-vscode/src/model-editor/auto-model-api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Credentials } from "../common/authentication";
import { OctokitResponse } from "@octokit/types";
import fetch from "node-fetch";
import { ModelConfigListener } from "../config";

export enum AutomodelMode {
Unspecified = "AUTOMODEL_MODE_UNSPECIFIED",
Expand All @@ -20,15 +22,44 @@ export interface ModelResponse {
export async function autoModel(
credentials: Credentials,
request: ModelRequest,
modelingConfig: ModelConfigListener,
): Promise<ModelResponse> {
const octokit = await credentials.getOctokit();
const devEndpoint = modelingConfig.llmGenerationDevEndpoint;
if (devEndpoint) {
return callAutoModelDevEndpoint(devEndpoint, request);
} else {
const octokit = await credentials.getOctokit();

const response: OctokitResponse<ModelResponse> = await octokit.request(
"POST /repos/github/codeql/code-scanning/codeql/auto-model",
{
data: request,
const response: OctokitResponse<ModelResponse> = await octokit.request(
"POST /repos/github/codeql/code-scanning/codeql/auto-model",
{
data: request,
},
);

return response.data;
}
}

async function callAutoModelDevEndpoint(
endpoint: string,
request: ModelRequest,
): Promise<ModelResponse> {
const json = JSON.stringify(request);
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
);
body: json,
});

if (!response.ok) {
throw new Error(
`Error calling auto-model API: ${response.status} ${response.statusText}`,
);
}

return response.data;
const data = await response.json();
return data as ModelResponse;
}
2 changes: 1 addition & 1 deletion extensions/ql-vscode/src/model-editor/auto-modeler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export class AutoModeler {
request: ModelRequest,
): Promise<ModelResponse | null> {
try {
return await autoModel(this.app.credentials, request);
return await autoModel(this.app.credentials, request, this.modelConfig);
} catch (e) {
if (e instanceof RequestError && e.status === 429) {
void showAndLogExceptionWithTelemetry(
Expand Down