summaryrefslogtreecommitdiff
path: root/extension
diff options
context:
space:
mode:
authorNate Sesti <sestinj@gmail.com>2023-07-12 13:22:40 -0700
committerNate Sesti <sestinj@gmail.com>2023-07-12 13:22:40 -0700
commit93ac6b52c9e5067c9703d096104c99f4f29e8eb5 (patch)
tree485af72e86415407f11ce0c91390d097eae05bc6 /extension
parent51f620524cd8d658058b4a07d8e8f8e1b3be49bd (diff)
downloadsncontinue-93ac6b52c9e5067c9703d096104c99f4f29e8eb5.tar.gz
sncontinue-93ac6b52c9e5067c9703d096104c99f4f29e8eb5.tar.bz2
sncontinue-93ac6b52c9e5067c9703d096104c99f4f29e8eb5.zip
purging unecessary files
Diffstat (limited to 'extension')
-rw-r--r--extension/react-app/src/App.tsx13
-rw-r--r--extension/react-app/src/pages/gui.tsx (renamed from extension/react-app/src/tabs/gui.tsx)0
-rw-r--r--extension/react-app/src/tabs/additionalContext.tsx18
-rw-r--r--extension/react-app/src/tabs/chat/MessageDiv.tsx75
-rw-r--r--extension/react-app/src/tabs/chat/index.tsx267
-rw-r--r--extension/react-app/src/tabs/main.tsx189
-rw-r--r--extension/react-app/src/tabs/welcome.tsx22
-rw-r--r--extension/src/bridge.ts215
8 files changed, 6 insertions, 793 deletions
diff --git a/extension/react-app/src/App.tsx b/extension/react-app/src/App.tsx
index 8785f88f..c9bd42e0 100644
--- a/extension/react-app/src/App.tsx
+++ b/extension/react-app/src/App.tsx
@@ -1,8 +1,5 @@
import DebugPanel from "./components/DebugPanel";
-import MainTab from "./tabs/main";
-import WelcomeTab from "./tabs/welcome";
-import ChatTab from "./tabs/chat";
-import GUI from "./tabs/gui";
+import GUI from "./pages/gui";
import { createContext } from "react";
import useContinueGUIProtocol from "./hooks/useWebsocket";
import ContinueGUIClientProtocol from "./hooks/useContinueGUIProtocol";
@@ -18,13 +15,7 @@ function App() {
<GUIClientContext.Provider value={client}>
<DebugPanel
tabs={[
- {
- element: <GUI />,
- title: "GUI",
- },
- // { element: <MainTab />, title: "Debug Panel" },
- // { element: <WelcomeTab />, title: "Welcome" },
- // { element: <ChatTab />, title: "Chat" },
+ { element: <GUI />, title: "GUI" }
]}
/>
</GUIClientContext.Provider>
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/pages/gui.tsx
index b6a18dc8..b6a18dc8 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/pages/gui.tsx
diff --git a/extension/react-app/src/tabs/additionalContext.tsx b/extension/react-app/src/tabs/additionalContext.tsx
deleted file mode 100644
index 98fce9f1..00000000
--- a/extension/react-app/src/tabs/additionalContext.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from "react";
-import { H3, TextArea } from "../components";
-
-function AdditionalContextTab() {
- return (
- <div className="mx-5">
- <H3>Additional Context</H3>
- <TextArea
- rows={8}
- placeholder="Copy and paste information related to the bug from GitHub Issues, Slack threads, or other notes here."
- className="additionalContextTextarea"
- ></TextArea>
- <br></br>
- </div>
- );
-}
-
-export default AdditionalContextTab;
diff --git a/extension/react-app/src/tabs/chat/MessageDiv.tsx b/extension/react-app/src/tabs/chat/MessageDiv.tsx
deleted file mode 100644
index 3543dd93..00000000
--- a/extension/react-app/src/tabs/chat/MessageDiv.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import React, { useEffect } from "react";
-import { ChatMessage } from "../../redux/store";
-import styled from "styled-components";
-import {
- buttonColor,
- defaultBorderRadius,
- secondaryDark,
-} from "../../components";
-import VSCodeFileLink from "../../components/VSCodeFileLink";
-import ReactMarkdown from "react-markdown";
-import "../../highlight/dark.min.css";
-import hljs from "highlight.js";
-import { useSelector } from "react-redux";
-import { selectIsStreaming } from "../../redux/selectors/chatSelectors";
-
-const Container = styled.div`
- padding-left: 8px;
- padding-right: 8px;
- border-radius: 8px;
- margin: 3px;
- width: fit-content;
- max-width: 75%;
- overflow-y: scroll;
- word-wrap: break-word;
- -ms-word-wrap: break-word;
- height: fit-content;
- overflow: hidden;
- background-color: ${(props) => {
- if (props.role === "user") {
- return buttonColor;
- } else {
- return secondaryDark;
- }
- }};
- float: ${(props) => {
- if (props.role === "user") {
- return "right";
- } else {
- return "left";
- }
- }};
- display: block;
-
- & pre {
- border: 1px solid gray;
- border-radius: ${defaultBorderRadius};
- }
-`;
-
-function MessageDiv(props: ChatMessage) {
- const [richContent, setRichContent] = React.useState<JSX.Element[]>([]);
- const isStreaming = useSelector(selectIsStreaming);
-
- useEffect(() => {
- if (!isStreaming) {
- hljs.highlightAll();
- }
- }, [richContent, isStreaming]);
-
- useEffect(() => {
- setRichContent([
- <ReactMarkdown key={1} children={props.content}></ReactMarkdown>,
- ]);
- }, [props.content]);
-
- return (
- <>
- <div className="overflow-auto">
- <Container role={props.role}>{richContent}</Container>
- </div>
- </>
- );
-}
-
-export default MessageDiv;
diff --git a/extension/react-app/src/tabs/chat/index.tsx b/extension/react-app/src/tabs/chat/index.tsx
deleted file mode 100644
index a93ad4f9..00000000
--- a/extension/react-app/src/tabs/chat/index.tsx
+++ /dev/null
@@ -1,267 +0,0 @@
-import React, { useCallback, useEffect, useRef, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { selectChatMessages } from "../../redux/selectors/chatSelectors";
-import MessageDiv from "./MessageDiv";
-import styled from "styled-components";
-import { addMessage, setIsStreaming } from "../../redux/slices/chatSlice";
-import { AnyAction, Dispatch } from "@reduxjs/toolkit";
-import { closeStream, streamUpdate } from "../../redux/slices/chatSlice";
-import { ChatMessage, RootStore } from "../../redux/store";
-import { postVscMessage, vscRequest } from "../../vscode";
-import { defaultBorderRadius, Loader } from "../../components";
-import { selectHighlightedCode } from "../../redux/selectors/miscSelectors";
-import { readRangeInVirtualFileSystem } from "../../util";
-import { selectDebugContext } from "../../redux/selectors/debugContextSelectors";
-
-let textEntryBarHeight = "30px";
-
-const ChatContainer = styled.div`
- display: grid;
- grid-template-rows: 1fr auto;
- height: 100%;
-`;
-
-const BottomDiv = styled.div`
- display: grid;
- grid-template-rows: auto auto;
-`;
-
-const BottomButton = styled.button(
- (props: { active: boolean }) => `
- font-size: 10px;
- border: none;
- color: white;
- margin-right: 4px;
- cursor: pointer;
- background-color: ${props.active ? "black" : "gray"};
- border-radius: ${defaultBorderRadius};
- padding: 8px;
-`
-);
-
-const TextEntryBar = styled.input`
- height: ${textEntryBarHeight};
- border-bottom-left-radius: ${defaultBorderRadius};
- border-bottom-right-radius: ${defaultBorderRadius};
- padding: 8px;
- border: 1px solid white;
- background-color: black;
- color: white;
- outline: none;
-`;
-
-function ChatTab() {
- const dispatch = useDispatch();
- const chatMessages = useSelector(selectChatMessages);
- const isStreaming = useSelector((state: RootStore) => state.chat.isStreaming);
- const baseUrl = useSelector((state: RootStore) => state.config.apiUrl);
- const debugContext = useSelector(selectDebugContext);
-
- const [includeHighlightedCode, setIncludeHighlightedCode] = useState(true);
- const [writeToEditor, setWriteToEditor] = useState(false);
- const [waitingForResponse, setWaitingForResponse] = useState(false);
-
- const highlightedCode = useSelector(selectHighlightedCode);
-
- const streamToStateThunk = useCallback(
- (dispatch: Dispatch<AnyAction>, getResponse: () => Promise<Response>) => {
- let streamToCursor = writeToEditor;
- getResponse().then((resp) => {
- setWaitingForResponse(false);
- if (resp.body) {
- resp.body.pipeTo(
- new WritableStream({
- write(chunk) {
- let update = new TextDecoder("utf-8").decode(chunk);
- dispatch(streamUpdate(update));
- if (streamToCursor) {
- postVscMessage("streamUpdate", { update });
- }
- },
- close() {
- dispatch(closeStream());
- if (streamToCursor) {
- postVscMessage("closeStream", null);
- }
- },
- })
- );
- }
- });
- },
- [writeToEditor]
- );
-
- const compileHiddenChatMessages = useCallback(async () => {
- let messages: ChatMessage[] = [];
- if (
- includeHighlightedCode &&
- highlightedCode?.filepath !== undefined &&
- highlightedCode?.range !== undefined &&
- debugContext.filesystem[highlightedCode.filepath] !== undefined
- ) {
- let fileContents = readRangeInVirtualFileSystem(
- highlightedCode,
- debugContext.filesystem
- );
- if (fileContents) {
- messages.push({
- role: "user",
- content: fileContents,
- });
- }
- } else {
- // Similarity search over workspace
- let data = await vscRequest("queryEmbeddings", {
- query: chatMessages[chatMessages.length - 1].content,
- });
- let codeContextMessages = data.results.map(
- (result: { id: string; document: string }) => {
- let msg: ChatMessage = {
- role: "user",
- content: `File: ${result.id} \n ${result.document}`,
- };
- return msg;
- }
- );
- codeContextMessages.push({
- role: "user",
- content:
- "Use the above code to help you answer the question below. Answer in asterisk bullet points, and give the full path whenever you reference files.",
- });
- messages.push(...codeContextMessages);
- }
-
- let systemMsgContent = writeToEditor
- ? "Respond only with the exact code requested, no additional text."
- : "Use the above code to help you answer the question below. Respond in markdown if using bullets or other special formatting, being sure to specify language for code blocks.";
-
- messages.push({
- role: "system",
- content: systemMsgContent,
- });
- return messages;
- }, [highlightedCode, chatMessages, includeHighlightedCode, writeToEditor]);
-
- useEffect(() => {
- if (
- chatMessages.length > 0 &&
- chatMessages[chatMessages.length - 1].role === "user" &&
- !isStreaming
- ) {
- dispatch(setIsStreaming(true));
- streamToStateThunk(dispatch, async () => {
- if (chatMessages.length === 0) {
- return new Promise((resolve, _) => resolve(new Response()));
- }
- let hiddenChatMessages = await compileHiddenChatMessages();
- let augmentedMessages = [
- ...chatMessages.slice(0, -1),
- ...hiddenChatMessages,
- chatMessages[chatMessages.length - 1],
- ];
- console.log(augmentedMessages);
- // The autogenerated client can't handle streams, so have to go raw
- return fetch(`${baseUrl}/chat/complete`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- messages: augmentedMessages,
- }),
- });
- });
- }
- }, [chatMessages, dispatch, isStreaming, highlightedCode]);
-
- const chatMessagesDiv = useRef<HTMLDivElement>(null);
- useEffect(() => {
- // Scroll to bottom
- let interval = setInterval(() => {
- if (chatMessagesDiv.current && !waitingForResponse) {
- chatMessagesDiv.current.scrollTop += Math.max(
- 4,
- 0.05 * chatMessagesDiv.current.scrollHeight -
- chatMessagesDiv.current.clientHeight -
- chatMessagesDiv.current.scrollTop
- );
- if (
- chatMessagesDiv.current.scrollTop >=
- chatMessagesDiv.current.scrollHeight -
- chatMessagesDiv.current.clientHeight
- ) {
- clearInterval(interval);
- }
- }
- }, 10);
- }, [chatMessages, chatMessagesDiv, waitingForResponse]);
-
- return (
- <ChatContainer>
- <div className="mx-5 overflow-y-scroll" ref={chatMessagesDiv}>
- <h1>Chat</h1>
- <hr></hr>
- <div>
- {chatMessages.length > 0 ? (
- chatMessages.map((message, idx) => {
- return <MessageDiv key={idx} {...message}></MessageDiv>;
- })
- ) : (
- <p className="text-gray-400 m-auto text-center">
- You can ask questions about your codebase or ask for code written
- directly in the editor.
- </p>
- )}
- {waitingForResponse && <Loader></Loader>}
- </div>
- </div>
-
- <BottomDiv>
- <div className="h-12 bg-secondary-">
- <div className="flex items-center p-2">
- {/* <p className="mr-auto text-xs">
- Highlighted code is automatically included in your chat message.
- </p> */}
- <BottomButton
- className="ml-auto"
- active={writeToEditor}
- onClick={() => {
- setWriteToEditor(!writeToEditor);
- }}
- >
- {writeToEditor ? "Writing to editor" : "Write to editor"}
- </BottomButton>
-
- <BottomButton
- active={includeHighlightedCode}
- onClick={() => {
- setIncludeHighlightedCode(!includeHighlightedCode);
- }}
- >
- {includeHighlightedCode
- ? "Including highlighted code"
- : "Automatically finding relevant code"}
- </BottomButton>
- </div>
- </div>
- <TextEntryBar
- type="text"
- placeholder="Enter your message here"
- onKeyDown={(e) => {
- if (e.key === "Enter" && e.currentTarget.value !== "") {
- console.log("Sending message", e.currentTarget.value);
- dispatch(
- addMessage({ content: e.currentTarget.value, role: "user" })
- );
- (e.target as any).value = "";
- setWaitingForResponse(true);
- }
- }}
- ></TextEntryBar>
- </BottomDiv>
- </ChatContainer>
- );
-}
-
-export default ChatTab;
diff --git a/extension/react-app/src/tabs/main.tsx b/extension/react-app/src/tabs/main.tsx
deleted file mode 100644
index a8b3300d..00000000
--- a/extension/react-app/src/tabs/main.tsx
+++ /dev/null
@@ -1,189 +0,0 @@
-import React, { useEffect, useState } from "react";
-import { H3, TextArea, Button, Pre, Loader } from "../components";
-import styled from "styled-components";
-import { postVscMessage, withProgress } from "../vscode";
-import { useDebugContextValue } from "../redux/hooks";
-import CodeMultiselect from "../components/CodeMultiselect";
-import { useSelector } from "react-redux";
-import { selectDebugContext } from "../redux/selectors/debugContextSelectors";
-import { useDispatch } from "react-redux";
-import { updateValue } from "../redux/slices/debugContexSlice";
-import { setWorkspacePath } from "../redux/slices/configSlice";
-import { SerializedDebugContext } from "../../../src/client";
-import { useEditCache } from "../util/editCache";
-import { useApi } from "../util/api";
-
-const ButtonDiv = styled.div`
- display: flex;
- justify-content: space-between;
- align-items: center;
- gap: 4px;
- margin: 4px;
- flex-wrap: wrap;
-
- & button {
- flex-grow: 1;
- }
-`;
-
-function MainTab(props: any) {
- const dispatch = useDispatch();
-
- const [suggestion, setSuggestion] = useState("");
- const [traceback, setTraceback] = useDebugContextValue("traceback", "");
- const [selectedRanges, setSelectedRanges] = useDebugContextValue(
- "rangesInFiles",
- []
- );
-
- const editCache = useEditCache();
- const { debugApi } = useApi();
-
- const [responseLoading, setResponseLoading] = useState(false);
-
- let debugContext = useSelector(selectDebugContext);
-
- useEffect(() => {
- editCache.preloadEdit(debugContext);
- }, [debugContext]);
-
- function postVscMessageWithDebugContext(
- type: string,
- overrideDebugContext: SerializedDebugContext | null = null
- ) {
- postVscMessage(type, {
- debugContext: overrideDebugContext || debugContext,
- });
- }
-
- function launchFindSuspiciousCode(newTraceback: string) {
- // setTraceback's effects don't occur immediately, so we have to add it to the debug context manually
- let updatedDebugContext = {
- ...debugContext,
- traceback: newTraceback,
- };
- postVscMessageWithDebugContext("findSuspiciousCode", updatedDebugContext);
- postVscMessageWithDebugContext("preloadEdit", updatedDebugContext);
- }
-
- useEffect(() => {
- const eventListener = (event: any) => {
- switch (event.data.type) {
- case "suggestFix":
- case "explainCode":
- case "listTenThings":
- setSuggestion(event.data.value);
- setResponseLoading(false);
- break;
- case "traceback":
- setTraceback(event.data.value);
- launchFindSuspiciousCode(event.data.value);
- break;
- case "workspacePath":
- dispatch(setWorkspacePath(event.data.value));
- break;
- }
- };
- window.addEventListener("message", eventListener);
-
- return () => window.removeEventListener("message", eventListener);
- }, [debugContext, selectedRanges]);
-
- return (
- <div className="mx-5">
- <h1>Debug Panel</h1>
-
- <H3>Code Sections</H3>
- <CodeMultiselect></CodeMultiselect>
-
- <H3>Bug Description</H3>
- <TextArea
- id="bugDescription"
- name="bugDescription"
- className="bugDescription"
- rows={4}
- cols={50}
- placeholder="Describe your bug..."
- ></TextArea>
-
- <H3>Stack Trace</H3>
- <TextArea
- id="traceback"
- className="traceback"
- name="traceback"
- rows={4}
- cols={50}
- placeholder="Paste stack trace here"
- onChange={(e) => {
- setTraceback(e.target.value);
- dispatch(updateValue({ key: "traceback", value: e.target.value }));
- // postVscMessageWithDebugContext("findSuspiciousCode");
- }}
- onPaste={(e) => {
- let pasted = e.clipboardData.getData("text");
- console.log("PASTED", pasted);
- setTraceback(pasted);
- launchFindSuspiciousCode(pasted);
- }}
- value={traceback}
- ></TextArea>
-
- <select
- hidden
- id="relevantVars"
- className="relevantVars"
- name="relevantVars"
- ></select>
-
- <ButtonDiv>
- <Button
- onClick={() => {
- postVscMessageWithDebugContext("explainCode");
- setResponseLoading(true);
- }}
- >
- Explain Code
- </Button>
- <Button
- onClick={() => {
- postVscMessageWithDebugContext("suggestFix");
- setResponseLoading(true);
- }}
- >
- Generate Ideas
- </Button>
- <Button
- disabled={selectedRanges.length === 0}
- onClick={async () => {
- withProgress("Generating Fix", async () => {
- let edits = await editCache.getEdit(debugContext);
- postVscMessage("makeEdit", { edits });
- });
- }}
- >
- Suggest Fix
- </Button>
- <Button
- disabled={selectedRanges.length === 0}
- onClick={() => {
- postVscMessageWithDebugContext("generateUnitTest");
- }}
- >
- Create Test
- </Button>
- </ButtonDiv>
- <Loader hidden={!responseLoading}></Loader>
-
- <Pre
- className="fixSuggestion"
- hidden={!(typeof suggestion === "string" && suggestion.length > 0)}
- >
- {suggestion}
- </Pre>
-
- <br></br>
- </div>
- );
-}
-
-export default MainTab;
diff --git a/extension/react-app/src/tabs/welcome.tsx b/extension/react-app/src/tabs/welcome.tsx
deleted file mode 100644
index c29d260a..00000000
--- a/extension/react-app/src/tabs/welcome.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import React from "react";
-
-function WelcomeTab() {
- return (
- <div className="mx-5">
- <h1>Welcome to Continue</h1>
-
- <p>
- Learn more in the{" "}
- <a href="https://www.notion.so/continue-dev/Continue-User-Guide-1c6ad99887d0474d9e42206f6c98efa4">
- Continue User Guide
- </a>{" "}
- </p>
- <p>Send Nate or Ty your feedback:</p>
- <p>1. What excites you about Continue?</p>
- <p>2. What did you struggle with when using Continue?</p>
- <p>3. How do you wish Continue worked?</p>
- </div>
- );
-}
-
-export default WelcomeTab;
diff --git a/extension/src/bridge.ts b/extension/src/bridge.ts
index 92ba4044..55c4cc3b 100644
--- a/extension/src/bridge.ts
+++ b/extension/src/bridge.ts
@@ -4,14 +4,11 @@ import * as vscode from "vscode";
import {
Configuration,
DebugApi,
- RangeInFile,
- SerializedDebugContext,
UnittestApi,
} from "./client";
import { convertSingleToDoubleQuoteJSON } from "./util/util";
import { getExtensionUri } from "./util/vscode";
import { extensionContext } from "./activation/activate";
-const axios = require("axios").default;
const util = require("util");
const exec = util.promisify(require("child_process").exec);
@@ -36,21 +33,16 @@ const configuration = new Configuration({
export const debugApi = new DebugApi(configuration);
export const unittestApi = new UnittestApi(configuration);
-function get_python_path() {
- return path.join(getExtensionUri().fsPath, "..");
-}
-
export function get_api_url() {
- let extensionUri = getExtensionUri();
- let configFile = path.join(extensionUri.fsPath, "config/config.json");
- let config = require(configFile);
+ const extensionUri = getExtensionUri();
+ const configFile = path.join(extensionUri.fsPath, "config/config.json");
+ const config = require(configFile);
if (config.API_URL) {
return config.API_URL;
}
return "http://localhost:65432";
}
-const API_URL = get_api_url();
export function getContinueServerUrl() {
// If in debug mode, always use 8001
@@ -58,7 +50,7 @@ export function getContinueServerUrl() {
extensionContext &&
extensionContext.extensionMode === vscode.ExtensionMode.Development
) {
- return "http://localhost:8001";
+ // return "http://localhost:8001";
}
return (
vscode.workspace.getConfiguration("continue").get<string>("serverUrl") ||
@@ -66,10 +58,6 @@ export function getContinueServerUrl() {
);
}
-function build_python_command(cmd: string): string {
- return `cd ${get_python_path()} && source env/bin/activate && ${cmd}`;
-}
-
function listToCmdLineArgs(list: string[]): string {
return list.map((el) => `"$(echo "${el}")"`).join(" ");
}
@@ -103,198 +91,3 @@ export async function runPythonScript(
}
}
}
-
-function parseStdout(
- stdout: string,
- key: string,
- until_end: boolean = false
-): string {
- const prompt = `${key}=`;
- let lines = stdout.split("\n");
-
- let value: string = "";
- for (let i = 0; i < lines.length; i++) {
- if (lines[i].startsWith(prompt)) {
- if (until_end) {
- return lines.slice(i).join("\n").substring(prompt.length);
- } else {
- return lines[i].substring(prompt.length);
- }
- }
- }
- return "";
-}
-
-export async function askQuestion(
- question: string,
- workspacePath: string
-): Promise<{ answer: string; range: vscode.Range; filename: string }> {
- const command = build_python_command(
- `python3 ${path.join(
- get_python_path(),
- "ask.py"
- )} ask ${workspacePath} "${question}"`
- );
-
- const { stdout, stderr } = await exec(command);
- if (stderr) {
- throw new Error(stderr);
- }
- // Use the output
- const answer = parseStdout(stdout, "Answer");
- const filename = parseStdout(stdout, "Filename");
- const startLineno = parseInt(parseStdout(stdout, "Start lineno"));
- const endLineno = parseInt(parseStdout(stdout, "End lineno"));
- const range = new vscode.Range(
- new vscode.Position(startLineno, 0),
- new vscode.Position(endLineno, 0)
- );
- if (answer && filename && startLineno && endLineno) {
- return { answer, filename, range };
- } else {
- throw new Error("Error: No answer found");
- }
-}
-
-export async function apiRequest(
- endpoint: string,
- options: {
- method?: string;
- query?: { [key: string]: any };
- body?: { [key: string]: any };
- }
-): Promise<any> {
- let defaults = {
- method: "GET",
- query: {},
- body: {},
- };
- options = Object.assign(defaults, options); // Second takes over first
- if (endpoint.startsWith("/")) endpoint = endpoint.substring(1);
- console.log("API request: ", options.body);
-
- let resp;
- try {
- resp = await axios({
- method: options.method,
- url: `${API_URL}/${endpoint}`,
- data: options.body,
- params: options.query,
- headers: {
- "x-vsc-machine-id": vscode.env.machineId,
- },
- });
- } catch (err) {
- console.log("Error: ", err);
- throw err;
- }
-
- return resp.data;
-}
-
-// Write a docstring for the most specific function or class at the current line in the given file
-export async function writeDocstringForFunction(
- filename: string,
- position: vscode.Position
-): Promise<{ lineno: number; docstring: string }> {
- let resp = await apiRequest("docstring/forline", {
- query: {
- filecontents: (
- await vscode.workspace.fs.readFile(vscode.Uri.file(filename))
- ).toString(),
- lineno: position.line.toString(),
- },
- });
-
- const lineno = resp.lineno;
- const docstring = resp.completion;
- if (lineno && docstring) {
- return { lineno, docstring };
- } else {
- throw new Error("Error: No docstring returned");
- }
-}
-
-export async function findSuspiciousCode(
- ctx: SerializedDebugContext
-): Promise<RangeInFile[]> {
- if (!ctx.traceback) return [];
- let files = await getFileContents(
- getFilenamesFromPythonStacktrace(ctx.traceback)
- );
- let resp = await debugApi.findSusCodeEndpointDebugFindPost({
- findBody: {
- traceback: ctx.traceback,
- description: ctx.description,
- filesystem: files,
- },
- });
- let ranges = resp.response;
- if (
- ranges.length <= 1 &&
- ctx.traceback &&
- ctx.traceback.includes("AssertionError")
- ) {
- let parsed_traceback =
- await debugApi.parseTracebackEndpointDebugParseTracebackGet({
- traceback: ctx.traceback,
- });
- let last_frame = parsed_traceback.frames[0];
- if (!last_frame) return [];
- ranges = (
- await runPythonScript("build_call_graph.py", [
- last_frame.filepath,
- last_frame.lineno.toString(),
- last_frame._function,
- ])
- ).value;
- }
-
- return ranges;
-}
-
-export async function writeUnitTestForFunction(
- filename: string,
- position: vscode.Position
-): Promise<string> {
- let resp = await apiRequest("unittest/forline", {
- method: "POST",
- body: {
- filecontents: (
- await vscode.workspace.fs.readFile(vscode.Uri.file(filename))
- ).toString(),
- lineno: position.line,
- userid: vscode.env.machineId,
- },
- });
-
- return resp.completion;
-}
-
-async function getFileContents(
- files: string[]
-): Promise<{ [key: string]: string }> {
- let contents = await Promise.all(
- files.map(async (file: string) => {
- return (
- await vscode.workspace.fs.readFile(vscode.Uri.file(file))
- ).toString();
- })
- );
- let fileContents: { [key: string]: string } = {};
- for (let i = 0; i < files.length; i++) {
- fileContents[files[i]] = contents[i];
- }
- return fileContents;
-}
-
-function getFilenamesFromPythonStacktrace(traceback: string): string[] {
- let filenames: string[] = [];
- for (let line of traceback.split("\n")) {
- let match = line.match(/File "(.*)", line/);
- if (match) {
- filenames.push(match[1]);
- }
- }
- return filenames;
-}